diff --git a/.github/actions/cmake-config/action.yml b/.github/actions/cmake-config/action.yml deleted file mode 100644 index 2ddb93a653..0000000000 --- a/.github/actions/cmake-config/action.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: 'Configure CMake' -description: 'Configure the CMake project' -author: 'Rafael Mudafort https://github.com/rafmudaf' - -inputs: - build-type: - description: 'Set the CMake build type: Release (-O3); RelWithDebInfo (-O2 -g); Debug (-g)' - default: 'Release' - additional-flags: - description: 'Additional flags to pass directly to the CMake command' - default: '' - -runs: - using: 'composite' - steps: - - run: cmake .. -DCMAKE_BUILD_TYPE=${{ inputs.build-type }} ${{ inputs.additional-flags }} - working-directory: "/openfast/build" - shell: bash diff --git a/.github/actions/compile/action.yml b/.github/actions/compile/action.yml deleted file mode 100644 index 243026586c..0000000000 --- a/.github/actions/compile/action.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: 'Compile OpenFAST' -description: 'Compile part or all of OpenFAST' -author: 'Rafael Mudafort https://github.com/rafmudaf' - -inputs: - build-target: - description: 'Which targets to compile' - default: 'install' - -runs: - using: 'composite' - steps: - - run: make -j4 ${{ inputs.build-target }} - working-directory: "/openfast/build" - shell: bash diff --git a/.github/actions/git-update/action.yml b/.github/actions/git-update/action.yml deleted file mode 100644 index c2f1484a62..0000000000 --- a/.github/actions/git-update/action.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: 'Update the existin OpenFAST project in the Docker image' -description: 'Workaround to avoid recompiling every component since the Docker image has the latest "dev" branch precompiled.' -author: 'Rafael Mudafort https://github.com/rafmudaf' - -inputs: - repository: - description: 'The GitHub repository that is taking action.' - required: true - ref: - description: 'The branch or tag ref that triggered the action.' - required: true - -runs: - using: 'composite' - steps: - - run: | - git config --global user.email "openfast@github_actions.ci" - git config --global user.name "OpenFAST Continuous Integration" - git pull --no-verify https://github.com/${{ inputs.repository }} ${{ inputs.ref }} - git submodule update - working-directory: "/openfast/" - shell: bash diff --git a/.github/actions/tests-gluecode-openfast/action.yml b/.github/actions/tests-gluecode-openfast/action.yml index 5b83dc96c4..e295492830 100644 --- a/.github/actions/tests-gluecode-openfast/action.yml +++ b/.github/actions/tests-gluecode-openfast/action.yml @@ -7,7 +7,7 @@ runs: - run: | ctest -VV -L linear -E Ideal ctest -VV -j8 -I 1,1,1,2,3,4,5,6,7,8,10,11,12,13,14,15,17,18,21,22,23,24,25,26,27,28,29 - working-directory: "/openfast/build" + working-directory: ${{runner.workspace}}/build shell: bash # OpenFAST linearization tests diff --git a/.github/actions/tests-module-aerodyn/action.yml b/.github/actions/tests-module-aerodyn/action.yml index 7b2e332f56..bc83c599e0 100644 --- a/.github/actions/tests-module-aerodyn/action.yml +++ b/.github/actions/tests-module-aerodyn/action.yml @@ -5,5 +5,5 @@ runs: using: "composite" steps: - run: ctest -VV -R fvw_utest - working-directory: "/openfast/build" + working-directory: ${{runner.workspace}}/build shell: bash diff --git a/.github/actions/tests-module-beamdyn/action.yml b/.github/actions/tests-module-beamdyn/action.yml index 46a1cc1473..660a2de9f6 100644 --- a/.github/actions/tests-module-beamdyn/action.yml +++ b/.github/actions/tests-module-beamdyn/action.yml @@ -20,5 +20,5 @@ runs: ctest -VV -j7 -R bd_ fi - working-directory: "/openfast/build" + working-directory: ${{runner.workspace}}/build shell: bash diff --git a/.github/actions/tests-module-hydrodyn/action.yml b/.github/actions/tests-module-hydrodyn/action.yml index e4a44cd152..4890c414fc 100644 --- a/.github/actions/tests-module-hydrodyn/action.yml +++ b/.github/actions/tests-module-hydrodyn/action.yml @@ -5,5 +5,5 @@ runs: using: "composite" steps: - run: ctest -VV -j7 -R hd_ - working-directory: "/openfast/build" + working-directory: ${{runner.workspace}}/build shell: bash diff --git a/.github/actions/tests-module-inflowwind/action.yml b/.github/actions/tests-module-inflowwind/action.yml index 93a7e14b5f..4a204980ad 100644 --- a/.github/actions/tests-module-inflowwind/action.yml +++ b/.github/actions/tests-module-inflowwind/action.yml @@ -5,5 +5,5 @@ runs: using: "composite" steps: - run: ctest -VV -R inflowwind_utest - working-directory: "/openfast/build" + working-directory: ${{runner.workspace}}/build shell: bash diff --git a/.github/actions/tests-module-nwtclibrary/action.yml b/.github/actions/tests-module-nwtclibrary/action.yml index e26b0d99dc..a8d27e4174 100644 --- a/.github/actions/tests-module-nwtclibrary/action.yml +++ b/.github/actions/tests-module-nwtclibrary/action.yml @@ -5,5 +5,5 @@ runs: using: "composite" steps: - run: ctest -VV -R nwtc_library_utest - working-directory: "/openfast/build" + working-directory: ${{runner.workspace}}/build shell: bash diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index c472362e84..1a7c6f7baa 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -15,6 +15,10 @@ on: - 'share/**' - 'vs-build/**' +env: + FORTRAN_COMPILER: gfortran-10 + NUM_PROCS: 8 + # runs-on: ${{ matrix.os }} # strategy: # matrix: @@ -22,124 +26,123 @@ on: jobs: regression-test: - runs-on: ubuntu-latest - container: - image: rafmudaf/openfast-ubuntu:dev + runs-on: ubuntu-20.04 steps: - name: Checkout uses: actions/checkout@main with: submodules: recursive - - name: Git Update - uses: ./.github/actions/git-update - with: - repository: $GITHUB_REPOSITORY - ref: $GITHUB_REF - - name: Configure CMake - uses: ./.github/actions/cmake-config - with: - build-type: RelWithDebInfo - additional-flags: -DBUILD_TESTING=ON -DCTEST_PLOT_ERRORS=ON + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: '3.7' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install numpy Bokeh==1.4 - - name: Compile Drivers - uses: ./.github/actions/compile - with: - build-target: 'beamdyn_driver hydrodyn_driver' - - name: Compile OpenFAST + - name: Setup Workspace + run: cmake -E make_directory ${{runner.workspace}}/build + - name: Configure Build + working-directory: ${{runner.workspace}}/build + run: | + cmake \ + -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/install \ + -DCMAKE_Fortran_COMPILER:STRING=${{env.FORTRAN_COMPILER}} \ + -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo \ + -DBUILD_TESTING:BOOL=ON \ + -DCTEST_PLOT_ERRORS:BOOL=ON \ + ${GITHUB_WORKSPACE} + - name: Build OpenFAST # if: contains(github.event.head_commit.message, 'Action - Test All') || contains(github.event.pull_request.labels.*.name, 'Action - Test All') - uses: ./.github/actions/compile - with: - build-target: 'regression_tests' + working-directory: ${{runner.workspace}}/build + run: cmake --build . --target install -- -j ${{env.NUM_PROCS}} - - name: 'Run BeamDyn tests' + - name: Run BeamDyn tests uses: ./.github/actions/tests-module-beamdyn with: test-target: regression - - name: 'Run HydroDyn tests' + - name: Run HydroDyn tests uses: ./.github/actions/tests-module-hydrodyn - - name: 'Run OpenFAST tests' + - name: Run OpenFAST tests # if: contains(github.event.head_commit.message, 'Action - Test All') || contains(github.event.pull_request.labels.*.name, 'Action - Test All') uses: ./.github/actions/tests-gluecode-openfast - - name: 'If failure, post test files' + - name: Failing test artifacts uses: actions/upload-artifact@v2 if: failure() with: name: test-results path: | - /openfast/build/reg_tests/modules - /openfast/build/reg_tests/glue-codes/openfast - !/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline - !/openfast/build/reg_tests/glue-codes/openfast/AOC - !/openfast/build/reg_tests/glue-codes/openfast/AWT27 - !/openfast/build/reg_tests/glue-codes/openfast/SWRT - !/openfast/build/reg_tests/glue-codes/openfast/UAE_VI - !/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline + ${{runner.workspace}}/build/reg_tests/modules + ${{runner.workspace}}/build/reg_tests/glue-codes/openfast + !${{runner.workspace}}/build/reg_tests/glue-codes/openfast/5MW_Baseline + !${{runner.workspace}}/build/reg_tests/glue-codes/openfast/AOC + !${{runner.workspace}}/build/reg_tests/glue-codes/openfast/AWT27 + !${{runner.workspace}}/build/reg_tests/glue-codes/openfast/SWRT + !${{runner.workspace}}/build/reg_tests/glue-codes/openfast/UAE_VI + !${{runner.workspace}}/build/reg_tests/glue-codes/openfast/WP_Baseline unit-test: - runs-on: ubuntu-latest - container: - image: rafmudaf/openfast-ubuntu:dev + runs-on: ubuntu-20.04 steps: - name: Checkout uses: actions/checkout@main with: submodules: recursive - - name: Git Update - uses: ./.github/actions/git-update - with: - repository: $GITHUB_REPOSITORY - ref: $GITHUB_REF + - name: Setup + run: cmake -E make_directory ${{runner.workspace}}/build + - name: Configure + working-directory: ${{runner.workspace}}/build + run: | + cmake \ + -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/install \ + -DCMAKE_Fortran_COMPILER:STRING=${{env.FORTRAN_COMPILER}} \ + -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo \ + -DBUILD_TESTING:BOOL=ON \ + ${GITHUB_WORKSPACE} - - name: Configure CMake - uses: ./.github/actions/cmake-config - with: - build-type: RelWithDebInfo - additional-flags: -DBUILD_TESTING=ON - - - name: Compile Unit Tests - uses: ./.github/actions/compile - with: - build-target: 'unit_tests' + - name: Build unit tests + working-directory: ${{runner.workspace}}/build + run: cmake --build . --target unit_tests -- -j ${{env.NUM_PROCS}} - - name: 'Run NWTC Library tests' + - name: Run NWTC Library tests uses: ./.github/actions/tests-module-nwtclibrary - - name: 'Run AeroDyn tests' + - name: Run AeroDyn tests uses: ./.github/actions/tests-module-aerodyn - - name: 'Run BeamDyn tests' + - name: Run BeamDyn tests uses: ./.github/actions/tests-module-beamdyn with: test-target: unit - - name: 'Run InflowWind tests' + - name: Run InflowWind tests uses: ./.github/actions/tests-module-inflowwind compile-all-single-precision: # Test if single precision compile completes. + # Compiles all targets excluding tests. # Do not run the test suite. - runs-on: ubuntu-latest - container: - image: rafmudaf/openfast-ubuntu:dev + runs-on: ubuntu-20.04 steps: - name: Checkout uses: actions/checkout@main with: submodules: recursive - - name: Git Update - uses: ./.github/actions/git-update - with: - repository: $GITHUB_REPOSITORY - ref: $GITHUB_REF - - name: Configure CMake - uses: ./.github/actions/cmake-config - with: - build-type: Debug - additional-flags: -DDOUBLE_PRECISION=OFF - - name: Compile OpenFAST - uses: ./.github/actions/compile - with: - build-target: 'all' - - name: simple-test - working-directory: /openfast/build + - name: Setup + run: cmake -E make_directory ${{runner.workspace}}/build + - name: Configure + working-directory: ${{runner.workspace}}/build + run: | + cmake \ + -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/install \ + -DCMAKE_Fortran_COMPILER:STRING=${{env.FORTRAN_COMPILER}} \ + -DCMAKE_BUILD_TYPE:STRING=Debug \ + -DDOUBLE_PRECISION:BOOL=OFF \ + ${GITHUB_WORKSPACE} + - name: Build all + working-directory: ${{runner.workspace}}/build + run: cmake --build . --target all -- -j ${{env.NUM_PROCS}} + - name: Test + working-directory: ${{runner.workspace}}/build run: ./glue-codes/openfast/openfast -v diff --git a/cmake/OpenfastFortranOptions.cmake b/cmake/OpenfastFortranOptions.cmake index b4cc263b36..4822218a72 100644 --- a/cmake/OpenfastFortranOptions.cmake +++ b/cmake/OpenfastFortranOptions.cmake @@ -110,7 +110,7 @@ macro(set_fast_gfortran) # Disable stack reuse within routines: issues seen with gfortran 9.x, but others may also exhibit # see section 3.16 of https://gcc.gnu.org/onlinedocs/gcc-9.2.0/gcc.pdf # and https://github.com/OpenFAST/openfast/pull/595 - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fstack-reuse='none'") + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fstack-reuse=none") # Deal with Double/Single precision if (DOUBLE_PRECISION) @@ -120,7 +120,7 @@ macro(set_fast_gfortran) # debug flags if(CMAKE_BUILD_TYPE MATCHES Debug) - set( CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -fcheck=all -pedantic -fbacktrace " ) + set( CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -fcheck=all,no-array-temps -pedantic -fbacktrace " ) endif() if(CYGWIN) @@ -158,12 +158,16 @@ macro(set_fast_intel_fortran_posix) # Deal with Double/Single precision if (DOUBLE_PRECISION) add_definitions(-DOPENFAST_DOUBLE_PRECISION) - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -r8 -double_size 128") + if("${CMAKE_Fortran_COMPILER_VERSION}" VERSION_GREATER "19") + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -r8 -double-size 128") + else() + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -r8 -double_size 128") + endif() endif (DOUBLE_PRECISION) # debug flags if(CMAKE_BUILD_TYPE MATCHES Debug) - set( CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -check all -traceback" ) + set( CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -check all,no-array-temps -traceback" ) endif() # OPENMP @@ -204,7 +208,11 @@ macro(set_fast_intel_fortran_windows) # Deal with Double/Single precision if (DOUBLE_PRECISION) add_definitions(-DOPENFAST_DOUBLE_PRECISION) - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} /real_size:64 /double_size:128") + if("${CMAKE_Fortran_COMPILER_VERSION}" VERSION_GREATER "19") + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} /real-size:64 /double-size:128") + else() + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} /real_size:64 /double_size:128") + endif() endif (DOUBLE_PRECISION) # increase the default 2MB stack size to 16 MB diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000000..98dc073027 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,19 @@ + +# You can set these variables from the command line. +ALLSPHINXOPTS = -c conf.py +SPHINXBUILD = sphinx-build +PAPER = +ALLSPHINXOPTS = -d _build/doctrees $(SPHINXOPTS) . + +BUILDDIR = _build + + +all: html + +$(BUILDDIR): + mkdir $(BUILDDIR) + +html: $(BUILDDIR) + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR) + @echo + @echo "Build finished. The HTML pages are in _build/html." diff --git a/docs/OtherSupporting/OutListParameters.xlsx b/docs/OtherSupporting/OutListParameters.xlsx index 461e96fa46..18d640a052 100644 Binary files a/docs/OtherSupporting/OutListParameters.xlsx and b/docs/OtherSupporting/OutListParameters.xlsx differ diff --git a/docs/conf.py b/docs/conf.py index 709302a581..2c72935c69 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -115,9 +115,9 @@ def runDoxygen(sourcfile, doxyfileIn, doxyfileOut): # built documents. # # The short X.Y version. -version = u'2.5' +version = u'2.6' # The full version, including alpha/beta/rc tags. -release = u'v2.5.0' +release = u'v2.6.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -245,7 +245,10 @@ def runDoxygen(sourcfile, doxyfileIn, doxyfileOut): ] def setup(app): - app.add_css_file('css/math_eq.css') + try: + app.add_css_file('css/math_eq.css') + except: + pass app.add_object_type( "confval", "confval", diff --git a/docs/source/user/aerodyn/examples/ad_primary_example.inp b/docs/source/user/aerodyn/examples/ad_primary_example.inp index 029f3b7773..62a691d7f1 100644 --- a/docs/source/user/aerodyn/examples/ad_primary_example.inp +++ b/docs/source/user/aerodyn/examples/ad_primary_example.inp @@ -3,10 +3,10 @@ Description line that will be printed in the output file and written to the scre ====== General Options ============================================================================ True Echo - Echo the input to ".AD.ech"? (flag) "default" DTAero - Time interval for aerodynamic calculations {or "default"} (s) - 1 WakeMod - Type of wake/induction model (switch) {0=none, 1=BEMT, 2=DBEMT} [WakeMod cannot be 2 when linearizing] + 1 WakeMod - Type of wake/induction model (switch) {0=none, 1=BEMT, 2=DBEMT, 3=OLAF} [WakeMod cannot be 2 or 3 when linearizing] 1 AFAeroMod - Type of blade airfoil aerodynamics model (switch) {1=steady model, 2=Beddoes-Leishman unsteady model} [AFAeroMod must be 1 when linearizing] 0 TwrPotent - Type tower influence on wind based on potential flow around the tower (switch) {0=none, 1=baseline potential flow, 2=potential flow with Bak correction} -False TwrShadow - Calculate tower influence on wind based on downstream tower shadow? (flag) + 0 TwrShadow - Calculate tower influence on wind based on downstream tower shadow (switch) {0=none, 1=Powles model, 2=Eames model} False TwrAero - Calculate tower aerodynamic loads? (flag) False FrozenWake - Assume frozen wake during linearization? (flag) [used only when WakeMod=1 and when linearizing] False CavitCheck - Perform cavitation check? (flag) [AFAeroMod must be 1 when CavitCheck=true] @@ -19,15 +19,15 @@ False CompAA - Flag to compute AeroAcoustics calculation [on 101325 Patm - Atmospheric pressure (Pa) [used only when CavitCheck=True] 2000 Pvap - Vapour pressure of fluid (Pa) [used only when CavitCheck=True] 0.6 FluidDepth - Water depth above mid-hub height (m) [used only when CavitCheck=True] -====== Blade-Element/Momentum Theory Options ====================================================== [unused when WakeMod=0] - 1 SkewMod - Type of skewed-wake correction model (switch) {1=uncoupled, 2=Pitt/Peters, 3=coupled} [unused when WakeMod=0] -"default" SkewModFactor - Constant used in Pitt/Peters skewed wake model {or "default" is 15/32*pi} (-) [used only when SkewMod=2; unused when WakeMod=0] -f TipLoss - Use the Prandtl tip-loss model? (flag) [unused when WakeMod=0] -f HubLoss - Use the Prandtl hub-loss model? (flag) [unused when WakeMod=0] -True TanInd - Include tangential induction in BEMT calculations? (flag) [unused when WakeMod=0] -True AIDrag - Include the drag term in the axial-induction calculation? (flag) [unused when WakeMod=0] -True TIDrag - Include the drag term in the tangential-induction calculation? (flag) [unused when WakeMod=0 or TanInd=FALSE] - 1E-05 IndToler - Convergence tolerance for BEMT nonlinear solve residual equation {or "default"} (-) [unused when WakeMod=0] +====== Blade-Element/Momentum Theory Options ====================================================== [unused when WakeMod=0 or 3] + 1 SkewMod - Type of skewed-wake correction model (switch) {1=uncoupled, 2=Pitt/Peters, 3=coupled} [unused when WakeMod=0 or 3] +"default" SkewModFactor - Constant used in Pitt/Peters skewed wake model {or "default" is 15/32*pi} (-) [used only when SkewMod=2; unused when WakeMod=0 or 3] +f TipLoss - Use the Prandtl tip-loss model? (flag) [unused when WakeMod=0 or 3] +f HubLoss - Use the Prandtl hub-loss model? (flag) [unused when WakeMod=0 or 3] +True TanInd - Include tangential induction in BEMT calculations? (flag) [unused when WakeMod=0 or 3] +True AIDrag - Include the drag term in the axial-induction calculation? (flag) [unused when WakeMod=0 or 3] +True TIDrag - Include the drag term in the tangential-induction calculation? (flag) [unused when WakeMod=0,3 or TanInd=FALSE] + 1E-05 IndToler - Convergence tolerance for BEMT nonlinear solve residual equation {or "default"} (-) [unused when WakeMod=0 or 3] 100 MaxIter - Maximum number of iteration steps (-) [unused when WakeMod=0] ====== Dynamic Blade-Element/Momentum Theory Options ============================================== [used only when WakeMod=2] 2 DBEMT_Mod - Type of dynamic BEMT (DBEMT) model {1=constant tau1, 2=time-dependent tau1} (-) [used only when WakeMod=2] @@ -60,15 +60,15 @@ True UseBlCm - Include aerodynamic pitching moment in calcul "Test01_UAE_AeroDyn_blade.dat" ADBlFile(1) - Name of file containing distributed aerodynamic properties for Blade #1 (-) "Test01_UAE_AeroDyn_blade.dat" ADBlFile(2) - Name of file containing distributed aerodynamic properties for Blade #2 (-) [unused if NumBl < 2] "Test01_UAE_AeroDyn_blade.dat" ADBlFile(3) - Name of file containing distributed aerodynamic properties for Blade #3 (-) [unused if NumBl < 3] -====== Tower Influence and Aerodynamics ============================================================= [used only when TwrPotent/=0, TwrShadow=True, or TwrAero=True] +====== Tower Influence and Aerodynamics ============================================================= [used only when TwrPotent/=0, TwrShadow/=0, or TwrAero=True] 5 NumTwrNds - Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow=True, or TwrAero=True] -TwrElev TwrDiam TwrCd -(m) (m) (-) -0.0000000E+00 6.0000000E+00 0.0000000E+00 -2.0000000E+01 5.5000000E+00 0.0000000E+00 -4.0000000E+01 5.0000000E+00 0.0000000E+00 -6.0000000E+01 4.5000000E+00 0.0000000E+00 -8.0000000E+01 4.0000000E+00 0.0000000E+00 +TwrElev TwrDiam TwrCd TwrTI (used only with TwrShadow=2) +(m) (m) (-) (-) +0.0000000E+00 6.0000000E+00 0.0000000E+00 1.0000000E-01 +2.0000000E+01 5.5000000E+00 0.0000000E+00 1.0000000E-01 +4.0000000E+01 5.0000000E+00 0.0000000E+00 1.0000000E-01 +6.0000000E+01 4.5000000E+00 0.0000000E+00 1.0000000E-01 +8.0000000E+01 4.0000000E+00 0.0000000E+00 1.0000000E-01 ====== Outputs ==================================================================================== True SumPrint - Generate a summary file listing input options and interpolated properties to ".AD.sum"? (flag) 4 NBlOuts - Number of blade node outputs [0 - 9] (-) diff --git a/docs/source/user/aerodyn/index.rst b/docs/source/user/aerodyn/index.rst index d27e02e42d..48ce1edfb6 100644 --- a/docs/source/user/aerodyn/index.rst +++ b/docs/source/user/aerodyn/index.rst @@ -19,5 +19,6 @@ AeroDyn Users Guide and Theory Manual input.rst output.rst modeling.rst + theory.rst appendix.rst diff --git a/docs/source/user/aerodyn/input.rst b/docs/source/user/aerodyn/input.rst index 7c78c68506..04c208f1ff 100644 --- a/docs/source/user/aerodyn/input.rst +++ b/docs/source/user/aerodyn/input.rst @@ -180,11 +180,12 @@ potential-flow influence of the tower on the fluid flow local to the blade, 1 to enable the standard potential-flow model, or 2 to include the Bak correction in the potential-flow model. -Set the ``TwrShadow`` -flag to TRUE to include the influence of the tower on the flow local to -the blade based on the downstream tower shadow model or FALSE to disable -these effects. If the tower influence from potential flow and tower -shadow are both enabled, the two influences will be superimposed. +Set the ``TwrShadow`` to 0 to disable to the tower shadow model, +1 to enable the Powles tower shadow model, or 2 to use the Eames tower +shadow model. These models calculate the influence of the tower on the +flow local to the blade based on the downstream tower shadow model. If +the tower influence from potential flow and tower shadow are both +enabled, the two influences will be superimposed. Set the ``TwrAero`` flag to TRUE to calculate fluid drag loads on the tower or FALSE to disable these effects. @@ -379,7 +380,7 @@ Tower Influence and Aerodynamics The input parameters in this section pertain to the tower influence and/or tower drag calculations and are only used when ``TwrPotent`` > -0, ``TwrShadow = TRUE``, or ``TwrAero = TRUE``. +0, ``TwrShadow`` > 0, or ``TwrAero = TRUE``. ``NumTwrNds`` is the user-specified number of tower analysis nodes and determines the number of rows in the subsequent table (after two table @@ -389,10 +390,18 @@ time; we recommend that ``NumTwrNds`` be between 10 and 20 to balance accuracy with computational expense. For each node, ``TwrElev`` specifies the local elevation of the tower node above ground (or above MSL for offshore wind turbines or above the seabed for MHK turbines), -``TwrDiam`` specifies the local tower diameter, and ``TwrCd`` -specifies the local tower drag-force coefficient. ``TwrElev`` must be -entered in monotonically increasing order—from the lowest (tower-base) -to the highest (tower-top) elevation. See Figure 2. +``TwrDiam`` specifies the local tower diameter, ``TwrCd`` specifies the +local tower drag-force coefficient, and ``TwrTI`` specifies the +turbulence intensity used in the Eames tower shadow model +(``TwrShadow`` = 2) as a fraction (rather than a percentage) of the +wind fluctuation. ``TwrElev`` must be entered in monotonically +increasing order—from the lowest (tower-base) to the highest +(tower-top) elevation. Values of ``TwrTI`` between 0.05 and 0.4 are +recommended. Values larger than 0.4 up to 1 will trigger a warning +that the results will need to be interpretted carefully, but the code +will allow such values for scientific investigation purposes. +See :numref:`fig:TwrGeom`. + .. _AD-Outputs: @@ -403,7 +412,7 @@ Specifying ``SumPrint`` to TRUE causes AeroDyn to generate a summary file with name ``OutFileRoot**.AD.sum*. ``OutFileRoot`` is either specified in the I/O SETTINGS section of the driver input file when running AeroDyn standalone, or by the OpenFAST program when running a -coupled simulation. See section 5.2 for summary file details. +coupled simulation. See :numref:`sec:ad_SumFile` for summary file details. AeroDyn can output aerodynamic and kinematic quantities at up to nine nodes specified along the tower and up to nine nodes along each blade. @@ -427,6 +436,7 @@ quantities are actually output at these nodes. .. figure:: figs/ad_tower_geom.png :width: 60% + :name: fig:TwrGeom :align: center AeroDyn Tower Geometry diff --git a/docs/source/user/aerodyn/introduction.rst b/docs/source/user/aerodyn/introduction.rst index 915a7be9a7..62674e3fae 100644 --- a/docs/source/user/aerodyn/introduction.rst +++ b/docs/source/user/aerodyn/introduction.rst @@ -3,17 +3,23 @@ Introduction ============ -AeroDyn is a time-domain wind turbine aerodynamics module that is coupled in the OpenFAST multi-physics engineering tool to enable aero-elastic simulation of horizontal-axis turbines. -AeroDyn can also be driven as a standalone code to compute wind turbine aerodynamic response uncoupled from OpenFAST. -When coupled to OpenFAST, AeroDyn can also be linearized as part of the linearization of the full coupled solution (linearization is not available in standalone mode). -AeroDyn was originally developed for modeling wind turbine aerodynamics. +AeroDyn is a time-domain wind turbine aerodynamics module that is coupled in the +OpenFAST multi-physics engineering tool to enable aero-elastic simulation of +horizontal-axis turbines. AeroDyn can also be driven as a standalone code to +compute wind turbine aerodynamic response uncoupled from OpenFAST. When coupled +to OpenFAST, AeroDyn can also be linearized as part of the linearization of the +full coupled solution (linearization is not available in standalone mode). +AeroDyn was originally developed for modeling wind turbine aerodynamics. However, the module equally applies to the hydrodynamics of marine hydrokinetic -(MHK) turbines (the terms “wind turbine”, “tower”, “aerodynamics” etc. in this document imply “MHK turbine”, “MHK support structure”, “hydrodynamics” etc. for MHK turbines). -Additional physics important for MHK turbines, not applicable to wind turbines, computed by AeroDyn include a cavitation check. -This documentation pertains version of AeroDyn in the OpenFAST github repository. -The AeroDyn version released of OpenFAST 1.0.0 is most closely related to AeroDyn version 15 in the legacy version numbering. -AeroDyn version 15 was a complete overhaul from earlier version of AeroDyn. -AeroDyn version 15 and newer follows the requirements of the FAST modularization framework. +(MHK) turbines (the terms “wind turbine”, “tower”, “aerodynamics” etc. in this +document imply “MHK turbine”, “MHK support structure”, “hydrodynamics” etc. for +MHK turbines). Additional physics important for MHK turbines, not applicable to +wind turbines, computed by AeroDyn include a cavitation check. This +documentation pertains version of AeroDyn in the OpenFAST github repository. +The AeroDyn version released of OpenFAST 1.0.0 is most closely related to +AeroDyn version 15 in the legacy version numbering. AeroDyn version 15 was a +complete overhaul from earlier version of AeroDyn. AeroDyn version 15 and newer +follows the requirements of the FAST modularization framework. AeroDyn calculates aerodynamic loads on both the blades and tower. Aerodynamic calculations within AeroDyn are based on the principles of diff --git a/docs/source/user/aerodyn/modeling.rst b/docs/source/user/aerodyn/modeling.rst index 5b36deec1f..a63f541077 100644 --- a/docs/source/user/aerodyn/modeling.rst +++ b/docs/source/user/aerodyn/modeling.rst @@ -61,7 +61,7 @@ the blade tip. Aerodynamic imbalances are possible through the use of geometrical differences between each blade. When the tower potential-flow (``TwrPotent > 0``), tower shadow -(``TwrShadow = TRUE``), and/or the tower aerodynamic load +(``TwrShadow > 0``), and/or the tower aerodynamic load (``TwrAero = TRUE``) models are enabled, we also recommend that ``NumTwrNds`` be between 10 and 20 to balance accuracy with computational expense. Normally the local elevation of the tower node @@ -117,7 +117,7 @@ speed, in which case we recommend that ``TwrAero = TRUE``. Otherwise, We recommend to include the influence of the tower on the fluid local to the blade for both operational and parked/idling rotors. We recommend that ``TwrPotent > 0`` for upwind rotors and that ``TwrPotent = 2`` -or ``TwrShadow = TRUE`` for downwind rotors. +or ``TwrShadow > 0`` for downwind rotors. Linearization ------------- diff --git a/docs/source/user/aerodyn/output.rst b/docs/source/user/aerodyn/output.rst index 8c57e9f39c..2a7d81dccf 100644 --- a/docs/source/user/aerodyn/output.rst +++ b/docs/source/user/aerodyn/output.rst @@ -22,6 +22,8 @@ will be truncated if AeroDyn encounters an error while parsing an input file. The error usually corresponds to the line after the last successfully echoed line. +.. _sec:ad_SumFile: + Summary File ------------ diff --git a/docs/source/user/aerodyn/theory.rst b/docs/source/user/aerodyn/theory.rst new file mode 100644 index 0000000000..39b383dc3d --- /dev/null +++ b/docs/source/user/aerodyn/theory.rst @@ -0,0 +1,30 @@ + +.. _AD_theory: + +AeroDynTheory +============= + +This theory manual is work in progress, please refer to the AeroDyn manual for more details. + + +.. _AD_twr_shadow: + +Tower shadow models +~~~~~~~~~~~~~~~~~~~ + +Powles tower shadow model (**TwrShadow=1**) is given by: + +.. math:: + u_{TwrShadow} = - \frac{C_d}{ \sqrt{\overline{r}} } + \cos\left( \frac{\pi/2 \overline{y}}{\sqrt{\overline{r}}}\right)^2 + +where :math:`\overline{r} = \sqrt{ \overline{x}^2 + \overline{y}^2 }`. + + +Eames tower shadow model (**TwrShadow=2**) is given by: + +.. math:: + u_{TwrShadow} = -\frac{C_d}{ TI \: \overline{x} \, \sqrt{2 \pi } } + \exp{\left( -\frac{1}{2} \left(\frac{ \overline{y}}{ TI \: \overline{x} } \right)^2 \right) } + +where :math:`TI` is the turbulence intensity at the tower node. diff --git a/docs/source/user/api_change.rst b/docs/source/user/api_change.rst index aa5f2d4ea3..51cf5a8b5d 100644 --- a/docs/source/user/api_change.rst +++ b/docs/source/user/api_change.rst @@ -9,6 +9,99 @@ 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 v2.6.0 to OpenFAST `dev` +--------------------------------- +No changes. + + + +OpenFAST v2.5.0 to OpenFAST v2.6.0 +---------------------------------- + +Many changes were applied to SubDyn input file format. You may consult the following example: +:download:`(SubDyn's Input File) <./subdyn/examples/OC4_Jacket_SD_Input.dat>`: +and the online SubDyn documentation. + +============================================= ==== =============== ======================================================================================================================================================================================================== +Added in OpenFAST v2.6.0 +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Module Line Flag Name Example Value +============================================= ==== =============== ======================================================================================================================================================================================================== +AeroDyn 15 TwrTi 0.0000000E+00 6.0000000E+00 1.0000000E+00 1.0000000E-01 [additional column in *Tower Influence and Aerodynamics* table] +SubDyn 8 GuyanLoadCorr. False GuyanLoadCorection - Include extra moment from lever arm at interface and rotate FEM for floating +SubDyn 15 GuyanDampMod 0 GuyanDampMod - Guyan damping {0=none, 1=Rayleigh Damping, 2=user specified 6x6 matrix} +SubDyn 16 RayleighDamp 0.001, 0.003 RayleighDamp - Mass and stiffness proportional damping coefficients (Rayleigh Damping) [only if GuyanDampMod=1] +SubDyn 17 GuyanDampSize 6 GuyanDampSize - Guyan damping matrix size (square, 6x6) [only if GuyanDampMod=2] +SubDyn 18 GuyanDampMat 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 +SubDyn -23 GuyanDampMat 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 +SubDyn na CablesSection -------------------------- CABLE PROPERTIES ------------------------------------- +SubDyn na CablesSection 0 NCablePropSets - Number of cable cable properties +SubDyn na CablesSection PropSetID EA MatDens T0 +SubDyn na CablesSection (-) (N) (kg/m) (N) +SubDyn na RigidSection ---------------------- RIGID LINK PROPERTIES ------------------------------------ +SubDyn na RigidSection 0 NRigidPropSets - Number of rigid link properties +SubDyn na RigidSection PropSetID MatDens +SubDyn na RigidSection (-) (kg/m) +HydroDyn 52 NBody 1 NBody - Number of WAMIT bodies to be used (-) [>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6] +HydroDyn 53 NBodyMod 1 NBodyMod - Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1] + +============================================= ==== =============== ======================================================================================================================================================================================================== + +============================================= ====== =============== ====================================================================================================================================================================================================== +Modified in OpenFAST v2.6.0 +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Module Line Flag Name Example Value +============================================= ====== =============== ====================================================================================================================================================================================================== +AeroDyn 15 9 TwrShadow 0 TwrShadow - Calculate tower influence on wind based on downstream tower shadow (switch) {0=none, 1=Powles model, 2=Eames model} +SubDyn 26 Joints JointID JointXss JointYss JointZss JointType JointDirX JointDirY JointDirZ JointStiff +SubDyn 27 Joints (-) (m) (m) (m) (-) (-) (-) (-) (Nm/rad) +SubDyn na Members MemberID MJointID1 MJointID2 MPropSetID1 MPropSetID2 MType COSMID +SubDyn na Members (-) (-) (-) (-) (-) (-) (-) +SubDyn na ConcentratedM CMJointID JMass JMXX JMYY JMZZ JMXY JMXZ JMYZ MCGX MCGY MCGZ +SubDyn na ConcentratedM (-) (kg) (kg*m^2) (kg*m^2) (kg*m^2) (kg*m^2) (kg*m^2) (kg*m^2) (m) (m) (m) +HydroDyn 48 ExtnMod 1 ExctnMod - Wave-excitation model {0: no wave-excitation calculation, 1: DFT, 2: state-space} (switch) [only used when PotMod=1; STATE-SPACE REQUIRES \*.ssexctn INPUT FILE] +HydroDyn 49 RdtnMod 2 RdtnMod - Radiation memory-effect model {0: no memory-effect calculation, 1: convolution, 2: state-space} (switch) [only used when PotMod=1; STATE-SPACE REQUIRES \*.ss INPUT FILE] +HydroDyn 50 RdtnTMax 60 RdtnTMax - Analysis time for wave radiation kernel calculations (sec) [only used when PotMod=1 and RdtnMod>0; determines RdtnDOmega=Pi/RdtnTMax in the cosine transform; MAKE SURE THIS IS LONG ENOUGH FOR THE RADIATION IMPULSE RESPONSE FUNCTIONS TO DECAY TO NEAR-ZERO FOR THE GIVEN PLATFORM!] +HydroDyn 51 RdtnDT 0.0125 RdtnDT - Time step for wave radiation kernel calculations (sec) [only used when PotMod=1 and ExctnMod>0 or RdtnMod>0; DT<=RdtnDT<=0.1 recommended; determines RdtnOmegaMax=Pi/RdtnDT in the cosine transform] +HydroDyn 54 PotFile "Barge" PotFile - Root name of potential-flow model data; WAMIT output files containing the linear, nondimensionalized, hydrostatic restoring matrix (.hst), frequency-dependent hydrodynamic added mass matrix and damping matrix (.1), and frequency- and direction-dependent wave excitation force vector per unit wave amplitude (.3) (quoted string) [1 to NBody if NBodyMod>1] [MAKE SURE THE FREQUENCIES INHERENT IN THESE WAMIT FILES SPAN THE PHYSICALLY-SIGNIFICANT RANGE OF FREQUENCIES FOR THE GIVEN PLATFORM; THEY MUST CONTAIN THE ZERO- AND INFINITE-FREQUENCY LIMITS!] +HydroDyn 55 WAMITULEN 1 WAMITULEN - Characteristic body length scale used to redimensionalize WAMIT output (meters) [1 to NBody if NBodyMod>1] [only used when PotMod=1] +HydroDyn 56 PtfmRefxt 0.0 PtfmRefxt - The xt offset of the body reference point(s) from (0,0,0) (meters) [1 to NBody] [only used when PotMod=1] +HydroDyn 57 PtfmRefyt 0.0 PtfmRefyt - The yt offset of the body reference point(s) from (0,0,0) (meters) [1 to NBody] [only used when PotMod=1] +HydroDyn 58 PtfmRefzt 0.0 PtfmRefzt - The zt offset of the body reference point(s) from (0,0,0) (meters) [1 to NBody] [only used when PotMod=1. If NBodyMod=2,PtfmRefzt=0.0] +HydroDyn 59 PtfmRefztRot 0.0 PtfmRefztRot - The rotation about zt of the body reference frame(s) from xt/yt (degrees) [1 to NBody] [only used when PotMod=1] +HydroDyn 60 PtfmVol0 6000 PtfmVol0 - Displaced volume of water when the body is in its undisplaced position (m^3) [1 to NBody] [only used when PotMod=1; USE THE SAME VALUE COMPUTED BY WAMIT AS OUTPUT IN THE .OUT FILE!] +HydroDyn 61 PtfmCOBxt 0.0 PtfmCOBxt - The xt offset of the center of buoyancy (COB) from (0,0) (meters) [1 to NBody] [only used when PotMod=1] +HydroDyn 62 PtfmCOByt 0.0 PtfmCOByt - The yt offset of the center of buoyancy (COB) from (0,0) (meters) [1 to NBody] [only used when PotMod=1] +HydroDyn 69-74 AddF0 0 AddF0 - Additional preload (N, N-m) [If NBodyMod=1, one size 6*NBody x 1 vector; if NBodyMod>1, NBody size 6 x 1 vectors] +HydroDyn 75-80 AddCLin 0 0 0 0 0 0 AddCLin - Additional linear stiffness (N/m, N/rad, N-m/m, N-m/rad) [If NBodyMod=1, one size 6*NBody x 6*NBody matrix; if NBodyMod>1, NBody size 6 x 6 matrices] +HydroDyn 81-86 AddBLin 0 0 0 0 0 0 AddBLin - Additional linear damping(N/(m/s), N/(rad/s), N-m/(m/s), N-m/(rad/s)) [If NBodyMod=1, one size 6*NBody x 6*NBody matrix; if NBodyMod>1, NBody size 6 x 6 matrices] +HydroDyn 87-92 AddBQuad 0 0 0 0 0 0 AddBQuad - Additional quadratic drag(N/(m/s)^2, N/(rad/s)^2, N-m(m/s)^2, N-m/(rad/s)^2) [If NBodyMod=1, one size 6*NBody x 6*NBody matrix; if NBodyMod>1, NBody size 6 x 6 matrices] +HydroDyn na Simple Coef Tab SimplCd SimplCdMG SimplCa SimplCaMG SimplCp SimplCpMG SimplAxCa SimplAxCaMG SimplAxCa SimplAxCaMG SimplAxCp SimplAxCpMG +HydroDyn na (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) +HydroDyn na Depth Coef Tab Dpth DpthCd DpthCdMG DpthCa DpthCaMG DpthCp DpthCpMG DpthAxCa DpthAxCaMG DpthAxCa DpthAxCaMG DpthAxCp DpthAxCpMG +HydroDyn na (m) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) +HydroDyn na Member Coef Tab 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 +HydroDyn na (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) +HydroDyn na OutList names *see OutlistParameters.xlsx for new and revised output channel names* +============================================= ====== =============== ====================================================================================================================================================================================================== + +============================================= ==== =============== ======================================================================================================================================================================================================== +Removed in OpenFAST v2.6.0 +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Module Line Flag Name Example Value +============================================= ==== =============== ======================================================================================================================================================================================================== +HydroDyn 68 na ---------------------- FLOATING PLATFORM FORCE FLAGS -------------------------- [unused with WaveMod=6] +HydroDyn 69 PtfmSgF True PtfmSgF - Platform horizontal surge translation force (flag) or DEFAULT +HydroDyn 70 PtfmSwF True PtfmSwF - Platform horizontal sway translation force (flag) or DEFAULT +HydroDyn 71 PtfmHvF True PtfmHvF - Platform vertical heave translation force (flag) or DEFAULT +HydroDyn 72 PtfmRF True PtfmRF - Platform roll tilt rotation force (flag) or DEFAULT +HydroDyn 73 PtfmPF True PtfmPF - Platform pitch tilt rotation force (flag) or DEFAULT +HydroDyn 74 PtfmYF True PtfmYF - Platform yaw rotation force (flag) or DEFAULT +============================================= ==== =============== ======================================================================================================================================================================================================== + + + OpenFAST v2.4.0 to OpenFAST v2.5.0 ---------------------------------- @@ -25,6 +118,7 @@ InflowWind 7 VFlowAng 0 VFlowAng - Upflow angle (degree ============== ==== ================== ============================================================================================================================================================================= + OpenFAST v2.3.0 to OpenFAST v2.4.0 ---------------------------------- @@ -62,6 +156,8 @@ AirFoilTables 40\* filtCutOff "DEFAULT" filtCutOff Additional nodal output channels added for :ref:`AeroDyn15`, :ref:`BeamDyn`, and :ref:`ElastoDyn`. + + OpenFAST v2.2.0 to OpenFAST v2.3.0 ---------------------------------- @@ -84,12 +180,14 @@ AeroDyn 37 AFTabMod 1 AFTabMod ============================================= ==== =============== ======================================================================================================================================================================================================== + OpenFAST v2.1.0 to OpenFAST v2.2.0 ---------------------------------- No changes required. + OpenFAST v2.0.0 to OpenFAST v2.1.0 ---------------------------------- @@ -101,6 +199,8 @@ OpenFAST v2.0.0 to OpenFAST v2.1.0 BeamDyn driver 21 GlbRotBladeT0 True GlbRotBladeT0 - Reference orientation for BeamDyn calculations is aligned with initial blade root? ============== ==== ================== ===================================================================================================================================================================== + + OpenFAST v1.0.0 to OpenFAST v2.0.0 ---------------------------------- diff --git a/docs/source/user/index.rst b/docs/source/user/index.rst index 8a94dcaf93..79ccef984a 100644 --- a/docs/source/user/index.rst +++ b/docs/source/user/index.rst @@ -17,6 +17,7 @@ Details on the transition from FAST v8 to OpenFAST may be found in :numref:`fast aerodyn-olaf/index.rst aerodyn-aeroacoustics/index.rst beamdyn/index.rst + subdyn/index.rst elastodyn/index.rst inflowwind/index.rst fast_to_openfast.rst diff --git a/docs/source/user/subdyn/.gitignore b/docs/source/user/subdyn/.gitignore new file mode 100644 index 0000000000..ba08b44184 --- /dev/null +++ b/docs/source/user/subdyn/.gitignore @@ -0,0 +1,4 @@ +_build* +*.pdf +*.docx +_* diff --git a/docs/source/user/subdyn/Makefile b/docs/source/user/subdyn/Makefile new file mode 100644 index 0000000000..c7b2f24a4d --- /dev/null +++ b/docs/source/user/subdyn/Makefile @@ -0,0 +1,136 @@ +# Makefile for Sphinx documentation +# +MAIN=SubDyn +INKSCAPE="C:/Program Files/Inkscape/inkscape.exe" + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + + +SVGDIR=figs +SVGOUTDIR=figs +SVGS=$(notdir $(wildcard $(SVGDIR)/*.svg)) +SVGS2PDFS=$(patsubst %,$(SVGOUTDIR)/%,$(SVGS:.svg=.pdf)) +SVGS2PNGS=$(patsubst %,$(SVGOUTDIR)/%,$(SVGS:.svg=.png)) +#INKSCAPE=inkscape + + +.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest + +all: pdf + +doc2rst: + pandoc -F pandoc-crossref -F pandoc-citeproc -s -t rst --toc SubDyn_Manual_Rev037.docx -o output.rst --bibliography=references_SD.bib + +# --wrap=preserve +# -F pandoc-crossref +# -F pandoc-eqnos +# --number-section + + +help: + @echo "Please use \`make ' where is one of" + @echo " pdf to make pdf from LaTeX files (uses latex)" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf _build/* + +pdf: latex pdf-compile +# diff +# cd _build/latex && make all-pdf + +pdf-compile: + cd _build/latex && pdflatex $(MAIN).tex +# cd _build/latex && make all-pdf + +pdf-html: pdf html + cp _build/latex/sampledoc.pdf _build/html + +diff: + cd _build/latex && latexdiff -p ../../LatexDiffPreamble.tex $(MAIN)-old.tex $(MAIN).tex > $(MAIN)-diff.tex + cd _build/latex && cp $(MAIN).aux $(MAIN)-diff.aux + cd _build/latex && pdflatex --interaction=nonstopmode $(MAIN)-diff.tex + +# Rule to create pdf or png from svg +$(SVGOUTDIR)/%.pdf:$(SVGDIR)/%.svg + $(INKSCAPE) -A -D --file="$<" "$@" +$(SVGOUTDIR)/%.png:$(SVGDIR)/%.svg + $(INKSCAPE) -D --export-dpi 300 --file="$<" -e "$@" + + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html + @echo + @echo "Build finished. The HTML pages are in _build/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) _build/dirhtml + @echo + @echo "Build finished. The HTML pages are in _build/dirhtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) _build/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in _build/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) _build/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in _build/qthelp, like this:" + @echo "# qcollectiongenerator _build/qthelp/sampledoc.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile _build/qthelp/sampledoc.qhc" + +latex: $(SVGS2PNGS) + cp -r figs _build/latex + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex + @echo + @echo "Build finished; the LaTeX files are in _build/latex." + @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ + "run these through (pdf)latex." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes + @echo + @echo "The overview file is in _build/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in _build/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) _build/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in _build/doctest/output.txt." + diff --git a/docs/source/user/subdyn/appendixA.rst b/docs/source/user/subdyn/appendixA.rst new file mode 100644 index 0000000000..898a38f2bb --- /dev/null +++ b/docs/source/user/subdyn/appendixA.rst @@ -0,0 +1,13 @@ +.. _sd_appendix_A: + +Appendix A. OC4 Jacket Input File +================================= + +SubDyn's primary input file +:download:`(OC4 Jacket SubDyn's Input File) <./examples/OC4_Jacket_SD_Input.dat>`: + +This file includes information on the integration method (e.g., Adams-Bashforth 4 :sup:`th`} order), +numerical-solution parameters (e.g., integration time interval, static solver flag, numer of modes to retain within the Craig-Bampton reduction), +finite element analysis information (beam element model, number of elements per member), +and the geometric definition of the beam members via joints, member connectivity, and member cross-sectional properties. +This file also specifies any SSI input files (soil/pile stiffness and mass matrices). diff --git a/docs/source/user/subdyn/appendixB.rst b/docs/source/user/subdyn/appendixB.rst new file mode 100644 index 0000000000..02f21e901e --- /dev/null +++ b/docs/source/user/subdyn/appendixB.rst @@ -0,0 +1,12 @@ +.. _sd_appendix_B: + +Appendix B. OC4 Jacket Driver File +================================== + +SubDyn's Driver Input File +:download:`(OC4 Jacket Driver File) <./examples/OC4_Jacket_SD_Driver.dvr>`: + +This file includes information on the environmental conditions (gravity and water depth), +numerical-solution parameters (e.g., integration time interval, numer of time-steps), TP reference point coordinates in global reference frame, +rotation angle of the structure geometry in degrees about the global Z axis, the input mode for the TP reference point displacements, velocities, and accelerations (steady-state or time-series from file) and any related input +file if not steady-state input. diff --git a/docs/source/user/subdyn/appendixC.rst b/docs/source/user/subdyn/appendixC.rst new file mode 100644 index 0000000000..74af12f314 --- /dev/null +++ b/docs/source/user/subdyn/appendixC.rst @@ -0,0 +1,9 @@ +.. _sd_appendix_C: + +Appendix C. OC4 Jacket SSI Input File +===================================== + +SubDyn's SSI File +:download:`(OC4 Jacket SSI File) <./examples/OC4_Jacket_SD_SSI.txt>`: + +This file includes information on the stiffness of embedded-pile/soil combination. diff --git a/docs/source/user/subdyn/appendixD.rst b/docs/source/user/subdyn/appendixD.rst new file mode 100644 index 0000000000..e2bcbab592 --- /dev/null +++ b/docs/source/user/subdyn/appendixD.rst @@ -0,0 +1,104 @@ +.. _sd_appendix_D: + +Appendix D. List of Output Channels +=================================== + +This is a list of all possible output parameters for the SubDyn module. +The names are grouped by meaning, but can be ordered in the OUTPUT +CHANNELS section of the SubDyn input file as the user sees fit. :math:`M \alpha N \beta`, +refers to node :math:`\beta` of member :math:`\alpha`, where :math:`\alpha` is a number in the range [1,9] and +corresponds to row :math:`\alpha` in the MEMBER OUTPUT LIST table (see Section ) and +:math:`\beta` is a number in the range [1,9] and corresponds to node :math:`\beta` in the +**NodeCnt** list of that table entry. + +Some outputs are in the SS reference coordinate system (global +inertial-frame coordinate system), and end with the suffix `ss`; others +refer to the local (member) reference system and they have suffixes +"Xe", "Ye", or "Ze" (see Section 7). + +Table C-1. List of Output Channels. + ++---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| Channel Name(s) | Units | Description | ++=======================================+==============================================================+=====================================================================================================================================+ +| *Base and Interface Reaction Loads* | | ++---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| ReactFXss, ReactFYss, ReactFZss, | (N), (N), (N), | Total base reaction forces and moments | +| | | | +| ReactMXss, ReactMYss, ReactMZss, | (Nm), (Nm), (Nm) | at the (0.,0.,-**WtrDpth**) location in SS coordinate system | ++---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| IntfFXss, IntfFYss, IntfFZss, | (N), (N), (N), | Total interface reaction forces and moments | +| | | | +| IntfMXss, IntfMYss, IntfMZss, | (Nm), (Nm), (Nm) | at the TP reference point (platform reference point) location in SS coordinate system | ++---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| Interface Kinematics | | ++---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| IntfTDXss, IntfTDYss, IntfTDZss, | (m), (m), (m), | Displacements and rotations of the TP reference point | +| | | | +| IntfRDXss, IntfRDYss IntfRDZss | (rad), (rad), (rad) | (platform reference point) location in SS coordinate system | ++---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| IntfTAXss, IntfTAYss, IntfTAZss, | (:math:`{m/s^2}`), (:math:`{m/s^2}`), (:math:`{m/s^2}`), | Translational and rotational accelerations of the TP reference point | +| | | | +| IntfRAXss, IntfRAYss IntfRAZss | (:math:`{rad/s^2}`), (:math:`{rad/s^2}`), (:math:`{rad/s^2}`)| (platform reference point) location in SS coordinate system | ++---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| *Modal Parameters* | | ++---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SSqm01-SSqm99 | (-) | C-B modal variables (up to first 99) | ++---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SSqmd01-SSqmd99 | (1/s) | First time-derivatives of C-B modal variables (up to first 99) | ++---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SSqmdd01-SSqmdd99 | (:math:`{1/s^2}`) | Second time-derivatives of C-B modal variables (up to first 99) | ++---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| *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, | | | +| | | (up to 81 designated locations) in member local coordinate system | +| :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}` 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) | | ++---------------------------------------+--------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ + diff --git a/docs/source/user/subdyn/appendixE.rst b/docs/source/user/subdyn/appendixE.rst new file mode 100644 index 0000000000..888f6e6183 --- /dev/null +++ b/docs/source/user/subdyn/appendixE.rst @@ -0,0 +1,7 @@ +.. _sd_appendix_E: + +Appendix E. Compiling Stand-Alone SubDyn +======================================== + +See the FAST documentation for instructions on how to compile SubDyn coupled to FAST. +Future versions of the manual will include compiling instructions for building the stand-alone SubDyn program. diff --git a/docs/source/user/subdyn/appendixF.rst b/docs/source/user/subdyn/appendixF.rst new file mode 100644 index 0000000000..c73ea87253 --- /dev/null +++ b/docs/source/user/subdyn/appendixF.rst @@ -0,0 +1,144 @@ +.. _sd_appendix_F: + +Appendix F. Major Changes in SubDyn +=================================== + +When first released, SubDyn (v0.4) was included as an undocumented +feature of FAST v8 and packaged as a stand-alone archive. Since v0.4, +SubDyn has been well integrated into FAST v8 and OpenFast, and the stand-alone form is +also available. This appendix outlines significant modifications to +SubDyn made since v0.4. Following are the main changes that the user may +notice, but for more information, refer to the *changelog.txt* text file +within the official archive and the GitHub log. + + +V1.04.00 (September 2020) +------------------------------ + +- Version 1.04.00 integrates with OpenFAST version 2.4 + +- Member types: beam, rigid link, pretension cable + +- Joint types: cantilever, universal, pin, ball + +- Input of all terms for concentrated mass + +- Guyan damping matrix + +- Extra lever arm + +- Coupling sith SoilDyn + +- Inclusion of soil-structure interaction (SSI) via flexible degrees of fixity at the restrained nodes and a new input file that allows for 6x6 stiffness and mass matrices that simulate boundary conditions at those nodes. + +- Controllable pretension cable elements + + +V1.03.00a-rrd (September 2017) +------------------------------ + +- Version 1.03.00a-rrd integrates with the `OpenFast software `__. + + + +V1.01.01a-rrd (September 2014) +------------------------------ + +Version 1.01.01a-rrd integrates with the `FAST v8 +software `__ +v8.09.00a-bjj. + +- Finite-element eigenvalue bug fixes: the full system eigenvalues were + incorrectly reported in the summary file, although with no further + consequences on the results. This bug is now fixed. + +- Shear area correction factor improvement: the shear area correction + factor in the Timoshenko treatment is now aligned with Steinboeck et + al. (2013). + +- The formulation for the TP reaction has been rearranged to adhere to + the theory manual, with no consequences on the output results. + + +V1.01.00a-rrd (June 2014) +------------------------------ + +Version 1.00.01a-rrd integrates with the `FAST v8 software `__ +v8.08.00c-bjj. + +The new implementation has well-defined data exchange interfaces +(`following the FAST modularization +framework `__) +that should make integration of SubDyn into other multiphysics software +packages much simpler. + +Several improvements and bug fixes have been implemented since version +v0.4 and the module has undergone an extensive verification effort with +good results. + +- Eigensolver bug fixes: the LAPACK solver proved to be unstable in + single precision, and now it is solely run in double precision, + regardless of the precision used in other parts of the code. + +- The input file format has changed. Please refer to the sample input + file in Appendix A and the following notes: + + - First header line has been removed. + + - Simulation Control Section: + + - **SDeltaT**: The "DEFAULT" keyword (in place of 0.0) is now + used to indicate that the glue-code time step will be used for + time integration by SubDyn. + + - **IntMethod**: Allowed values are now 1-4 (in place of 0-3). + + - **SttcSolve**: New flag introduced. If set to TRUE, the + static-improvement method (SIM) will be used. + + - FEA and Craig-Bampton Parameters Section: + + - In v0.4, the damping coefficients had to be specified for all + retained Craig-Bampton modes, or just once for all the modes + (if **CBMod** = FALSE). In this version, the user can input + any number of damping coefficients. In case the number of + retained C-B modes (**NModes**) is larger than the input + number of damping coefficients (**JDampings**), the last + damping value will be replicated for all the remaining modes. + + - Base Reaction Joints, Interface Joints, Member, and Member Cosine + Matrices Sections: + + - One line with units, below the headers, is expected in all the + tables of the input file. + + - Output: Summary and Outfile Section: + + - This section now also contains the parameters previously + assigned under the Section titled "Output: Fast/Subdyn + Output-File Variables" + +- Some of the quantities in the summary file have been fixed. Some of + the output matrices were, in fact, being output with wrong values + because of an index mismatch. The new summary file is shorter and + does not contain some of the CB method matrices, unless the compiler + directive, DEBUG, is set. + +- SIM. This new implementation helps minimize the number of needed + modes to capture the contribution of certain loads (such as static + gravity and buoyancy loads or high-frequency loads transferred from + the turbine). In the previous version, a large number of internal + modes were needed to engage substructural modes excited by static and + high-frequency forces. These modes are no longer needed and fewer + modes can be retained while still achieving accurate results (see + also :numref:`subdyn-theory`). With SIM enabled, all modes that are not considered + by the Craig-Bampton reduction are treated quasi-statically. + +- There is now the possibility of retaining no internal C-B modes, thus + relying solely only on SIM, in those cases where the substructure`s + first eigenfrequencies are much higher than the expected + energy-containing modes of the entire system. + +- The coupling of SubDyn within FAST now includes full hydro-elastic + coupling with the HydroDyn hydrodynamics module. + diff --git a/docs/source/user/subdyn/conf.py b/docs/source/user/subdyn/conf.py new file mode 100644 index 0000000000..50911aa137 --- /dev/null +++ b/docs/source/user/subdyn/conf.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +# +# OpenFAST documentation build configuration file, created by +# sphinx-quickstart on Wed Jan 25 13:52:07 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. + +import os +import sys +import subprocess +import re + +#sys.path.append(os.path.abspath('_extensions/')) + +readTheDocs = os.environ.get('READTHEDOCS', None) == 'True' +sourcedir = sys.argv[-2] +builddir = sys.argv[-1] + +# Use this to turn Doxygen on or off +useDoxygen=False + +# This function was adapted from https://gitlab.kitware.com/cmb/smtk +# Only run when on readthedocs +def runDoxygen(sourcfile, doxyfileIn, doxyfileOut): + dx = open(os.path.join(sourcedir, doxyfileIn), 'r') + cfg = dx.read() + srcdir = os.path.abspath(os.path.join(os.getcwd(), '..')) + bindir = srcdir + c2 = re.sub('@CMAKE_SOURCE_DIR@', srcdir, \ + re.sub('@CMAKE_BINARY_DIR@', bindir, cfg)) + doxname = os.path.join(sourcedir, doxyfileOut) + dox = open(doxname, 'w') + print >>dox, c2 + dox.close() + print 'Running Doxygen on %s' % doxyfileOut + doxproc = subprocess.call(('doxygen', doxname)) + +if readTheDocs and useDoxygen: + runDoxygen(sourcedir, 'Doxyfile.in', 'Doxyfile') + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.5.2' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.autosummary', + 'sphinx.ext.mathjax', + 'sphinx.ext.intersphinx', + 'sphinxcontrib.doxylink', + 'sphinxcontrib.bibtex', + ] + +autodoc_default_flags = ['members','show-inheritance','undoc-members'] + +autoclass_content = 'both' + +mathjax_path = 'https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML' + +# FIXME: Naively assuming build directory one level up locally, and two up on readthedocs + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = ['.rst'] + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'SubDyn' +copyright = u'2017, National Renewable Energy Laboratory' +author = u'OpenFAST Team' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'1.0' +# The full version, including alpha/beta/rc tags. +release = u'1.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +#If true, figures, tables and code-blocks are automatically numbered if they +#have a caption. At same time, the numref role is enabled. For now, it works +#only with the HTML builder and LaTeX builder. Default is False. +numfig = True + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# FIXME: Naively assuming build directory one level up locally, and two up on readthedocs +if useDoxygen: + if readTheDocs: + html_extra_path = [os.path.join(builddir, '..', '..', 'doxygen')] + else: + html_extra_path = [os.path.join(builddir, '..', 'doxygen')] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' +html_logo = '../../../_static/openfastlogo.jpg' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['../../../_static'] + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Openfastdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'SubDyn.tex', u'SubDyn Documentation', + u'National Renewable Energy Laboratory', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'subdyn', u'SubDyn Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'SunDyn', u'SunDyn Documentation', + author, 'SunDyn', 'One line description of project.', + 'Miscellaneous'), +] + +def setup(app): + app.add_object_type("confval", "confval", + objname="input file parameter", + indextemplate="pair: %s; input file parameter") + app.add_object_type("cmakeval", "cmakeval", + objname="CMake configuration value", + indextemplate="pair: %s; CMake configuration") + diff --git a/docs/source/user/subdyn/examples/OC4_Jacket_SD_Driver.dvr b/docs/source/user/subdyn/examples/OC4_Jacket_SD_Driver.dvr new file mode 100644 index 0000000000..1a9d5f4dcf --- /dev/null +++ b/docs/source/user/subdyn/examples/OC4_Jacket_SD_Driver.dvr @@ -0,0 +1,21 @@ +--- SubDyn Driver file for Unit TestFrame. +Compatible with SubDyn v1.00.00 +TRUE Echo - Echo the input file data (flag) +---------------------- ENVIRONMENTAL CONDITIONS ------------------------------------------------- +9.81 Gravity - Gravity (m/s^2). +43.127 WtrDpth - Water Depth (m) positive value. +---------------------- SubDyn ------------------------------------------------------------------- +".\SubDyn_OC4Jacket.dat" SDInputFile - Absolute or relative path. +".\SubDyn_OC4Jacket" OutRootName - Basename for output files. +600 NSteps - Number of time steps in the simulations (-) +0.001 TimeInterval - TimeInterval for the simulation (sec) +0.0 0.0 18.15 TP_RefPoint - Location of the TP reference point in global coordinates (m) +0.0 SubRotateZ - Rotation angle of the structure geometry in degrees about the global Z axis. +---------------------- INPUTS ------------------------------------------------------------------- + 1 InputsMod - Inputs model {0: all inputs are zero for every timestep, 1: steady state inputs, 2: read inputs from a file (InputsFile)} (switch) +"" InputsFile - Name of the inputs file if InputsMod = 2. This file has to be defined as follows: i: No header. ii: It has NSteps+1 rows and each row (i) has in the first column the time: t = (i-1)*TimeInterval. The successive columns define the displacements ([m], [rad]), velocities ([m/s], [rad/s]) and accelerations ([m/s^2], [rad/s^2]) +---------------------- STEADY INPUTS (for InputsMod = 1) ---------------------------------------- +3.821E-02 1.656E-03 -4.325E-02 -1.339E-04 7.266E-02 -2.411E-03 uTPInSteady - input displacements and rotations ( m, rads ) +1.02 2.03 5.03 0.03 0.03 0.03 uDotTPInSteady - input translational and rotational velocities ( m/s, rads/s) +2.02 3.03 -9.03 0.3 0.03 0.3 uDotDotTPInSteady - input translational and rotational accelerations( m/s^2, rads/s^2) +END of driver input file diff --git a/docs/source/user/subdyn/examples/OC4_Jacket_SD_Input.dat b/docs/source/user/subdyn/examples/OC4_Jacket_SD_Input.dat new file mode 100644 index 0000000000..56c91f40a9 --- /dev/null +++ b/docs/source/user/subdyn/examples/OC4_Jacket_SD_Input.dat @@ -0,0 +1,286 @@ +----------- SubDyn MultiMember Support Structure Input File ------------ +OC4 'Jacket' SubStructure Input File. The grouted connection is simulated with an equivalent tubular beam of enhanced properties. RRD 10/15/2013 +-------------------------- SIMULATION CONTROL --------------------------------- +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. + 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] + 6 GuyanDampSize - Guyan damping matrix (6x6) [only if GuyanDampMod=2] + 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 + 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 + 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 + 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 + 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 + 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 +---- STRUCTURE JOINTS: joints connect structure members (~Hydrodyn Input File)--- + 64 NJoints - Number of joints (-) +JointID JointXss JointYss JointZss JointType JointDirX JointDirY JointDirZ JointStiff + (-) (m) (m) (m) (-) (-) (-) (-) (Nm/rad) + 1 6.00000 6.00000 -45.50000 1 0.0 0.0 0.0 0.0 + 2 6.00000 6.00000 -45.00000 1 0.0 0.0 0.0 0.0 + 3 5.96700 5.96700 -44.00100 1 0.0 0.0 0.0 0.0 + 4 5.93900 5.93900 -43.12700 1 0.0 0.0 0.0 0.0 + 5 5.33300 5.33300 -24.61400 1 0.0 0.0 0.0 0.0 + 6 -6.00000 6.00000 -45.50000 1 0.0 0.0 0.0 0.0 + 7 -6.00000 6.00000 -45.00000 1 0.0 0.0 0.0 0.0 + 8 -5.96700 5.96700 -44.00100 1 0.0 0.0 0.0 0.0 + 9 -5.93900 5.93900 -43.12700 1 0.0 0.0 0.0 0.0 + 10 -5.33300 5.33300 -24.61400 1 0.0 0.0 0.0 0.0 + 11 -6.00000 -6.00000 -45.50000 1 0.0 0.0 0.0 0.0 + 12 -6.00000 -6.00000 -45.00000 1 0.0 0.0 0.0 0.0 + 13 -5.96700 -5.96700 -44.00100 1 0.0 0.0 0.0 0.0 + 14 -5.93900 -5.93900 -43.12700 1 0.0 0.0 0.0 0.0 + 15 -5.33300 -5.33300 -24.61400 1 0.0 0.0 0.0 0.0 + 16 6.00000 -6.00000 -45.50000 1 0.0 0.0 0.0 0.0 + 17 6.00000 -6.00000 -45.00000 1 0.0 0.0 0.0 0.0 + 18 5.96700 -5.96700 -44.00100 1 0.0 0.0 0.0 0.0 + 19 5.93900 -5.93900 -43.12700 1 0.0 0.0 0.0 0.0 + 20 5.33300 -5.33300 -24.61400 1 0.0 0.0 0.0 0.0 + 21 4.82000 4.82000 -8.92200 1 0.0 0.0 0.0 0.0 + 22 4.38500 4.38500 4.37800 1 0.0 0.0 0.0 0.0 + 23 4.01600 4.01600 15.65100 1 0.0 0.0 0.0 0.0 + 24 4.00000 4.00000 16.15000 1 0.0 0.0 0.0 0.0 + 25 -4.82000 4.82000 -8.92200 1 0.0 0.0 0.0 0.0 + 26 -4.38500 4.38500 4.37800 1 0.0 0.0 0.0 0.0 + 27 -4.01600 4.01600 15.65100 1 0.0 0.0 0.0 0.0 + 28 -4.00000 4.00000 16.15000 1 0.0 0.0 0.0 0.0 + 29 -4.82000 -4.82000 -8.92200 1 0.0 0.0 0.0 0.0 + 30 -4.38500 -4.38500 4.37800 1 0.0 0.0 0.0 0.0 + 31 -4.01600 -4.01600 15.65100 1 0.0 0.0 0.0 0.0 + 32 -4.00000 -4.00000 16.15000 1 0.0 0.0 0.0 0.0 + 33 4.82000 -4.82000 -8.92200 1 0.0 0.0 0.0 0.0 + 34 4.38500 -4.38500 4.37800 1 0.0 0.0 0.0 0.0 + 35 4.01600 -4.01600 15.65100 1 0.0 0.0 0.0 0.0 + 36 4.00000 -4.00000 16.15000 1 0.0 0.0 0.0 0.0 + 37 5.62000 0.00000 -33.37300 1 0.0 0.0 0.0 0.0 + 38 -5.62000 0.00000 -33.37300 1 0.0 0.0 0.0 0.0 + 39 0.00000 5.62000 -33.37300 1 0.0 0.0 0.0 0.0 + 40 0.00000 -5.62000 -33.37300 1 0.0 0.0 0.0 0.0 + 41 5.06400 0.00000 -16.37100 1 0.0 0.0 0.0 0.0 + 42 -5.06400 0.00000 -16.37100 1 0.0 0.0 0.0 0.0 + 43 0.00000 5.06400 -16.37100 1 0.0 0.0 0.0 0.0 + 44 0.00000 -5.06400 -16.37100 1 0.0 0.0 0.0 0.0 + 45 4.59200 0.00000 -1.95800 1 0.0 0.0 0.0 0.0 + 46 -4.59200 0.00000 -1.95800 1 0.0 0.0 0.0 0.0 + 47 0.00000 4.59200 -1.95800 1 0.0 0.0 0.0 0.0 + 48 0.00000 -4.59200 -1.95800 1 0.0 0.0 0.0 0.0 + 49 4.19300 0.00000 10.26200 1 0.0 0.0 0.0 0.0 + 50 -4.19300 0.00000 10.26200 1 0.0 0.0 0.0 0.0 + 51 0.00000 4.19300 10.26200 1 0.0 0.0 0.0 0.0 + 52 0.00000 -4.19300 10.26200 1 0.0 0.0 0.0 0.0 + 53 4.00000 4.00000 20.15000 1 0.0 0.0 0.0 0.0 + 54 -4.00000 4.00000 20.15000 1 0.0 0.0 0.0 0.0 + 55 4.00000 -4.00000 20.15000 1 0.0 0.0 0.0 0.0 + 56 -4.00000 -4.00000 20.15000 1 0.0 0.0 0.0 0.0 + 57 6.00000 -6.00000 -49.50000 1 0.0 0.0 0.0 0.0 + 58 6.00000 6.00000 -49.50000 1 0.0 0.0 0.0 0.0 + 59 -6.00000 -6.00000 -49.50000 1 0.0 0.0 0.0 0.0 + 60 -6.00000 6.00000 -49.50000 1 0.0 0.0 0.0 0.0 + 61 6.00000 -6.00000 -50.00100 1 0.0 0.0 0.0 0.0 + 62 6.00000 6.00000 -50.00100 1 0.0 0.0 0.0 0.0 + 63 -6.00000 -6.00000 -50.00100 1 0.0 0.0 0.0 0.0 + 64 -6.00000 6.00000 -50.00100 1 0.0 0.0 0.0 0.0 +------------------- BASE REACTION JOINTS: 1/0 for Locked/Free DOF @ each Reaction Node --------------------- + 4 NReact - Number of Joints with reaction forces; be sure to remove all rigid motion DOFs of the structure (else det([K])=[0]) +RJointID RctTDXss RctTDYss RctTDZss RctRDXss RctRDYss RctRDZss SSIfile [Global Coordinate System] + (-) (flag) (flag) (flag) (flag) (flag) (flag) (string) + 61 1 1 1 1 1 1 "OC4_Jacket_SD_SSI.txt" + 62 1 1 1 1 1 1 "OC4_Jacket_SD_SSI.txt" + 63 1 1 1 1 1 1 "OC4_Jacket_SD_SSI.txt" + 64 1 1 1 1 1 1 "OC4_Jacket_SD_SSI.txt" +------- INTERFACE JOINTS: 1/0 for Locked (to the TP)/Free DOF @each Interface Joint (only Locked-to-TP implemented thus far (=rigid TP)) --------- + 8 NInterf - Number of interface joints locked to the Transition Piece (TP): be sure to remove all rigid motion dofs +IJointID ItfTDXss ItfTDYss ItfTDZss ItfRDXss ItfRDYss ItfRDZss [Global Coordinate System] + (-) (flag) (flag) (flag) (flag) (flag) (flag) + 24 1 1 1 1 1 1 + 28 1 1 1 1 1 1 + 32 1 1 1 1 1 1 + 36 1 1 1 1 1 1 + 53 1 1 1 1 1 1 + 54 1 1 1 1 1 1 + 55 1 1 1 1 1 1 + 56 1 1 1 1 1 1 +----------------------------------- MEMBERS -------------------------------------- + 112 NMembers - Number of frame members +MemberID MJointID1 MJointID2 MPropSetID1 MPropSetID2 MType COSMID + (-) (-) (-) (-) (-) (-) (-) + 1 1 2 2 2 1 + 2 2 3 2 2 1 + 3 3 4 2 2 1 + 4 4 5 2 2 1 + 5 6 7 2 2 1 + 6 7 8 2 2 1 + 7 8 9 2 2 1 + 8 9 10 2 2 1 + 9 11 12 2 2 1 + 10 12 13 2 2 1 + 11 13 14 2 2 1 + 12 14 15 2 2 1 + 13 16 17 2 2 1 + 14 17 18 2 2 1 + 15 18 19 2 2 1 + 16 19 20 2 2 1 + 17 5 21 3 3 1 + 18 21 22 3 3 1 + 19 22 23 3 3 1 + 20 23 24 3 3 1 + 21 10 25 3 3 1 + 22 25 26 3 3 1 + 23 26 27 3 3 1 + 24 27 28 3 3 1 + 25 15 29 3 3 1 + 26 29 30 3 3 1 + 27 30 31 3 3 1 + 28 31 32 3 3 1 + 29 20 33 3 3 1 + 30 33 34 3 3 1 + 31 34 35 3 3 1 + 32 35 36 3 3 1 + 33 8 3 1 1 1 + 34 13 8 1 1 1 + 35 13 18 1 1 1 + 36 18 3 1 1 1 + 37 4 37 1 1 1 + 38 37 20 1 1 1 + 39 19 37 1 1 1 + 40 37 5 1 1 1 + 41 9 38 1 1 1 + 42 38 15 1 1 1 + 43 14 38 1 1 1 + 44 38 10 1 1 1 + 45 4 39 1 1 1 + 46 39 10 1 1 1 + 47 9 39 1 1 1 + 48 39 5 1 1 1 + 49 19 40 1 1 1 + 50 40 15 1 1 1 + 51 14 40 1 1 1 + 52 40 20 1 1 1 + 53 5 41 1 1 1 + 54 41 33 1 1 1 + 55 20 41 1 1 1 + 56 41 21 1 1 1 + 57 10 42 1 1 1 + 58 42 29 1 1 1 + 59 15 42 1 1 1 + 60 42 25 1 1 1 + 61 5 43 1 1 1 + 62 43 25 1 1 1 + 63 10 43 1 1 1 + 64 43 21 1 1 1 + 65 20 44 1 1 1 + 66 44 29 1 1 1 + 67 15 44 1 1 1 + 68 44 33 1 1 1 + 69 21 45 1 1 1 + 70 45 34 1 1 1 + 71 33 45 1 1 1 + 72 45 22 1 1 1 + 73 25 46 1 1 1 + 74 46 30 1 1 1 + 75 29 46 1 1 1 + 76 46 26 1 1 1 + 77 21 47 1 1 1 + 78 47 26 1 1 1 + 79 25 47 1 1 1 + 80 47 22 1 1 1 + 81 33 48 1 1 1 + 82 48 30 1 1 1 + 83 29 48 1 1 1 + 84 48 34 1 1 1 + 85 22 49 1 1 1 + 86 49 35 1 1 1 + 87 34 49 1 1 1 + 88 49 23 1 1 1 + 89 26 50 1 1 1 + 90 50 31 1 1 1 + 91 30 50 1 1 1 + 92 50 27 1 1 1 + 93 22 51 1 1 1 + 94 51 27 1 1 1 + 95 26 51 1 1 1 + 96 51 23 1 1 1 + 97 34 52 1 1 1 + 98 52 31 1 1 1 + 99 30 52 1 1 1 + 100 52 35 1 1 1 + 101 24 53 4 4 1 + 102 28 54 4 4 1 + 103 32 56 4 4 1 + 104 36 55 4 4 1 + 105 58 1 5 5 1 + 106 57 16 5 5 1 + 107 60 6 5 5 1 + 108 59 11 5 5 1 + 109 62 58 6 6 1 + 110 61 57 6 6 1 + 111 64 60 6 6 1 + 112 63 59 6 6 1 +------------------ MEMBER X-SECTION PROPERTY data 1/2 [isotropic material for now: use this table for circular-tubular elements] ------------------------ + 6 NPropSets - Number of structurally unique x-sections (i.e. how many groups of X-sectional properties are utilized throughout all of the members) +PropSetID YoungE ShearG MatDens XsecD XsecT + (-) (N/m2) (N/m2) (kg/m3) (m) (m) + 1 2.10000e+11 8.07690e+10 7850.00 0.800000 0.020000 + 2 2.10000e+11 8.07690e+10 7850.00 1.200000 0.050000 + 3 2.10000e+11 8.07690e+10 7850.00 1.200000 0.035000 + 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 +------------------ MEMBER X-SECTION PROPERTY data 2/2 [isotropic material for now: use this table if any section other than circular, however provide COSM(i,j) below] ------------------------ + 0 NXPropSets - Number of structurally unique non-circular x-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) +-------------------------- CABLE PROPERTIES ------------------------------------- + 0 NCablePropSets - Number of cable cable properties +PropSetID EA MatDens T0 + (-) (N) (kg/m) (N) +----------------------- RIGID LINK PROPERTIES ------------------------------------ + 0 NRigidPropSets - Number of rigid link properties +PropSetID MatDens + (-) (kg/m) +---------------------- MEMBER COSINE MATRICES COSM(i,j) ------------------------ + 0 NCOSMs - Number of unique cosine matrices (i.e., of unique member alignments including principal axis rotations); ignored if NXPropSets=0 or 9999 in any element below +COSMID COSM11 COSM12 COSM13 COSM21 COSM22 COSM23 COSM31 COSM32 COSM33 + (-) (-) (-) (-) (-) (-) (-) (-) (-) (-) +------------------------ JOINT ADDITIONAL CONCENTRATED MASSES-------------------------- + 0 NCmass - Number of joints with concentrated masses; Global Coordinate System +CMJointID JMass JMXX JMYY JMZZ JMXY JMXZ JMYZ MCGX MCGY MCGZ + (-) (kg) (kg*m^2) (kg*m^2) (kg*m^2) (kg*m^2) (kg*m^2) (kg*m^2) (m) (m) (m) +---------------------------- OUTPUT: SUMMARY & OUTFILE ------------------------------ +True SumPrint - Output a Summary File (flag).It contains: matrices K,M and C-B reduced M_BB, M-BM, K_BB, K_MM(OMG^2), PHI_R, PHI_L. It can also contain COSMs if requested. +False OutCOSM - Output cosine matrices with the selected output member forces (flag) +False OutAll - [T/F] Output all members' end forces + 1 OutSwtch - [1/2/3] Output requested channels to: 1=.SD.out; 2=.out (generated by FAST); 3=both files. +True TabDelim - Generate a tab-delimited output in the .SD.out file + 1 OutDec - Decimation of output in the .SD.out file +"ES11.4e2" OutFmt - Output format for numerical results in the .SD.out file +"A11" OutSFmt - Output format for header strings in the .SD.out file +------------------------- MEMBER OUTPUT LIST ------------------------------------------ + 8 NMOutputs - Number of members whose forces/displacements/velocities/accelerations will be output (-) [Must be <= 9]. +MemberID NOutCnt NodeCnt [NOutCnt=how many nodes to get output for [< 10]; NodeCnt are local ordinal numbers from the start of the member, and must be >=1 and <= NDiv+1] If NMOutputs=0 leave blank as well. + (-) (-) (-) + 22 1 3 + 30 1 3 + 73 1 3 + 83 1 3 + 41 2 2 3 + 51 2 2 3 + 6 1 3 + 14 1 3 +------------------------- SDOutList: The next line(s) contains a list of output parameters that will be output in .SD.out or .out. ------ +"M1N1FKZe, M2N1FKZe" - Axial force in leg 2 at K1L2 and in leg 4 at K1L4 +"M3N1TDXss, M3N1TDYss, M3N1TDZss, M4N1TDXss, M4N1TDYss, M4N1TDZss" - Deflections at X2S2, X2S3: use cosdir matrix to get Out-of-plane (OOP) deflection +"M5N2TDXss, M5N2TDYss, M5N2TDZss, M6N2TDXss, M6N2TDYss, M6N2TDZss" - Deflections at X4S2, X4S3: use cosdir matrix to get OOP deflection +"M5N1FKXe,M5N1FKYe,M5N1FKZe,M6N1FKXe,M6N1FKYe,M6N1FKZe" - Forces OOP and Axial at mid brace points x,y, z >> *we will need to do some post-processing using the direction cosine matrices to get OOP forces +"M7N1FKZe, M8N1FKZe" - Axial force in leg 2 and leg 4 at mudbrace level: MudbraceL2, MudbraceL4 +"-ReactFXss, -ReactFYss, -ReactMXss, -ReactMYss, -ReactMZss, -ReactFZss" - Base reactions: fore-aft shear, side-to-side shear, side-to-side moment, fore-aft moment, yaw moment, vertical force +END of output channels and end of file. (the word "END" must appear in the first 3 columns of this line) diff --git a/docs/source/user/subdyn/examples/OC4_Jacket_SD_SSI.txt b/docs/source/user/subdyn/examples/OC4_Jacket_SD_SSI.txt new file mode 100644 index 0000000000..86e6875ee7 --- /dev/null +++ b/docs/source/user/subdyn/examples/OC4_Jacket_SD_SSI.txt @@ -0,0 +1,23 @@ +!---------------- Pile Head K and M elements -------------------! +!Equivalent Stiffness Constants: Kxx, Kyy, Kzz, Kxtx, Kxty..Kztx,Kzty,Kztz in any order; max 21 elements +-1.98E+09 Kxty +-6.83E-02 Kyty +0.00E+00 Kzty +-2.73E-01 Ktxty +1.35E+10 Ktyty +0.00E+00 Kxtz +0.00E+00 Kytz +0.00E+00 Kztz +0.00E+00 Ktxtz +0.00E+00 Ktytz +7.00E+08 Ktztz +5.04E+08 Kxx +3.11E-02 Kxy +5.06E+08 Kyy +0.00E+00 Kxz +0.00E+00 Kyz +2.54E+09 Kzz +6.83E-02 Kxtx +1.99E+09 Kytx +0.00E+00 Kztx +1.35E+10 Ktxtx \ No newline at end of file diff --git a/docs/source/user/subdyn/figs/ElementsDefinitions.png b/docs/source/user/subdyn/figs/ElementsDefinitions.png new file mode 100644 index 0000000000..5c949f4a46 Binary files /dev/null and b/docs/source/user/subdyn/figs/ElementsDefinitions.png differ diff --git a/docs/source/user/subdyn/figs/ElementsDefinitions.svg b/docs/source/user/subdyn/figs/ElementsDefinitions.svg new file mode 100644 index 0000000000..1d33ad96db --- /dev/null +++ b/docs/source/user/subdyn/figs/ElementsDefinitions.svg @@ -0,0 +1,1132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Members + Elements (after subdivision) + + + Joints (from input file) Joint Axis + Joints (after subdivision) + + + + Element nodal DOFs Element frame + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Rigid links + + Rigid link assembly + + diff --git a/docs/source/user/subdyn/figs/FEJointPin.png b/docs/source/user/subdyn/figs/FEJointPin.png new file mode 100644 index 0000000000..6ef0e6ddb1 Binary files /dev/null and b/docs/source/user/subdyn/figs/FEJointPin.png differ diff --git a/docs/source/user/subdyn/figs/FEJointPin.svg b/docs/source/user/subdyn/figs/FEJointPin.svg new file mode 100644 index 0000000000..191cc88441 --- /dev/null +++ b/docs/source/user/subdyn/figs/FEJointPin.svg @@ -0,0 +1,815 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + xk + k + + + + + + + + + + + + + + + l + xl + p + + + + + + + + p2 + p1 + + + + diff --git a/docs/source/user/subdyn/figs/FEPreTension.png b/docs/source/user/subdyn/figs/FEPreTension.png new file mode 100644 index 0000000000..98fa929d77 Binary files /dev/null and b/docs/source/user/subdyn/figs/FEPreTension.png differ diff --git a/docs/source/user/subdyn/figs/FEPreTension.svg b/docs/source/user/subdyn/figs/FEPreTension.svg new file mode 100644 index 0000000000..f1798ec77f --- /dev/null +++ b/docs/source/user/subdyn/figs/FEPreTension.svg @@ -0,0 +1,905 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + L0 + uz + Le + ux + θ + + T0 + Td + + Ld + + ∆L0<0 + + + + + diff --git a/docs/source/user/subdyn/figs/element-cs.png b/docs/source/user/subdyn/figs/element-cs.png new file mode 100644 index 0000000000..08f7775e8a Binary files /dev/null and b/docs/source/user/subdyn/figs/element-cs.png differ diff --git a/docs/source/user/subdyn/figs/extramoment.png b/docs/source/user/subdyn/figs/extramoment.png new file mode 100644 index 0000000000..2a94789185 Binary files /dev/null and b/docs/source/user/subdyn/figs/extramoment.png differ diff --git a/docs/source/user/subdyn/figs/extramoment.svg b/docs/source/user/subdyn/figs/extramoment.svg new file mode 100644 index 0000000000..97f05733d5 --- /dev/null +++ b/docs/source/user/subdyn/figs/extramoment.svg @@ -0,0 +1,624 @@ + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Case 1: fixed bottom Case 2: free/floating + Input position Reference position + + + + + + + + + + + + + + + + + + + + Deflected position "Guyan" position + uTP + Input position Reference position + + + + "Guyan" position + uTP + + + + + ∆ui fi + + + + ∆ui fi + Deflected position uTP + + + + RiUTP" + + + + RiUTP" + diff --git a/docs/source/user/subdyn/figs/flowchart.png b/docs/source/user/subdyn/figs/flowchart.png new file mode 100644 index 0000000000..275441f20e Binary files /dev/null and b/docs/source/user/subdyn/figs/flowchart.png differ diff --git a/docs/source/user/subdyn/figs/flowchart2.png b/docs/source/user/subdyn/figs/flowchart2.png new file mode 100644 index 0000000000..558465d425 Binary files /dev/null and b/docs/source/user/subdyn/figs/flowchart2.png differ diff --git a/docs/source/user/subdyn/figs/global-cs.png b/docs/source/user/subdyn/figs/global-cs.png new file mode 100644 index 0000000000..faca86ab9e Binary files /dev/null and b/docs/source/user/subdyn/figs/global-cs.png differ diff --git a/docs/source/user/subdyn/figs/self-extractor.png b/docs/source/user/subdyn/figs/self-extractor.png new file mode 100644 index 0000000000..6780556605 Binary files /dev/null and b/docs/source/user/subdyn/figs/self-extractor.png differ diff --git a/docs/source/user/subdyn/future_work.rst b/docs/source/user/subdyn/future_work.rst new file mode 100644 index 0000000000..feb963d2f0 --- /dev/null +++ b/docs/source/user/subdyn/future_work.rst @@ -0,0 +1,42 @@ +.. _sd_future-work: + +Known Limitations and Future Work +================================= + + +The following list contains known current limitations in the code: + +- Tight coupling is not yet supported. + +- Only nontapered two-node Euler-Bernoulli (E-B) or Timoshenko (T) + element formulations are available. (In the future, tapered E-B and + tapered Timoshenko element formulations will be implemented.) + +- Only straight circular members are permitted. (In the future, a + generic cross section will be allowed.) + +- The number of elements per member (**NDiv**) is constant throughout + the structure. + +- Internal matrices are not stored in sparse form, limiting the total + number of possible nodes/DOFs to about 300/1800. + +- The dynamics system reduction is performed in the absence of external + loading (e.g., hydrodynamic added mass). + +- Gravitational loading does not impact the global substructure + stiffness. + +- Loads (gravitational, inertial, hydrodynamic) can only be applied as + concentrated loads at element nodes; distributed loads (per unit + length) are not yet supported. + +- The overlap of multiple members connected to a single joint is not + modeled with super-elements. + +- Member-level outputs are only available for up to nine nodes of up to + nine members (although the **OutAll** flag can generate further + outputs at the member end nodes). + +- No graphics/animation capability is yet available to visualize the + substructure geometry, modes, motion, and loads. diff --git a/docs/source/user/subdyn/index.rst b/docs/source/user/subdyn/index.rst new file mode 100644 index 0000000000..d0ae506e5d --- /dev/null +++ b/docs/source/user/subdyn/index.rst @@ -0,0 +1,32 @@ +SubDyn User Guide and Theory Manual +====================================== + +.. only:: html + + This manual offers both a quick reference guide and a more in-depth theory guide for the SubDyn software program. + It is intended to be used by the general user in combination with the OpenFAST and HydroDyn manuals. + The documentation was started from :cite:`subdyn:manual` by Damiani et al. + The manual will be updated as new releases are issued and as needed to provide further information on advancements or modifications to the software. + + + The authors would like to acknowledge the following contributors: R. Damiani, E. Branlard, J. Jonkman, A. Robertson, F. Wendt and B. Barahona. Additional contributors may be found on github. + We also are grateful to the U.S. Department of Energy Wind and Water Power Program for supporting the development of this software. + + +.. toctree:: + :maxdepth: 2 + + introduction.rst + running_sd.rst + input_files.rst + output_files.rst + modeling.rst + theory.rst + future_work.rst + zrefs.rst + appendixA.rst + appendixB.rst + appendixC.rst + appendixD.rst + appendixE.rst + appendixF.rst diff --git a/docs/source/user/subdyn/input_files.rst b/docs/source/user/subdyn/input_files.rst new file mode 100644 index 0000000000..e1cf611138 --- /dev/null +++ b/docs/source/user/subdyn/input_files.rst @@ -0,0 +1,677 @@ +.. _sd_input-files: + +Input Files +=========== + +The user specifies the substructure model parameters, including its +geometry and properties, via a primary SubDyn input file. When used in +stand-alone mode, an additional driver input file is required. This +driver file specifies inputs normally provided to SubDyn by FAST, +including motions of the TP reference point. + +No lines should be added or removed from the input files, except in +tables where the number of rows is specified. + +Additional input files containing soil-structure information (*SSIfile*) +can be provided by the user specifying their paths in the main SubDyn +input file under the section titled *BASE REACTION JOINTS*. + +Units +----- + +SubDyn uses the SI system (kg, m, s, N). Angles are assumed to be in +radians unless otherwise specified. + +.. _sd_driver-input-file: + +SubDyn Driver Input File +------------------------- + +The driver input file is only needed for the stand-alone version of +SubDyn and contains inputs that are normally set by FAST, and that are +necessary to control the simulation for uncoupled models. It is possible +to provide per-time-step inputs to SubDyn, even in stand-alone mode, by +tying the driver file to an additional input file containing +time-histories of the TP motion (displacements, velocities, and +accelerations). A sample SubDyn driver input file is given in +:numref:`sd_appendix_B`. + +Users can set the **Echo** flag in this file to TRUE so that +*SubDyn\_win32.exe* echoes the contents of the driver input file (useful +for debugging errors in the driver file). The echo file has the naming +convention of **OutRootName.dvr.ech**. **OutRootName** is specified +in the SUBDYN section of the driver input file (see below). + +Set the gravity constant using the **Gravity** parameter. SubDyn +expects a magnitude, so in SI units this would be set to 9.80665 +:math:`\frac{m}{s^{2}}` for standard gravity. **WtrDpth** specifies +the water depth (depth of the seabed), based on the reference MSL, and +must be a value greater than zero. + +**SDInputFile** is the file name of the primary SubDyn input file. +This name should be in quotations and can contain an absolute path or a +relative path. All SubDyn-generated output files will be prefixed with +**OutRootName**. If this parameter includes a file path, the output +will be generated in that folder. **NSteps** specifies the number of +simulation time steps, and **TimeStep** specifies the time between +steps. Next, the user must specify the location of the TP reference +point **TP\_RefPoint** (in the global reference system). This is +normally set by FAST through the ElastoDyn input file, and it is the +so-called *platform* reference point location. When coupled to FAST, the +*platform* reference point location is identified by only one (*Z*) +coordinate. The interface joints, defined in SubDyn’s main input file, +are rigidly connected to this reference point. To utilize the same +geometry definition within SubDyn’s main input file, while still +allowing for different substructure orientations about the vertical, the +user can set **SubRotateZ** to a prescribed angle in degrees with +respect to the global *Z*-axis. The entire substructure will be rotated +by that angle. (This feature is only available in stand-alone mode.) + +Setting **InputsMod** = 0 sets all TP reference-point input motions to +zero for all time steps. Setting **InputsMod** = 1 allows the user to +provide steady (fixed) inputs for the TP motion in the STEADY INPUTS +section of the file—\ **uTPInSteady**, **uDotTPInSteady**, and +**uDotDotTPInSteady** following the same convention as Table 1 +(without time). Setting **InputsMod** = 2 allows the user to input a +time-series file whose name is specified via the **InputsFile** +parameter. The time-series input file is a text-formatted file. This +file has no header lines, **NSteps** rows, and each *i*\ :sup:`th` row +has the first column showing time as *t* = ( *i* – 1 )\*\ **TimeStep** +(the data will not be interpolated to other times). The remainder of +each row is made of white-space-separated columns of floating point +values representing the necessary motion inputs as shown in Table 1. All +motions are specified in the global, inertial-frame coordinate system. +SubDyn does not check for physical consistency between the displacement, +velocity, and acceleration motions specified for the TP reference point +in the driver file. + +Table 1. TP Reference Point Inputs Time-Series Data File Contents + ++-----------------+-------------------------------------------------------------------------------------------------------+------------------------------------------+ +| Column Number | Input | Units | ++=================+=======================================================================================================+==========================================+ +| 1 | Time step value | `s` | ++-----------------+-------------------------------------------------------------------------------------------------------+------------------------------------------+ +| 2-4 | TP reference point translational displacements along *X*, *Y*, and *Z* | `m` | ++-----------------+-------------------------------------------------------------------------------------------------------+------------------------------------------+ +| 5-7 | TP reference point rotational displacements about *X*, *Y*, and *Z* (small angle assumptions apply) | `rad/s` | ++-----------------+-------------------------------------------------------------------------------------------------------+------------------------------------------+ +| 8-10 | TP reference point translational velocities along *X*, *Y*, and *Z* | `m/s` | ++-----------------+-------------------------------------------------------------------------------------------------------+------------------------------------------+ +| 11-13 | TP reference point rotational velocities about *X*, *Y*, and *Z* | `rad/s` | ++-----------------+-------------------------------------------------------------------------------------------------------+------------------------------------------+ +| 14-16 | TP reference point translational accelerations along *X*, *Y*, and *Z* | `m/s^2` | ++-----------------+-------------------------------------------------------------------------------------------------------+------------------------------------------+ +| 17-19 | TP reference point rotational accelerations about *X*, *Y*, and *Z* | `rad/s^2` | ++-----------------+-------------------------------------------------------------------------------------------------------+------------------------------------------+ + +.. _sd_main-input-file: + +SubDyn Primary Input File +------------------------- +The SubDyn input file defines the substructure geometry, integration and +simulation options, finite-element parameters, and output channels. The +geometry of members is defined by joint coordinates of the undisplaced +substructure in the global reference system (inertial-frame coordinate +system), with the origin at the intersection of the undeflected tower +centerline with MSL or ground level for land-based structures. A member +connects two joints; multiple members can use a common joint. The +hydrodynamic and gravity loads are applied at the nodes, which are the +resultant of member refinement into multiple (**NDiv** input) elements +(nodes are located at the ends of each element), as calculated by the +module. Member properties include outer diameter, thickness, material +density, and Young’s and shear moduli. Member properties are specified +at the joints; if properties change from one joint to the other, they +will be linearly interpolated for the inner nodes. Unlike the geometric +properties, the material properties are not allowed to change within a +single member. + +Future releases will allow for members of different cross-sections, +i.e., noncircular members. For this reason, the input file has +(currently unused) sections dedicated to the identification of direction +cosines that in the future will allow the module to identify the correct +orientation of noncircular members. The current release only accepts +tubular (circular) members. + +The file is organized into several functional sections. Each section +corresponds to an aspect of the SubDyn model and substructure. + +If this manual refers to an ID in a table entry, it is an integer +identifier for the table entry and must be unique for a given table +entry. + +A sample SubDyn primary input file is given in :numref:`sd_appendix_A`. + +The input file begins with two lines of header information, which is for +the user but is not used by the software. + + +Simulation Control Parameters +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Users can set the **Echo** flag to TRUE to have SubDyn echo the +contents of the SubDyn input file (useful for debugging errors in the +input file). The echo file has the naming convention of +**OutRootName.SD.ech**. **OutRootName** is either specified in the +SUBDYN section of the driver input file when running SubDyn standalone, +or by FAST, when running a coupled simulation, from FAST’s main input +file. + +**SDdeltaT** specifies the fixed time step of the integration in +seconds. The keyword ‘DEFAULT’ may be used to indicate that the module +should employ the time step prescribed by the driver code +(FAST/standalone driver program). + +**IntMethod** specifies the integration algorithm to use. There are +four options: 1) Runge-Kutta 4\ :sup:`th`-order explicit (RK4); 2) +Adams-Bashforth 4\ :sup:`th`-order explicit predictor (AB4); 3) +Adams-Bashforth-Moulton 4\ :sup:`th`-order explicit predictor-corrector +(ABM4); 4) Adams-Moulton implicit 2\ :sup:`nd`-order (AM2). See Section +on how to properly select this and the previous parameter values. + +**SttcSolve** is a flag that specifies whether the static improvement method +(SIM, see :numref:`SD_SIM`) +shall be employed. Through this method, all (higher frequency) modes +that are not considered by the C-B reduction are treated +quasi-statically. This treatment helps +minimize the number of retained modes needed to capture effects such as +static gravity and buoyancy loads, and high-frequency loads transferred +from the turbine. Recommended to set to True. + + +**GuyanLoadCorrection** is a flag to specify whether the extra moment due to +the lever arm from the Guyan deflection of the structure is to be added to the loads +passed to SubDyn, and, whether the FEM representation should be expressed in the rotating +frame in the floating case (the rotation is induced by the rigid body Guyan modes). +See section :numref:`SD_Loads` for details. Recommended to set to True. + + +FEA and Craig-Bampton Parameters +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**FEMMod** specifies one of the following options for finite-element +formulation: 1) Euler-Bernoulli; 3) Timoshenko. Tapered formulations (2 +and 4) have yet to be implemented and will be available in a future +release. + +**NDiv** specifies the number of elements per member. Analysis nodes +are located at the ends of elements and the number of analysis nodes per +member equals **NDiv** + 1. **NDiv** is applied uniformly to all +members regardless of the member’s length, hence it could result in +small elements in some members and long elements in other members. +Increasing the number of elements per member may increase accuracy, with +the trade-off of increased memory usage and computation time. We +recommend using **NDiv** > 1 when modeling tapered members. + +**CBMod** is a flag that specifies whether or not the C-B reduction +should be carried out by the module. If FALSE, then the full +finite-element model is retained and **Nmodes** is ignored. + +**Nmodes** sets the number of internal C-B modal DOFs to retain in the +C-B reduction. **Nmodes** = 0 corresponds to a Guyan (static) +reduction. **Nmodes** is ignored if **CBMod** is set to FALSE, +meaning the full finite-element model is retained by keeping all modes +(i.e. a modal analysis is still done, and all the modes are used as DOFs) . + + +**JDampings** specifies value(s) of damping coefficients as a +percentage of critical damping for the retained C-B modes. Distinct +damping coefficients for each retained mode should be listed on the same +line, separated by white space. If the number of **JDampings** is less +than the number of retained modes, the last value will be replicated for +all the remaining modes. (see :numref:`SD_DampingSpecifications`) + +**GuyanDampMod** Guyan damping [0=none, 1=Rayleigh Damping, 2= user specified 6x6 matrix] (see :numref:`SD_DampingSpecifications`) + + +**RayleighDamp** Mass and stiffness proportional damping coefficients (:math:`(\alpha,\beta)` Rayleigh damping) [only if GuyanDampMod=1] +Guyan damping matrix (6x6) [only if GuyanDamgMod=2] (see :numref:`SD_DampingSpecifications`) + + +**Guyan damping matrix**: +The 6 lines following this input line consits of the 6x6 coefficients of the damping matrix to be applied at the interface. (see :numref:`SD_DampingSpecifications`) + + +For more information on these parameters and guidelines on how to set +them, see Sections :numref:`sd_modeling-considerations` and :numref:`subdyn-theory`. + +Structure Joints +~~~~~~~~~~~~~~~~ + +The finite-element model is based on a substructure composed of joints +interconnected by members. **NJoints** is the user-specified number of +joints, and determines the number of rows in the subsequent table. +Because a member connects two joints, **NJoints** must be greater than +or equal to two. Each joint listed in the table is identified by a +unique integer, **JointID**; each integer between one and +**NJoints** must be present in the table, but they need not be +sequential. The (*X*,\ *Y*,\ *Z*) coordinate of each joint is specified +in the substructure (SS) coordinate system, which coincides with the +global inertial-frame coordinate system via **JointXss**, +**JointYss**, and **JointZss**, respectively. This version of SubDyn +does not consider overlap when multiple members meet at a common joint, +therefore, it tends to overestimate the total substructure mass. Member +overlap and node offset calculations will be considered in a future +release of SubDyn. +The fifth column specifies the **JointType** (see :numref:`SD_FEM`): + +- Cantilever joints (*JointType=1*) + +- Universal joint (*JointType=2*) + +- Pin joint (*JointType=3*) + +- Ball joint (*JointType=4*) + +The three following columns specify the vector coordinates of the direction around which rotation is free for a pin joints. +The last column, **JointStiff** specify a value of additional stiffness to be added to the "free" rotational DOFs of Ball, Pin and Universal joints. + + +Note for HydroDyn coupling: modeling a fixed-bottom substructure +embedded into the seabed (e.g., through piles or suction buckets) +requires that the lowest member joint(s) in HydroDyn lie(s) below the +water depth. Placing a joint at or above the water depth will result in +static and dynamic pressure loads being applied at the joint. When +SubDyn is coupled to FAST, the joints and members need not match between +HydroDyn and SubDyn—FAST’s mesh-mapping utility handles transfer of +motion and loads across meshes in a physically relevant manner (Sprague +et al. 2014), but consistency between the joints and members in HydroDyn +and SubDyn is advised. + + +An example of joint table is given below + +.. code:: + + 3 NJoints - Number of joints (-) + JointID JointXss JointYss JointZss JointType JointDirX JointDirY JointDirZ JointStiff + (-) (m) (m) (m) (-) (-) (-) (-) (Nm/rad) + 101 0.0 0.0 50.0 1 0.0 0.0 0.0 0.0 + 111 0.0 0.0 10.0 2 0.0 1.0 0.0 100.0 + 102 0.0 0.0 -45.0 1 0.0 0.0 0.0 0.0 + + +Base Reaction Joints +~~~~~~~~~~~~~~~~~~~~~ + +SubDyn requires the user to specify the boundary joints. **NReact** +should be set equal to the number of joints (defined earlier) at the +bottom of the structure (i.e., seabed) that are fully constrained; +**NReact** also determines the number of rows in the subsequent table. +In SubDyn, **NReact** must be greater than or equal to one. Each joint +listed in the table is identified by a unique integer, **RJointID**, +which must correspond to the **JointID** value found in the STRUCTURE +JOINTS table. The flags **RctTDXss**, **RctTDYss**, **RctTDZss**, +**RctRDXss**, **RctRDYss**, **RctRDZss** indicate the fixity value +for the three translations (TD) and three rotations (RD) in the SS +coordinate system (global inertial-frame coordinate system). One denotes +fixed and zero denotes free (instead of TRUE/FALSE). **SSIfile** +points to the relative path and filename for an SSI information file. +This version of SubDyn can, in fact, handle partially restrained joints +by setting one or more DOF flags to 0 and providing the appropriate +stiffness and mass matrix elements for that DOF via the **SSIfile**. +If a DOF flag is set to 1, then the node DOF is considered restrained +and the associated matrix elements potentially provided in the +**SSIfile** will be ignored. + + +An example of base reaction and interface table is given below + +.. code:: + + ------------------- BASE REACTION JOINTS + 1 NReact - Number of Joints with reaction forces + RJointID RctTDXss RctTDYss RctTDZss RctRDXss RctRDYss RctRDZss SSIfile + (-) (flag) (flag) (flag) (flag) (flag) (flag) (string) + 61 1 1 1 1 1 1 "SSI.txt" + ------------------- INTERFACE JOINTS + 1 NInterf - Number of interface joints locked to the Transition Piece (TP) + IJointID ItfTDXss ItfTDYss ItfTDZss ItfRDXss ItfRDYss ItfRDZss + (-) (flag) (flag) (flag) (flag) (flag) (flag) + 24 1 1 1 1 1 1 + + +Interface Joints +~~~~~~~~~~~~~~~~ + +SubDyn requires the user to specify the interface joints. **NInterf** +should be set equal to the number of joints at the top of the structure +(i.e., TP); **NInterf** also determines the number of rows in the +subsequent table. In SubDyn, **NInterf** must be greater than or equal +to one. Note that these joints will be assumed to be rigidly connected +to the platform reference point of ElastoDyn (see FAST documentation) +when coupled to FAST, or to the TP reference point if SubDyn is run in +stand-alone mode. Each joint listed in the table is identified by a +unique integer, **IJointID**, which must correspond to the *JointID* +value found in the STRUCTURE JOINTS table. The flags **ItfTDXss**, +**ItfTDYss**, **ItfTDZss**, **ItfRDXss**, **ItfRDYss**, +**ItfRDZss** indicate the fixity value for the three translations (TD) +and three rotations (RD) in the SS coordinate system (global +inertial-frame coordinate system). One denotes fixed and zero denotes +free (instead of TRUE/FALSE). This version of SubDyn cannot handle +partially restrained joints, so all flags must be set to one; different +degrees of fixity will be considered in a future release. + +Members +~~~~~~~ + +**NMembers** is the user-specified number of members and determines +the number of rows in the subsequent table. Each member listed in the +table is identified by a unique integer, **MemberID**. Each integer +between one and **NMembers** must be present in the table, but they +need not be sequential. For each member distinguished by **MemberID**, +**MJointID1** specifies the starting joint and **MJointID2** +specifies the ending joint, corresponding to an identifier +(**JointID**) from the STRUCTURE JOINTS table. Likewise, +**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. +The sixth column specify the member type **MType**. +A member is one of the three following types (see :numref:`SD_FEM`): + +- Beams (*MType=1*), Euler-Bernoulli (*FEMMod=1*) or Timoshenko (*FEMMod=3*) + +- Pretension cables (*MType=2*) + +- Rigid link (*MType=3*) + +**COSMID** refers to the IDs of the members’ cosine matrices for +noncircular members; the current release ignores this column. + + +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 + + + + +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. + +For the circular cross-section members, properties 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 +**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, 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. + + + + + +Cable Properties +~~~~~~~~~~~~~~~~ + + +Members that are specified as pretension cables (**MType=2**), +have their properties defined in the cable properties table. +The table lists for each cable property: the property ID (**PropSetID**), the cable tension stiffness (**EA**), +the material density (**MatDens**), the pretension force (**T0**), and the control channel (**CtrlChannel**). +The control channel is only used if ServoDyn provides dedicated control signal, in which case +the cable tension (given in terms of a length change :math:`\Delta l`) +is dynamically changed (see :numref:`SD_ControlCable`). +The FEM representation of pretension cable is given in :numref:`SD_PretensionCable`. + +An example of cable properties table is given below: + +.. code:: + + -------------------------- CABLE PROPERTIES ------------------------------------- + 2 NCablePropSets - Number of cable cable properties + PropSetID EA MatDens T0 CtrlChannel + (-) (N) (kg/m) (N) (-) + 11 210E7 7850.0 2E7 1 + 10 210E7 7850.0 1E7 0 + + +Rigid link Properties +~~~~~~~~~~~~~~~~~~~~~ + +Members that are specified as rigid links (**MType=3**), +have their properties defined in the rigid link properties table. +The table lists the material density (**MatDens**) for each rigid link property. +The FEM representation of rigid links is given in :numref:`SD_RigidLinks`. + +An example of rigid link properties table is given below + +.. code:: + + ----------------------- RIGID LINK PROPERTIES ------------------------------------ + 1 NRigidPropSets - Number of rigid link properties + PropSetID MatDens + (-) (kg/m) + 12 7850.0 + 3 7000.0 + + + + + + + + + + + + + + + + + +Member Cosine Matrices COSM (i,j) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This table is not currently used by SubDyn, but in future releases it +will need to be populated if members with cross-sections other than +circular will be employed. + +**NCOSMs** rows, one for each unique member orientation set, will need +to be provided. Each row of the table will list the nine entries of the +direction cosine matrices (COSM11, COSM12,…COSM33) for matrix elements +(1,1), (1,2),…(3,3) that establish the orientation of the local member +axes (*x*,\ *y* principal axes in the cross-sectional plane, *z* along +the member longitudinal axis) with respect to the SS coordinate system +(local-to-global transformation matrices). + +Joint Additional Concentrated Masses +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +SubDyn can accept **NCmass** lumped masses/inertias defined at the +joints. The subsequent table will have **NCmass** rows, in which for +each joint distinguished by **CMJointID** (corresponding to an +identifier, **JointID**, from the STRUCTURE JOINTS table), **JMass** +specifies the lumped mass value, and **JMXX**, **JMYY**, **JMZZ** +specify the mass second moments of inertia with respect to the SS +coordinate system (not the element system). +Latest version of SubDyn accept 6 additional columns +(**JMXY**, **JMXZ**, **JMYZ**, **MCGX**, **MCGY**, **MCGZ**) +to specify off-diagonal terms. + +The additional mass matrix added to the node is computed in the SS system as follows: + +.. math:: + + M_\text{add}= + \begin{bmatrix} + m & 0 & 0 & 0 & z m & -y m \\ + 0 & m & 0 & -z m & 0 & x m \\ + 0 & 0 & m & y m & -x m & 0 \\ + 0 & -z m & y m & J_{xx} + m (y^2+z^2) & J_{xy} - m x y & J_{xz} - m x z \\ + z m & 0 & -x m & J_{xy} - m x y & J_{yy} + m (x^2+z^2) & J_{yz} - m y z \\ + -y m & x m & 0 & J_{xz} - m x z & J_{yz} - m y z & J_{zz} + m (x^2+y^2)\\ + \end{bmatrix} + +with :math:`m` the parameter **JMass**, and :math:`x,y,z`, the CG offsets. + + +An example of concentrated mass table is given below: + +.. code:: + + 2 NCmass - Number of joints with concentrated masses; (SS coord system) + CMJointID JMass JMXX JMYY JMZZ JMXY JMXZ JMYZ MCGX MCGY MCGZ + (-) (kg) (kgm^2) (kgm^2) (kgm^2) (kgm^2) (kgm^2) (kgm^2) (m) (m) (m) + 1 4090 0 0 0 0 0 0 0 0 0 + 3 4.2e6 0 0 3.3e9 0 0 0 0 0 0 + + +Output: Summary and Outfile +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In this section of the input file, the user sets flags and switches for +the desired output behavior. + +Specifying **SDSum** = TRUE causes SubDyn to generate a summary file +with name **OutRootName**.SD.sum*. **OutRootName** is either +specified in the SUBDYN section of the driver input file when running +SubDyn in stand-alone mode, or in the FAST input file when running a +coupled simulation. See Section 4.2 for summary file details. + +In this release, **OutCOSM** is ignored. In future releases, +specifying **OutCOSM** = TRUE will cause SubDyn to include direction +cosine matrices (undeflected) in the summary file for only those members +requested in the list of output channels. + +Specifying **OutAll** = TRUE causes SubDyn to output forces and +moments at all of the joints (not internal nodes). That is, the static +(elastic) and dynamic (inertia) components of the three forces and three +moments at the end node of each member connected to a given joint are +output for all joints. These outputs are included within the +**OutRootName**.SD.out* output file in addition to those directly +specified through the output channels section below. + +If **OutSwtch** is set to one, outputs are sent to a file with the +name **OutRootName**.SD.out*. If **OutSwtch** is set to two, outputs +are sent to the calling program (FAST) for writing in its main output +file (not available in stand-alone mode). If **OutSwtch** is set to +three, both file outputs occur. In stand-alone mode, setting +**OutSwtch** to two results in no output file being produced. + +If **TabDelim** is set to TRUE and **OutSwtch** is set to one, the +output file **OutRootName**.SD.out* will be tab-delimited. + +With **OutDec** set to an integer value greater than one, the output +file data rate will be decimated, and only every **OutDec**-th value +will be written to the file. This applies only to SubDyn’s output file +(**OutRootName**.SD.out*)—not FAST’s. + +The **OutFmt** and **OutSFmt** parameters control the formatting of +SubDyn’s output file for the output data and the channel headers, +respectively. SubDyn currently does not check the validity of these +format strings. They need to be valid Fortran format strings. +**OutSFmt** is used for the column header and **OutFmt** is used for +the channel data. Therefore, in order for the headers and channel data +to align properly, the width specification should match. For example: + +| "ES11.4" OutFmt +| "A11" OutSFmt. + + +.. _SD_Member_Output: + +Member Output List +~~~~~~~~~~~~~~~~~~ + +SubDyn can output load and kinematic quantities at up to nine locations +for up to nine different members, for a total of 81 possible local +member output locations. **NMOutputs** specifies the number of members +that output is requested for. The user must create a table entry for +each requested member. Within a row of this table, **MemberID** is the +ID specified in the MEMBERS table, and **NOutCnt** specifies how many +nodes along the member will generate output. **NodeCnt** specifies +those node numbers (a separate entry on the same line for each node) for +output as an integer index from the start-joint (node 1) to the +end-joint (node **NDiv** + 1) of the member. The outputs specified in +the SDOutList section determines which quantities are actually output at +these locations. + +Output Channels- SDOutList Section +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section specifies which quantities are output by SubDyn. Enter one +or more lines containing quoted strings that in turn contain one or more +output parameter names. Separate output parameter names by any +combination of commas, semicolons, spaces, and/or tabs. If a parameter +name is prefixed with a minus sign, “-”, underscore, “\_”, or the +characters “m” or “M”, SubDyn will multiply the value for that channel +by –1 before writing the data. The parameters are written in the order +they are listed in the input file. SubDyn allows the use of multiple +lines so that users can break their lists into meaningful groups and so +the lines can be shorter. Comments may also be entered after the closing +quote on any of the lines. Entering a line with the string “END” at the +beginning of the line or at the beginning of a quoted string found at +the beginning of the line will cause SubDyn to quit scanning for more +lines of channel names. Modal kinematics and member-node-, base-, and +interface-related kinematic and load quantities can be selected. +Member-node-related data follow the organization described in Section . +If SubDyn encounters an unknown/invalid channel name, it prints an error +message and halts execution. Please refer to :numref:`sd_appendix_C` for a complete +list of possible output parameters and their names. + +.. _sd_ssi_inputfile: + +SSI Input File +-------------- + +Individual SSI files (*SSIfiles*) can be provided for each restrained +node, therefore the maximum number of SSIfiles is **NReact**. In an +SSIfile, up to 21 elements for the SSI mass matrix and up to 21 SSI +stiffness matrix elements can be provided. The mass and stiffness +elements account for both pile and soil effects. No additional damping +can be provided at this point. + +The order of the elements is not important, because each element value +is accompanied by a string label that identifies the actual element. The +stiffness matrix accepted labels are: 'Kxx', 'Kxy', 'Kyy', 'Kxz', 'Kyz’, +'Kzz’, 'Kxtx', 'Kytx', 'Kztx', 'Ktxtx', 'Kxty', 'Kyty','Kzty’, 'Ktxty', +'Ktyty', ‘Kxtz', 'Kytz', 'Kztz', 'Ktxtz', 'Ktytz', 'Ktztz'. + +If any matrix element is not provided it will be set to infinity (i.e., +machine ‘huge’) by default. + +For the mass matrix the accepted labels are: +'Mxx','Mxy','Myy','Mxz','Myz', 'Mzz','Mxtx','Mytx','Mztx', 'Mtxtx', +'Mxty', 'Myty', 'Mzty', 'Mtxty', 'Mtyty', 'Mxtz', 'Mytz', 'Mztz', +'Mtxtz', 'Mtytz', 'Mtztz'. If any matrix element is not provided it will +be set to 0 by default. The labels contain ‘K’ or ‘M’ to specify +stiffness or mass matrix elements, and then the directions they apply +to, e.g., ‘Kxy’ refers to the force along x due to a unit displacement +along y; the ‘t’ refers to the rotation about one of the ‘x’,’y’, or ’z’ +axes in the global coordinate system. + +Units are in SI system (N/m; N/m/rad; Nm/rad, Kg, kgm, kgm2). + +Note that by selecting fixities of 1 in the various DOFs of the +restrained nodes, the columns and rows associated with those DOFs will +be removed, therefore the associated matrix elements will be ignored. + +A sample SubDyn SSI input file is given in :numref:`sd_appendix_C`. diff --git a/docs/source/user/subdyn/introduction.rst b/docs/source/user/subdyn/introduction.rst new file mode 100644 index 0000000000..c5b8e1bf23 --- /dev/null +++ b/docs/source/user/subdyn/introduction.rst @@ -0,0 +1,123 @@ +.. _sd_intro: + +Introduction +============ + +`SubDyn `__ is a time-domain +structural-dynamics module for multimember fixed-bottom substructures +created by the National Renewable Energy Laboratory (NREL) through U.S. +Department of Energy Wind and Water Power Program support. The module +has been coupled into the FAST aero-hydro-servo-elastic computer-aided +engineering (CAE) tool. Substructure types supported by SubDyn include +monopiles, tripods, jackets, and other non-floating lattice-type +substructures common for offshore wind installations in shallow and +transitional water depths. SubDyn can also be used to model lattice +support structures for land-based wind turbines. + +The new SubDyn module follows the requirements of the FAST +modularization framework, couples to +`OpenFAST `__, and +provides new capabilities (relative to prior released versions of the +software) for modeling the dynamic loading on multimember substructures. +(Refer to Appendix E and the *changelog.txt* file that is provided in +the archives for more details about changes among different versions.) +SubDyn can also be driven as a standalone code to compute the mode +shapes, natural frequencies, and time-domain responses of substructures +under prescribed motion at the interface to the tower, uncoupled from +FAST and in the absence of external loading other than gravity. + +SubDyn relies on two main engineering schematizations: (1) a linear +frame finite-element beam model (LFEB), and (2) a dynamics system +reduction via the Craig-Bampton(C-B) method, together with a +static-improvement method (SIM), greatly reducing the number of modes +needed to obtain an accurate solution. More details can be found in +Section 6, and in :cite:`song2013`, :cite:`damiani2013`, +:cite:`damiani2013omae`, :cite:`jonkmantcf`. + +In SubDyn, the substructure is considered to be either clamped or +supported by springs at the seabed, and rigidly connected to the +transition piece (TP) at the substructure top nodes (interface nodes). +The spring constants are provided by the user to simulate +soil-structure-interaction (SSI). Other restraint formulations may be +implemented in the future. Only the substructure structural dynamics are +intended to be modeled within SubDyn. When integrated with FAST, the +structural dynamics of the TP, tower, and rotor-nacelle assembly (RNA) +are modeled within FAST’s ElastoDyn module and hydrodynamics are modeled +within FAST’s `HydroDyn `__ module. For +full lattice support structures or other structures with no transition +piece, however, the entire support structure up to the yaw bearing may +be modeled within SubDyn. Modeling the tower in SubDyn as opposed to +ElastoDyn, for example, allows for the possibility of including more +than the first two fore-aft and side-to-side bending modes, thus +accounting for more general flexibility of the tower and its segments. +However, for tubular towers, the structural model in ElastoDyn tends to +be more accurate because ElastoDyn considers geometric nonlinearities +not treated in SubDyn. + +Loads and responses are transferred between SubDyn, HydroDyn, and +ElastoDyn via the FAST driver program (glue code) to enable +hydro-elastic interaction at each coupling time step. At the interface +nodes, the TP six degree-of-freedom (DOF) displacements (three +translations and three rotations), velocities, and accelerations are +inputs to SubDyn from ElastoDyn; and the six reaction loads at the TP +(three forces and three moments) are outputs from SubDyn to ElastoDyn. +SubDyn also outputs the local substructure displacements, velocities, +and accelerations to HydroDyn in order to calculate the local +hydrodynamic loads that become inputs for SubDyn. In addition, SubDyn +can calculate member internal reaction loads, as requested by the user +(see Figure 1). + + +.. _sd_flow-chart: + +.. figure:: figs/flowchart.png + :width: 100% + + SubDyn, HydroDyn, and FAST 8 coupled interaction + + +The input file defines the substructure geometry, material properties, +restraints and SSI data files, finite-element resolution, number of +retained modes in the dynamics system reduction, modal damping +coefficients, and auxiliary parameters. The geometry is defined by joint +coordinates in the global reference system (inertial-frame coordinate +system shown in ), with the origin at the intersection of the +undeflected tower centerline with mean sea level (MSL) or ground level +for land-based structures. A member connects two joints; multiple +members may use a common joint. Nodes are the result of the member +refinement into multiple (***NDiv*** input parameter) elements (nodes +are located at the ends of each element, as shown in ), and they are +calculated by the module. + +In the current release, the geometry of a member is defined by its outer +diameter and wall thickness (assuming a tubular geometry), and the +material properties are defined by its Young’s modulus, shear modulus, +and mass density. Member properties are specified at the joints; if +properties change from one joint to the other, they will be linearly +interpolated for the inner elements. Thus, a tapered member will be +treated as a cylindrical member with step-wise variation of its +properties. In a future release, a tapered finite-element formulation +will be implemented, and a more accurate representation of a tapered +member will become available. + +The hydrodynamic loads (including buoyancy) are computed by HydroDyn and +transferred by the glue code at those nodes that are underwater +(submerged nodes). Additionally, the self-weight distributed load +components (from gravity) are calculated by SubDyn and applied at all +the nodes. Note that other load and inertial properties may be input via +the HydroDyn module input file, where marine growth and +flooding/ballasting of the members can be specified. + +This document is organized as follows. Section :ref:`running-subdyn` details how to obtain +the SubDyn and FAST software archives and run either the stand-alone +version of SubDyn or SubDyn coupled to FAST. Section :ref:`sd_input-files` describes the +SubDyn input files. Section 4 discusses the :ref:`sd_output-files` generated by +SubDyn; these include echo files, a summary file, and the results file. +Section 5 provides modeling guidance when using SubDyn. The SubDyn +theory is covered in Section :ref:`subdyn-theory`. Section :ref:`sd_future-work` outlines future work, and +Section 8 contains a list of references. Example input files are shown +in Appendices :numref:`sd_appendix_A` and B. A summary of available output channels are found +in Appendix :ref:`sd_appendix_D`. Instructions for compiling the stand-alone SubDyn program +are detailed in Appendix D. Appendix E tracks the major changes that +have been made to SubDyn for each public release. + diff --git a/docs/source/user/subdyn/modeling.rst b/docs/source/user/subdyn/modeling.rst new file mode 100644 index 0000000000..0afc9cad06 --- /dev/null +++ b/docs/source/user/subdyn/modeling.rst @@ -0,0 +1,326 @@ +.. _sd_modeling-considerations: + +Modeling Considerations +======================= + +SubDyn was designed as a flexible tool for modeling a wide range of +substructures for both land-based and offshore applications. This +section provides some general guidance to help construct models that are +compatible with SubDyn. + +Please refer to the theory in Section 6 for detailed information about +SubDyn’s coordinate systems, and the theoretical approach we have +followed in SubDyn. + +Model Discretization +-------------------- + +SubDyn allows for the specification of arbitrary multimember structure +geometries. The user defines the geometry of a structure in SubDyn using +joints and members. Specifically, the user specifies a list of joints +that represent the endpoints of beams, and the connectivity between one +or more members at each joint. Members and their cross-sectional +properties are then defined between two joints. Members can be further +subdivided into multiple (**NDiv**) elements to increase the model +resolution. Nodes, where the numerical calculations take place, are +located at the endpoints of each element. To keep the mesh as uniform as +possible when using **NDiv**, the initial member definition should +also have a roughly uniform mesh. For tapered members, we recommend +setting **NDiv** > 1. Improper discretization of the members may +decrease the accuracy of the model. + +When SubDyn is coupled to FAST, the joints and members need not match +between HydroDyn and SubDyn—FAST’s mesh-mapping utility handles the +transfer of motion and loads across meshes in a physically relevant +manner :cite:`sprague2014`, but consistency between the joints and +members in HydroDyn and SubDyn is advised. + +For offshore applications, because of the exponential decay of +hydrodynamic loads with depth, HydroDyn requires higher resolution near +the water free surface to properly capture loads as waves oscillate +about the still water level (SWL). We recommend that the HydroDyn +discretization not exceed element lengths of 0.5 m in the region of the +free surface (5 to 10 m above and below SWL), 1.0 m between 25- and 50-m +depth, and 2.0 m in deeper waters. + +When SubDyn is hydro-elastically coupled to HydroDyn through FAST for +the analysis of fixed-bottom offshore systems, we recommend that the +length ratio between elements of SubDyn and HydroDyn not exceed 10 to 1. +As such, we recommend that the SubDyn discretization not exceed element +lengths of 5 m in the region of the free surface, 10 m down to 25- to +50-m depth, and 20 m in deeper waters. These are not absolute rules, but +rather a good starting point that will likely require refinement for a +given substructure. Additional considerations for SubDyn discretization +include aspects that will impact structural accuracy, such as member +weight, substructure modes and/or natural frequencies, load transfer, +tapered members, and so on. + +Members in SubDyn are assumed to be straight circular (and possibly +tapered) cylinders. The use of more generic cross-sectional shapes will +be considered in a future release. + +Foundations +----------- + +There are two methods that can be used to model foundation flexibility +or soil-structure interaction in SubDyn. The first method makes us of +the SSI stiffness and mass matrices at the partially restrained bottom +joints as described in Sections 3.3.4, 3.4, and 6. The second method +mimics the flexibility of the foundation through the apparent (or +effective) fixity (AF) length approach, which idealizes a pile as a +cantilever beam that has properties that are different above and below +the mudline. The beam above the mudline should have the real properties +(i.e., diameter, thickness, and material) of the pile. The beam below +the mudline is specified with effective properties and a fictive length +(i.e., the distance from the mudline to the cantilevered base) that are +tuned to ensure that the overall response of the pile above the mudline +is the same as the reality. The response can only be identical under a +particular set of conditions; however, it is common for the properties +of the fictive beam to be tuned so that the mudline displacement and +rotation would be realistic when loaded by a mudline shear force and +bending moment that are representative of the loading that exists when +the offshore wind turbine is operating under normal conditions. + +Note that in HydroDyn, all members that are embedded into the seabed +(e.g., through piles or suction buckets) must have a joint that is +located below the water depth. In SubDyn, the bottom joint(s) will be +considered clamped or partially restrained and therefore need not be +located below the seabed when not applying the AF approach. For example, +if the water depth is set to 20 m, and the user is modeling a +fixed-bottom monopile with a rigid foundation, then the bottom-most +joint in SubDyn can be set at *Z* = -20 m; HydroDyn, however, needs to +have a Z-coordinate such that *Z* < -20 m. This configuration avoids +HydroDyn applying static and dynamic pressure loads from the water on +the bottom of the structure. When the AF approach is applied, the +bottom-most joint in SubDyn should be set at *Z* < -20 m. + + +Member Overlap +-------------- + +As mentioned earlier, the current version of SubDyn is incapable of +treating the overlap of members at the joints, resulting in an +overestimate of the mass and potentially of the structure stiffness. One +strategy to overcome this shortcoming employs virtual members to +simulate the portion of each member within the overlap at a joint. The +virtual members should be characterized by low self-mass and high +stiffness. This can be achieved by introducing virtual joints at the +approximate intersection of the finite-sized members, and then +specifying additional members from these new joints to the original +(centerline) joints. The new virtual members then use reduced material +density and increased Young’s and shear moduli. Care is advised in the +choice of these parameters as they may render the system matrix +singular. Inspection of the eigenvalue results in the summary file +should confirm whether acceptable approximations have been achieved. + +.. _TowerTurbineCpling: + +Substructure Tower/Turbine Coupling +----------------------------------- + +When SubDyn is coupled to FAST, the 6 DOFs of the platform in ElastoDyn +must be enabled to couple loads and displacements between the turbine +and the substructure. The platform reference-point coordinates in +ElastoDyn should also be set equal to the TP reference-point’s +coordinates (commonly indicating either the tower-base flange location, +or TP centroid, or TP center of mass) that the user may have set in the +stand-alone mode for checking the SubDyn model. A rigid connection +between the SubDyn interface joints and TP reference point (:math:`{\equiv}` platform +reference point) is assumed. + +For full lattice support structures or other structures with no +transition piece, the entire support structure up to the yaw bearing may +be modeled within SubDyn. Modeling the tower in SubDyn as opposed to +ElastoDyn, for example, allows the ability to include more than the +first two fore-aft and side-to-side bending modes, thus accounting for +more general flexibility of the tower and its segments; however, for +tubular towers, the structural model in ElastoDyn tends to be more +accurate because ElastoDyn considers geometric nonlinearities not +treated in SubDyn. When modeling full-lattice towers using SubDyn, the +platform reference point in ElastoDyn can be located at the yaw bearing; +in this case, the tower-bending DOFs in ElastoDyn should be disabled. + +If FAST is run with SubDyn but not HydroDyn, the water depth will be +automatically set to 0 m. This will influence the calculation of the +reaction loads. Reactions are always provided at the assumed mudline, +therefore, they would not be correctly located for an offshore turbine +as a result. Thus, it is recommended that HydroDyn always be enabled +when modeling bottom-fixed offshore wind turbines. + +ElastoDyn also needs tower mode shapes specified (coefficients of +best-fit sixth-order polynomials), derived using appropriate tower-base +boundary conditions. They can be derived with an appropriate software +(finite-element analysis, energy methods, or analytically) and by making +use of the SubDyn-derived equivalent substructure stiffness and mass +matrices (the **KBBt** and **MBBt** matrices found in the SubDyn summary +file) to prescribe the boundary conditions at the base of the tower. + +For instance, using NREL’s BModes software, the SubDyn-obtained matrices +can be used in place of the hydrodynamic stiffness (**hydro\_K**) and mass +matrices (**hydro\_M**) (**mooring\_K** can be set to zero). By setting +the **hub\_conn** boundary condition to two (free-free), BModes will +calculate the mode shapes of the tower when tower cross-sectional +properties are supplied. To obtain eigenmodes that are compatible with +the FAST modal treatment of the tower (i.e., no axial or torsional modes +and no distributed rotational-inertia contribution to the eigenmodes), +the tower-distributed properties should be modified accordingly in +BModes (e.g., by reducing mass moments of inertia towards zero and by +increasing torsional and axial stiffness while assuring convergence of +the results; see also +`https://wind.nrel.gov/forum/wind/viewtopic.php?f=4&t=742 `__). + +The rotational inertia of the undeflected tower about its centerline is +not currently accounted for in ElastoDyn. Thus, when the nacelle-yaw DOF +is enabled in ElastoDyn there will not be any rotational inertia of the +platform-yaw DOF (which rotates the tower about its centerline) when +both the platform-yaw inertia in ElastoDyn is zero and the tower is +undeflected. To avoid a potential division-by-zero error in ElastoDyn +when coupled to SubDyn, we recommend setting the platform-yaw inertia +(**PtfmYIner**) in ElastoDyn equal to the total rotational inertia of +the undeflected tower about its centerline. Note that the platform mass +and inertia in ElastoDyn can be used to model heavy and rigid transition +pieces that one would not want to model as a flexible body in either the +ElastoDyn tower or SubDyn substructure models. + +***Damping of the Guyan modes:*** + +There are three ways to specify the damping associated with the motion +of the interface node. + +1. SubDyn Guyan damping matrix using Rayleigh damping +2. SubDyn Guyan damping matrix using user defined 6x6 matrix +3. HydroDyn additional linear damping matrix (**AddBLin**) + +The specificaiton of the Guyan damping matrix in SubDyn is discussed in :numref:`SD_DampingSpecifications`. + + +**Old:** + +The C-B method assumes no damping for the interface modes. This is +equivalent to having six undamped rigid-body DOFs at the TP reference +point in the absence of aerodynamic or hydrodynamic damping. Experience +has shown that negligible platform-heave damping can cause numerical +problems when SubDyn is coupled to FAST. One way to overcome this +problem is to augment overall system damping with an additional linear +damping for the platform-heave DOF. This augmentation can be achieved +quite easily by calculating the damping from Eq. :eq:`damping` and specifying this +as the (3,3) element of HydroDyn’s additional linear damping matrix, +**AddBLin**. Experience has shown that a damping ratio of 1% of +critical (:math:`{\zeta=0.01}`) is sufficient. In Eq. :eq:`damping`, :math:`{K_{33}^{(SD)}}` is the equivalent heave stiffness +of the substructure (the (3,3) element of the **KBBt** (i.e., :math:`{\tilde{K}_{BB}}`) matrix +found in the SubDyn summary file, see also Section 6), :math:`{M_{33}^{(SD)}}` is the equivalent +heave mass of the substructure (the (3,3) element of the **MBBt** +(i.e., :math:`{\tilde{M}_{BB}}`) matrix found in the SubDyn summary file, see also Section 6), +and :math:`{M^{(ED)}}` is the total mass of the rotor, nacelle, tower, and TP (found in the +ElastoDyn summary file). + +.. math:: :label: damping + + C_{33}^{(HD)} = 2 \zeta \sqrt{ K_{33}^{(SD)} \left( M_{33}^{(SD)}+M^{(ED)} \right)} + + +To minimize extraneous excitation of the platform-heave DOF, it is +useful to set the initial platform-heave displacement to its natural +static-equilibrium position, which can be approximated by Eq. :eq:`ptfmheave`, where +is the magnitude of gravity. *PtfmHeave* from Eq. :eq:`ptfmheave` should be +specified in the initial conditions section of the ElastoDyn input file. + +.. math:: :label: ptfmheave + + PtfmHeave = -\dfrac{ \left( M_{33}^{(SD)}+M^{(ED)} \right) g}{K_{33}^{(SD)}} + + + + + +Self-Weight Calculations +------------------------ + +SubDyn will calculate the self-weight of the members and apply +appropriate forces and moments at the element nodes. Lumped masses will +also be considered as concentrated gravity loads at prescribed joints. +The array of self-weight forces can be seen in the summary file if the +code is compiled with DEBUG compiler directives. In general, SubDyn +assumes that structural motions of the substructure are small, such that +(1) small-angle assumptions apply to structural rotations and (2) the +so-called P- :math:`{\Delta}` effect is negligible, and therefore undeflected node +locations are used for self-weight calculations. + +Note On Other Load Calculations +------------------------------- + +When SubDyn is coupled to HydroDyn through FAST, the hydrodynamic loads, +which include buoyancy, marine-growth weight, and wave and current +loads, will be applied to the effective, deflected location of the nodes +by the mesh-mapping routines in the glue code. Those loads, however, are +based on wave kinematics at the undeflected position (see Jonkman et al. +2014 for more information). + +.. _CBguide: + +Craig-Bampton Guidelines +------------------------ + +When SubDyn is coupled with FAST, it is important to choose a sufficient +number of C-B modes, ensuring that the vibrational modes of the coupled +system are properly captured by the coupled model. We recommend that all +modes up to at least 2-3 Hz be captured; wind, wave, and turbine +excitations are important for frequencies up to 2-3 Hz. Eigenanalysis of +the linearized, coupled system will make checking this condition +possible and aid in the selection of the number of retained modes; +however, the linearization process has yet to be implemented in FAST v8. +Until full-system linearization is made available, experience has shown +that it is sufficient to enable all C-B modes up to 10 Hz (the natural +frequencies of the C-B modes are written to the SubDyn summary file). If +SIM (see Section :numref:`sim`) is not enabled, in addition to capturing physical +modes up to a given frequency, the highest C-B mode must include the +substructure axial modes so that gravity loading from self-weight is +properly accounted for within SubDyn. This inclusion likely requires +enabling a high number of C-B modes, reducing the benefit of the C-B +reduction. Thus, we recommend employing the C-B reduction with SIM +enabled. Because of the fixed-fixed treatment of the substructure +boundary conditions in the C-B reduction, the C-B modes will always have +higher natural frequencies than the physical modes. + +Integration Time Step Guidelines +-------------------------------- + +Another consideration when creating SubDyn input files is the time step +size. SubDyn offers three explicit time-integrators --- the fourth-order +Runge-Kutta (RK4), fourth-order Adams-Bashforth (AB4), fourth-order +Adams-Bashforth-Moulton (ABM4) methods --- and the implicit second-order +Adams-Moulton (AM2) method. Users have the option of using the global +time step from the glue code or an alternative SubDyn-unique time step +that is an integer multiple smaller than the glue-code time step. +It is essential that a small enough time step is used to ensure solution +accuracy (by providing a sufficient sampling rate to characterize all +key frequencies of the system), numerical stability of the selected +explicit time-integrator, and that the coupling with FAST is numerically +stable. + +For the RK4 and ABM4 methods, we recommend that the SubDyn time step +follow the relationship shown in Eq. :eq:`dtmax`, where :math:`{f_{max}}` is the higher of (1) the +highest natural frequency of the retained C-B modes and (2) the highest +natural frequency of the physical modes when coupled to FAST. Although +the former can be obtained from the SubDyn summary file, the latter is +hard to estimate before the full-system linearization of the coupled +FAST model is realized. Until then, experience has shown that the +highest physical mode when SubDyn is coupled to FAST is often the +platform-heave mode of ElastoDyn, with a frequency given by Eq. :eq:`freq`, +where the variables are defined in Section 5.3. + +.. math:: :label: dtmax + + dt_{max} = \dfrac{1}{10 f_{max}} + +.. math:: :label: freq + + f= \dfrac{1}{2\pi} \sqrt{\dfrac{K_{33}^{(SD)}}{ M_{33}^{(SD)}+M^{(ED)}}} + +For the AB4 method, the recommended time step is half the value given by +Eq. :eq:`dtmax`. + +For AM2, being implicit, the required time step is not driven by natural +frequencies within SubDyn, but should still be chosen to ensure solution +accuracy and that the coupling to FAST is numerically stable. + diff --git a/docs/source/user/subdyn/output_files.rst b/docs/source/user/subdyn/output_files.rst new file mode 100644 index 0000000000..f016ecfa12 --- /dev/null +++ b/docs/source/user/subdyn/output_files.rst @@ -0,0 +1,126 @@ +.. _sd_output-files: + +Output Files +============ + +SubDyn produces three types of output files: an echo file, a summary +file, and a time-series results file. The following sections detail the +purpose and contents of these files. + +Echo File +--------- + +If the user sets the **Echo** flag to TRUE in the SubDyn driver file +or the primary SubDyn input file, the contents of those files will be +echoed to a file with the naming conventions, **OutRootName.dvr.ech** +for the driver input file and **OutRootName.SD.ech** for the primary +SubDyn input file. **OutRootName** is either specified in the SUBDYN +section of the driver input file, or in the FAST input file. The echo +files are helpful for debugging the input files. The contents of an echo +file will be truncated if SubDyn encounters an error while parsing an +input file. The error usually corresponds to the line after the last +successfully echoed line. + +.. _sd_sum-file: + +Summary File +------------ + +SubDyn generates a summary file with the naming convention, +**OutRootName.SD.sum** if the **SDSum** parameter is set to TRUE. +This file summarizes key information about the substructure model, +including: + +- Undisplaced node geometry: a list of all of the (**NNodes**) nodes + and the *X*,\ *Y*,\ *Z* coordinates in the global SS coordinate + system. Note that **NNodes** may be greater or equal to + **NJoints**, depending on **NDiv** (primary input file + parameters). + +- Element connectivity and properties at end nodes: a list of all + (**NElems**) elements, the start and end nodes (**Node\_I**, + **Node\_J**) and the ID of the property set (**Prop\_I**, + **Prop\_J**) at the start and end nodes. **NElems** may be + greater or equal to **NMembers**, depending on **NDiv** (primary + input file parameters). + +- Property sets. If tapered members are used, additional property sets + may be included beyond those specified in the main input file, based + on interpolated diameter and thickness values. Headers and their + meanings are identical to those described in Section . + +- Reaction DOFs and interface DOFs and their associated fixity; the + actual indices of the DOFs (**DOF\_ID**) associated with reaction + and interface nodes are listed together with the (1/0) flag to + distinguish the fixity level. + +- Concentrated mass schedule. This is an echo of the equivalent section + in the primary input file. Refer to Section . + +- Member schedule including connectivity to joints, nodes, and their + masses. A table lists all of the members by identifier + (**MemberID**), with their start and end nodes (**Joint1\_ID**, + **Joint2\_ID**), associated mass (**Mass**), and list of node + identifiers along the length of the members. + +- Direction cosine matrices for the members. Each row (columns 2-10) + corresponds to the direction cosine matrix entries (**DC(1,1)** + through **DC(3,3)**) for the member whose identifier is listed in + the first column. The direction cosine matrices specify the + transformation from the global reference to the local coordinate + system for each member. + +- Sorted eigenfrequencies [in Hertz (Hz)] for the full substructural + system (neglecting a possible coupling to ElastoDyn through FAST), + assuming the TP reference point is a free end. There are a total of + **NDOFs** eigenfrequencies and eigenvectors. + +- Sorted eigenfrequencies (in Hz) for the C-B reduced system, assuming + the TP reference point is a fixed end. There are a total of + **Nmodes** C-B reduced eigenfrequencies and eigenvectors. + +- Full substructural system eigenvectors. Each column represents an + eigenvector associated with the corresponding eigenfrequency + identified previously in the file. + +- C-B reduced system eigenvectors (**PhiM** matrix). Each column + represents an eigenvector associated with the corresponding + eigenfrequency identified previously in the file. + +- **PhiR** matrix or displacements of the internal nodes caused by + unit rigid body motions of the interface DOFs (see Section ). Each + column of the matrix represents the internal DOF displacements for a + given unit rigid-body motion along an interface DOF for each base and + interface joint. + +- Substructure equivalent stiffness and mass matrices referred to the + TP reference point (**KBBt** and **MBBt**), based on a Guyan + reduction. These are useful to calculate effects of substructure + flexibility while calculating tower eigenmodes for ElastoDyn. + +- Rigid-body-equivalent mass matrix relative to global origin + (**MRB**); a 6x6 mass matrix. + +- Substructure total (dry) mass. + +- Substructure center of mass coordinates in the global coordinate + system. + +The various sections of the summary file and variables are +self-explanatory and easily identifiable in the file. + +Results File +------------ + +The SubDyn time-series results are written to a text-based file with the +naming convention **OutRootName.SD.out** when **OutSwtch** is set to +either one or three. If SubDyn is coupled to FAST and **OutSwtch** is +set to two or three, then FAST will generate a master results file that +includes the SubDyn results. The results in **OutRootName.SD.out** are +in table format, where each column is a data channel (the first column +always being the simulation time), and each row corresponds to a +simulation time step. The data channels are specified in the SDOutList +section of the input file. The column format of the SubDyn-generated +file is specified using the **OutFmt** and **OutSFmt** parameters of +the input file. + diff --git a/docs/source/user/subdyn/references_SD.bib b/docs/source/user/subdyn/references_SD.bib new file mode 100644 index 0000000000..7e610dbea3 --- /dev/null +++ b/docs/source/user/subdyn/references_SD.bib @@ -0,0 +1,159 @@ +%% This BibTeX bibliography file was created using BibDesk. +%% http://bibdesk.sourceforge.net/ + + +%% Created for Clifton, Andrew at 2014-07-30 18:45:30 -0600 + + +%% Saved with string encoding Unicode (UTF-8) + +@book{chapra2010, + author = "Chapra, S.C. and Canale, R.P. ", + title = "Numerical Methods for Engineers", + year = "2010", + publisher = "McGraw-Hill Science/Engineering/Mat" +} + +@inproceedings{song2013, + author = "Song, H. and Damiani, R. and Robertson, A. and Jonkman, J.", + title = "(2013). New Structural-Dynamics Module for Offshore Multimember Substructures within the Wind Turbine Computer-Aided Engineering Tool {FAST}", + month = "June 30 -- July 5", + year = "2013", + booktitle = "Proceedings of the 23rd International Ocean, Offshore and Polar Engineering Conference - ISOPE 2013", + address = "Anchorage, Alaska", + note = "https://www.nrel.gov/docs/fy15osti/63165.pdf" +} + +% NOTE: clash with beamdyn reference since sphinx will use [Jon13] for both +@inproceedings{jjonkman2013, + author = "JJonkman", + title = "The New Modularization Framework for the {FAST} Wind Turbine {CAE} Tool.", + month = "January 7 -- 10", + year = "2013", + booktitle = "Proceedings of the 51st AIAA Aerospace Sciences Meeting and 31st ASME Wind Energy Symposium", + address = "Grapevine, Texas" +} + +@inproceedings{hurty1964, + author = "Hurty, W.C.", + title = "On the Dynamic Analysis of Structural Systems Using Component Modes", + month = "June 29--July 2", + year = "1964", + booktitle = "Proceedings of the 51st AIAA Annual Meeting", + address = "Washington, DC", + note = "AIAA Paper No. 64-487" +} + +@article{craig1968, + author = "Craig, R. and Bampton, M.", + title = "Coupling of Substructures for Dynamic Analyses", + year = "1968", + journal = "AIAA Journal", + volume = "6", + pages = "1313 -- 1319" +} + + +% NOTE: clashes with BeamDyn references +@inproceedings{sprague2014, + author = "MSprague and Jonkman, J.M. and Jonkman, B.J.", + title = "{FAST} Modular Wind Turbine {CAE} Tool: Nonmatching Spatial and Temporal Meshes", + month = "January", + year = "2014", + booktitle = "Proceedings of the 32nd ASME Wind Energy Symposium", + address = "National Harbor, Maryland" +} + + +@techreport{panzer2009, + Author = "Panzer, H. and Hubele, J. and Eid, R. and Lohmann, B.", + Volume = "TRAC-4", + Institution = "Technische Universitat Munchen", + Title = "Generating a Parametric Finite Element Model of a 3D Cantilever Timoshenko Beam Using Matlab", + Year = "2009", + Note = "Technical Reports on Automatic Control" +} + +@techreport{iso19902, + Author = "{ISO}", + Title = "{19902:2007} - Petroleum and natural gas industries -- Fixed steel offshore structures", + Institution = "{ISO}", + Address = "Geneva, Switzerland", + Revision = "1st edition", + Year = "2007" +} + +@TECHREPORT{api2014, + title={Planning, Designing and Constructing Fixed Offshore Platforms - Working Stress Design}, + author={{API}}, + institution={{A}merican {P}etroleum {I}nstitute}, + number={{API} Recommended Practice {2A-WSD}, 22nd Edition}, + year=2014 +} + +@article{steinboeck2013, + author = "Steinboeck, A. and Kugi, A. and Mang, H", + title = "Energy-consistent shear coefficients for beams with circular cross sections and radially in homogeneous materials", + year = "2013", + journal = "International Journal of Solids and Structures", + volume = "50", + number = "11--12", + pages = "1859--1868" +} + +@TECHREPORT{subdyn:manual, + title={SubDyn User's Guide and Theory Manual}, + author={R. Damiani and J. Jonkman and G. Hayman}, + institution={National Renewable Energy Laboratory}, + number={NREL/TP-5000-63062}, + year=2015 +} + +@article{damiani2013, + author={R. Damiani and H. Song}, + title={A Jacket Sizing Tool for Offshore Wind Turbines within the Systems Engineering Initiative}, + year=2013, + journal={Offshore Technology Conference}, + volume= 1, + number=1 +} +@article{damiani2013omae, + author={R. Damiani and H. Song and A. Robertson and J. Jonkman}, + title={Assessing the Importance of Nonlinear Structural Characteristics in the Development of a Jacket Model for the Wind Turbine CAE Tool FAST.}, + year=2013, + journal={32nd International Conference on Ocean, Offshore and Arctic Engineering}, + volume= 1, + number=1 +} + +@inproceedings{damiani2013omaeB, + author = "Damiani, R. and Song, H. and Robertson, A. and Jonkman, J.", + title = "Assessing the Importance of Nonlinear Structural Characteristics in the Development of a Jacket Model for the Wind Turbine {CAE} Tool {FAST}", + month = "Jne 9--14", + year = "2013", + booktitle = "Proceedings of the 32nd International Conference on Ocean, Offshore and Arctic Engineering (OMAE2013)", + address = "Nantes, France" +} + + +@techreport{felippa, + title={Introduction to finite element methods - Lecture notes (ASEN 5007)}, + author={Carlos A. Felippa}, + institution={{Department of Aerospace Engineering Sciences and Center for Aerospace Structures, University of Colorado, Boulder, CO, USA}}, + year={2004} +} + +@book{cook, + author = {Robert D. Cook }, + title = {Concepts and Applications of Finite Element Analysis}, + year = {2001}, + publisher= {John Wiley \& Sons} +} + +@techreport{jonkmantcf, + title={Implementation of Substructure Flexibility and Member-Level Load Capabilities for Floating Offshore Wind Turbines in OpenFAST}, + author={Jason Jonkman and Emmanuel Branlard and Matthew Hall and Greg Hayman and Andy Platt and Amy Robertson}, + institution={National Renewable Energy Laboratory}, + number={NREL/TP-5000-76822}, + year=2020 +} diff --git a/docs/source/user/subdyn/running_sd.rst b/docs/source/user/subdyn/running_sd.rst new file mode 100644 index 0000000000..eb07718b92 --- /dev/null +++ b/docs/source/user/subdyn/running_sd.rst @@ -0,0 +1,66 @@ +.. _running-subdyn: + +Running SubDyn +=============== + +This section discusses how to obtain and execute SubDyn from a personal +computer. Both the stand-alone version and the FAST-coupled version of +the software are considered. + +Downloading the SubDyn Software +-------------------------------- + +There are two forms of the SubDyn software to choose from: stand alone +and coupled to the FAST simulator. Although the user may not necessarily +need both forms, he/she would likely need to be familiar with and run +the stand-alone model if building a model of the substructure from +scratch. The stand-alone version is also helpful for model +troubleshooting and may benefit users who are interested in conducting +aero-hydro-servo-elastic simulations of an offshore wind turbine. + +Users can refer to the OpenFAST installation to download and compile SubDyn. + + +Running SubDyn +--------------- + +Running the Stand-Alone SubDyn Program +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The stand-alone SubDyn program, *SubDyn\_win32.exe*, simulates +substructure dynamic responses of the user’s input model, without +coupling to FAST. Unlike the coupled version, the stand-alone software +requires the use of a driver file in addition to the primary SubDyn +input file. This driver file specifies inputs normally provided to +SubDyn by FAST, including motions of the TP reference point. Both the +SubDyn summary file and the results output file are available when using +the stand-alone SubDyn (see Section 4 for more information regarding the +SubDyn output files). + +Run the standalone SubDyn software from a DOS command prompt by typing, +for example: + +.. code-block:: bash + + >SubDyn_win32.exe MyDriverFile.dvr + +where, *MyDriverFile.dvr* is the name of the SubDyn driver file, as +described in :numref:`sd_main-input-file`. The SubDyn primary input file is described in +Section :numref:`sd_driver-input-file`. + + +Running SubDyn Coupled to FAST +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Run the coupled FAST software from a DOS command prompt by typing, for +example: + +.. code-block:: bash + + >FAST_Win32.exe Test21.fst + +where, *Test21.fst* is the name of the primary FAST input file. This +input file has a feature switch to enable or disable the SubDyn +capabilities within FAST, and a corresponding reference to the SubDyn +input file. See the documentation supplied with FAST for further +information. diff --git a/docs/source/user/subdyn/theory.rst b/docs/source/user/subdyn/theory.rst new file mode 100644 index 0000000000..9ce6b69c18 --- /dev/null +++ b/docs/source/user/subdyn/theory.rst @@ -0,0 +1,2616 @@ +.. _subdyn-theory: + +SubDyn Theory +============= + + +Overview +-------- + +This section focuses on the theory behind the SubDyn module. + +SubDyn relies on two main engineering approaches: (1) a linear frame +finite-element model (LFEM), and (2) a dynamics system reduction +via the Craig-Bampton (C-B) method together with a static-improvement +method (SIM), greatly reducing the number of modes needed to obtain an +accurate solution. + +There are many nonlinearities present in offshore wind substructure +models, including material nonlinearity, axial shortening caused by +bending, large displacements, and so on. The material nonlinearity is +not considered here because most offshore multimember support structures +are designed to use steel and the maximum stress is intended to be below +the yield strength of the material. :cite:`damiani2013omae` demonstrate +that a linear finite-element method is suitable when analyzing wind +turbine substructures. In this work, several wind turbine configurations +that varied in base geometry, load paths, sizes, supported towers, and +turbine masses were analyzed under extreme loads using nonlinear and +linear models. The results revealed that the nonlinear behavior was +mainly caused by the mono-tower response and had little effect on the +multimember support structures. Therefore, an LFEM model for the +substructure is considered appropriate for wind turbine substructures. +The LFEM can accommodate different element types, including +Euler-Bernoulli and Timoshenko beam elements of either constant or +longitudinally tapered cross sections (Timoshenko beam elements account +for shear deformation and are better suited to represent low aspect +ratio beams that may be used within frames and to transfer the loads +within the frame). + +The large number of DOFs (~ :math:`{10^3}`) associated with a standard +finite-element analysis of a typical multimember structure would hamper +computational efficiency during wind turbine system dynamic simulations. +As a result, the C-B system reduction was implemented to speed up +processing time while retaining a high level of fidelity in the overall +system response. The C-B reduction is used to recharacterize the +substructure finite-element model into a reduced DOF model that +maintains the fundamental low-frequency response modes of the structure. +In the SubDyn initialization step, the large substructure physical DOFs +(displacements) are reduced to a small number of modal DOFs and +interface (boundary) DOFs, and during each time step, only the equations +of motion of these DOFs need to be solved. SubDyn only solves the +equations of motion for the modal DOFs, the motion of the interface +(boundary) DOFs are either prescribed when running SubDyn in stand-alone +mode or solved through equations of motion in ElastoDyn when SubDyn is +coupled to FAST. + +Retaining just a few DOFs may, however, lead to the exclusion of axial +modes (normally of very high frequencies), which are important to +capture static load effects, such as those caused by gravity and +buoyancy. The so-called SIM was implemented to mitigate this problem. +SIM computes two static solutions at each time step: one based on the +full system stiffness matrix and one based on the C-B reduced stiffness +matrix. At each time step the time-varying, C-B based, dynamic solution +is superimposed on the difference between the two static solutions, +which amounts to quasi-statically accounting for the contribution of +those modes not directly included within the dynamic solution. + +In SubDyn, the substructure is considered to be clamped, or connected +via linear spring-like elements, at the bottom nodes (normally at the +seabed) and rigidly connected to the TP at the substructure top nodes +(interface nodes). The user can provide 6x6, equivalent stiffness and +mass matrices for each of the bottom nodes to account for soil-pile +interaction. As described in other sections of this document, the input +file defines the substructure geometry, material properties, and +constraints. Users can define: element types; full finite-element mode +or C-B reduction; the number of modes to be retained in the C-B +reduction; modal damping coefficients; whether to take advantage of SIM; +and the number of elements for each member. + +The following sections discuss the integration of SubDyn within the FAST +framework, the main coordinate systems used in the module, and the +theory pertaining to the LFEM, the C-B reduction, and SIM. The +state-space formulations to be used in the time-domain simulation are +also presented. The last section discusses the calculation of the base +reaction calculation. For further details, see also :cite:`song2013`. + +Integration with the FAST Modularization Framework +-------------------------------------------------- + +Based on a new modularization framework :cite:`jjonkman2013`, FAST joins an +aerodynamics module, a hydrodynamics module, a control and electrical +system (servo) module, and structural-dynamics (elastic) modules to +enable coupled nonlinear aero-hydro-servo-elastic analysis of land-based +and offshore wind turbines in the time domain. :numref:`flow-chart2` shows the basic +layout of the SubDyn module within the FAST modularization framework. + +.. _flow-chart2: + +.. figure:: figs/flowchart2.png + :width: 70% + + SubDyn layout within the modularization framework + + +In the existing loosely coupled time-integration scheme, the glue-code +transfers data at each time step. Such data includes hydrodynamic loads, +substructure response, loads transmitted to the TP, and TP response +among SubDyn, HydroDyn, and ElastoDyn. At the interface nodes, the TP +displacement, rotation, velocity, and acceleration are inputs to SubDyn +from ElastoDyn, and the reaction forces at the TP are outputs of SubDyn +for input to ElastoDyn. SubDyn also outputs the substructure +displacements, velocities, and accelerations for input to HydroDyn to +calculate the hydrodynamic loads that become inputs for SubDyn. In +addition, SubDyn can calculate the member forces, as requested by the +user. Within this scheme, SubDyn tracks its states and integrates its +equations through its own solver. + +In a tightly coupled time-integration scheme (yet to be implemented), +SubDyn sets up its own equations, but its states and those of other +modules are tracked and integrated by a solver within the glue-code that +is common to all of the modules. + +SubDyn is implemented in a state-space formulation that forms the +equation of motion of the substructure system with physical DOFs at the +boundaries and modal DOFs representing all interior motions. At each +time step, loads and motions are exchanged between modules through the +driver code; the modal responses are calculated inside SubDyn’s +state-space model; and the next time-step responses are calculated by +the SubDyn integrator for loose coupling and the global system +integrator for tight coupling. + +Coordinate Systems +------------------ + +.. _global-cs: + +.. figure:: figs/global-cs.png + :width: 40% + + Global (coincident with the substructure) coordinate system. + Also shown are the DOFs associated with the TP reference point. + +Global and Substructure Coordinate System: (*X*, *Y*, *Z*) or (:math:`{X_{SS}, Y_{SS}, Z_{SS}}`) (:numref:`global-cs`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- The global axes are represented by the unit vectors :math:`{\hat{I}, \hat{J}}`, and :math:`{\hat{K}}`. + +- The origin is set at the intersection between the undeflected tower + centerline and the horizontal plane identified by the mean sea level + (MSL) for offshore systems or ground level for land-based systems. + +- The positive *Z* (:math:`{Z_{SS}}`) axis is vertical and pointing upward, opposite + gravity. + +- The positive *X* (:math:`{X_{SS}}`) axis is along the nominal (zero-degree) + wind and wave propagation direction. + +- The *Y* (:math:`{Y_{SS}}`) axis is transverse and can be found assuming a + right-handed Cartesian coordinate system (directed to the left when + looking in the nominal downwind direction). + +Member or Element Local Coordinate System (:math:`{x_e, y_e, z_e}`) (:numref:`element-cs`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Axes are represented by the unit vectors :math:`{\hat{i}_e, \hat{j}_e, \hat{k}_e}`. + +- The origin is set at the shear center of the cross section at the + start node (S,MJointID1). + +- The local :math:`z_{e}` axis is along the elastic axis of the member, directed from + the start node (S) to the end node (E,MJointID2). Nodes are ordered + along the member main axis directed from start joint to end joint + (per user's input definition). + +- The local :math:`x_{e}` axis is parallel to the global :math:`\text{XY}` plane, and + directed such that a positive, less than or equal to 180 :math:`^\circ` rotation + about it, would bring the local :math:`z_{e}` axis parallel to the global *Z* axis. + +- The local :math:`y_{e}` axis can be found assuming a right-handed Cartesian + coordinate system. + +.. _element-cs: + +.. figure:: figs/element-cs.png + :width: 100% + + The element coordinate system. The sketched member contains four elements, and the second element is called out with nodes S and E. + + + +Local to Global Transformation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The transformation from local to global coordinate system can be +expressed by the following equation: + + .. math:: :label: loc2glb + + \begin{bmatrix} \Delta X \\ \Delta Y \\ \Delta Z \end{bmatrix} = [ \mathbf{D_c} ] \begin{bmatrix} \Delta x_e \\ \Delta y_e \\ \Delta z_e \end{bmatrix} + +where :math:`\begin{bmatrix} \Delta x_e \\ \Delta y_e \\ \Delta z_e \end{bmatrix}` is a generic vector in the local coordinate system, and +:math:`\begin{bmatrix} \Delta X \\ \Delta Y \\ \Delta Z \end{bmatrix}` the same +vector but in the global coordinate system; and :math:`[ \mathbf{D_c} ]` is the direction cosine +matrix of the member axes and can be obtained as follows: + + .. math:: :label: Dc + + [ \mathbf{D_c} ] = \begin{bmatrix} + \frac{Y_E-Y_S}{L_{exy}} & \frac{ \left ( X_E-X_S \right) \left ( Z_E-Z_S \right)}{L_{exy} L_{e}} & \frac{X_E-X_S}{L_{e}} \\ + \frac{-X_E+X_S}{L_{exy}} & \frac{ \left ( Y_E-Y_S \right) \left ( Z_E-Z_S \right)}{L_{exy} L_{e}} & \frac{Y_E-Y_S}{L_{e}} \\ + 0 & \frac{ -L_{exy} }{L_{e}} & \frac{Z_E-Z_S}{L_{e}} + \end{bmatrix} + +Where :math:`{\left ( X_s,Y_s,Z_s \right )}` and :math:`{\left ( X_E,Y_E,Z_E \right )}` +are the start and end joints of the member (or nodes of the element of interest) in global coordinate system ; +:math:`{L_{exy}= \sqrt{ \left ( X_E-X_S \right )^2 + \left ( Y_E-Y_S \right )^2}}` and :math:`{L_{e}= \sqrt{ \left ( X_E-X_S \right )^2 + \left ( Y_E-Y_S \right )^2 + \left ( Z_E-Z_S \right )^2}}`. + +If :math:`{X_E = X_S}` and :math:`{Z_E = Z_S}`, the :math:`{[ \mathbf{D_c} ]}` matrix can be found as follows: + +if :math:`{Z_E >= Z_S}` then + + .. math:: :label: Dc_spec1 + + [ \mathbf{D_c} ] = \begin{bmatrix} + 1 & 0 & 0 \\ + 0 & 1 & 0 \\ + 0 & 0 & 1 + \end{bmatrix} + +else + + .. math:: :label: Dc_spec2 + + [ \mathbf{D_c} ] = \begin{bmatrix} + 1 & 0 & 0 \\ + 0 & -1 & 0 \\ + 0 & 0 & -1 + \end{bmatrix} + +In the current SubDyn release, the transpose (global to local) of these +direction cosine matrices for each member is returned in the summary +file. Given the circular shape of the member cross sections, the +direction cosine matrices have little importance on the member load +verification. To verify joints following the standards (e.g., :cite:`iso19902` :cite:`api2014` +), however, the bending moments need to be decomposed into +in-plane and out-of-plane components, where the plane is that defined by +either a pair of braces (for an X-joint), or by the pair brace(s) plus +leg (for a K-joint). It is therefore important to have the direction +cosines of the interested members readily available to properly +manipulate and transform the local shear forces and bending moments. + +When member cross sections other than circular are allowed in future +releases, the user will need to input cosine matrices to indicate the +final orientation of the member principal axes with respect to the +global reference frame. + +.. _SD_FEM: + +Finite-Element Model - Elements and Constraints +----------------------------------------------- + +Definitions +~~~~~~~~~~~ + +Figure :numref:`fig:ElementsDefinitions` is used to illustrate some of the definitions used. +The model of the substructure is assumed to consists of +different members. +A member is delimited by two joints. +A joint is defined by the coordinates of a point of the +undeflected structure and a type (*JointType*). The type of a joint defines the +boundary condition or constraint of all the members that are attached to +this joint. +The following joints are supported: + +- Cantilever joints (*JointType=1*) + +- Universal joint (*JointType=2*) + +- Pin joint (*JointType=3*) + +- Ball joint (*JointType=4*) + +A member is one of the three following types: + +- Beams (*MType=1*), Euler-Bernoulli (*FEMMod=1*) or Timoshenko (*FEMMod=3*) + +- Pretension cables (*MType=2*) + +- Rigid link (*MType=3*) + +Beam members may be split into several elements to increase the accuracy of the model (using +the input parameter *NDiv*). Member of other types (rigid links and +pretension cables) are not split. In this document, the term *element* +refers to: a sub-division of a beam member or a member of another type +than beam (rigid-link or pretension cable). The term *joints* refers to +the points defining the extremities of the members. Some joints are +defined in the input file, while others arise from the subdivision of +beam members. The end points of an elements are called nodes and each +node consists of 6 degrees of freedom (DOF) for the element implemented. +In the current implementation, no geometrical offsets are assumed between a joint and the node of an +element, or between the nodes of connected elements. + +.. figure:: figs/ElementsDefinitions.png + :alt: Definitions + :name: fig:ElementsDefinitions + :width: 80.0% + + Definitions of members, element, joints, nodes and rigid assemblies. + +.. _SD_FEM_Process: + +FEM process - from elements to system matrices +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The process to obtain a FE representation of the system (performed at initialization) is as follows: + +- Elements: The mass and stiffness matrices of each element are computed and transformed to global coordinates using directional cosine matrices + +- Assembly: The element matrices are inserted into the full system matrices. The DOFs of cantilever joints are mapped to each other. The translational DOFs of the nodes linked by a joint different from a cantilever joint are mapped to each other, but the rotational DOFs of each individual nodes are retained in this system. The vector of degrees of freedom of this full system is noted :math:`\boldsymbol{x}` + +- Constraints elimination: A direct-elimination technique is used to apply the constraints introduced by the joints and the rigid links. The elimination consists in forming a matrix :math:`\boldsymbol{T}` and a reduced set of degrees of freedom :math:`\boldsymbol{\tilde{x}}` such that :math:`\boldsymbol{x}=\boldsymbol{T} \boldsymbol{\tilde{x}}`. + +- CB-reduction: The Craig-Bampton reduction technique is used to obtain a reduced set of degrees of freedom (interface DOFs and Craig-Bampton modes) + +- Boundary conditions: The displacements boundary conditions are then applied (e.g. for a fixed bottom foundation) + +The remaining of the section focuses on the element matrices, +and the account of the constraints introduced by the joints and rigid links. +The Craig-Bampton reduction is described in :numref:`GenericCBReduction`. + + +Self-Weight Loads +~~~~~~~~~~~~~~~~~ +The loads caused by self-weight are precomputed during initialization +based on the undisplaced configuration. It is therefore assumed that the +displacements will be small and that P-delta effects are small for the +substructure. +The "extra" moment may be accounted for using the flag **GuyanLoadCorrection**, +see section :numref:`SD_ExtraMoment`. +For a nontapered beam element, the lumped loads caused by +gravity to be applied at the end nodes are as follows (in the global +coordinate system): + +.. math:: :label: FG + + \left\{ F_G \right\} = \rho A_z g + \begin{bmatrix} 0 \\ + 0 \\ + -\frac{L_e}{2} \\ + -\frac{L_e^2}{12} D_{c2,3} \\ + \frac{L_e^2}{12} D_{c1,3} \\ + 0\\ + 0\\ + 0\\ + -\frac{L_e}{2}\\ + \frac{L_e^2}{12} D_{c2,3}\\ + -\frac{L_e^2}{12} D_{c1,3}\\ + 0 + \end{bmatrix} + +Note also that if lumped masses exist (selected by the user at +prescribed joints), their contribution will be included as concentrated +forces along global *Z* at the relevant nodes. + + +Beam Element Formulation +~~~~~~~~~~~~~~~~~~~~~~~~ + +The uniform and tapered Euler-Bernoulli beam elements are +displacement-based and use third-order interpolation functions that +guarantee the displacement and rotation continuity between elements. The +uniform Timoshenko beam element is derived by introducing the shear +deformation into the uniform Euler-Bernoulli element, so the +displacements are represented by third-order interpolation functions as +well. +Following the classic Timoshenko beam theory, the generic two-node +element stiffness and consistent mass matrices can be written as follows +(see, for instance, :cite:`panzer2009`): + + +.. raw:: latex + + \renewcommand*{\arraystretch}{1.0} + + +.. math:: :label: ke0 + + \setcounter{MaxMatrixCols}{20} + + {\scriptstyle + [k_e]= + \begin{bmatrix} + \frac{12 E J_y} {L_e^3 \left( 1+ K_{sy} \right)} & 0 & 0 & 0 & \frac{6 E J_y}{L_e^2 \left( 1+ K_{sy} \right)} & 0 & -\frac{12 E J_y}{L_e^3 \left( 1+ K_{sy} \right)} & 0 & 0 & 0 & \frac{6 E J_y}{L_e^2 \left( 1+ K_{sy} \right)} & 0 \\ + & \frac{12 E J_x}{L_e^3 \left( 1+ K_{sx} \right)} & 0 & -\frac{6 E J_x}{L_e^2 \left ( 1+ K_{sx} \right )} & 0 & 0 & 0 & -\frac{12 E J_x}{L_e^3 \left ( 1+ K_{sx} \right )} & 0 & -\frac{6 E J_x}{L_e^2 \left ( 1+ K_{sx} \right )} & 0 & 0 \\ + & & \frac{E A_z}{L_e} & 0 & 0 & 0 & 0 & 0 & -\frac{E A_z}{L_e} & 0 & 0 & 0 \\ + & & & \frac{\left(4 + K_{sx} \right) E J_x}{L_e \left ( 1+ K_{sx} \right )} & 0 & 0 & 0 & \frac{6 E J_x}{L_e^2 \left ( 1+ K_{sx} \right )} & 0 & \frac{\left( 2-K_{sx} \right) E J_x}{L_e \left ( 1+ K_{sx} \right )} & 0 & 0 \\ + & & & & \frac{\left(4 + K_{sy} \right) E J_y}{L_e \left ( 1+ K_{sy} \right )} & 0 & -\frac{6 E J_y}{L_e^2 \left ( 1+ K_{sy} \right )} & 0 & 0 & 0 & \frac{\left( 2-K_{sy} \right) E J_y}{L_e \left ( 1+ K_{sy} \right )} & 0 \\ + & & & & & \frac{G J_z}{L_e} & 0 & 0 & 0 & 0 & 0 & -\frac{G J_z}{L_e} \\ + & & & & & & k_{11} & 0 & 0 & 0 & -\frac{6 E J_y}{L_e^2 \left ( 1+ K_{sy} \right )} & 0 \\ + & & & & & & & k_{22} & 0 & \frac{6 E J_x}{L_e^2 \left ( 1+ K_{sx} \right )} & 0 & 0 \\ + & & & & & & & & k_{33} & 0 & 0 & 0 \\ + & & & & & & & & & k_{44} & 0 & 0 \\ + & & & & & & & & & & k_{55} & 0 \\ + & & & & & & & & & & & k_{66} \\ + \end{bmatrix} + } + + +.. math:: :label: me0 + + [m_e]= \rho \\ + \left[\begin{array}{*{12}c} + \frac{13 A_z L_e}{35}+\frac{6 J_y}{5 L_e} & 0 & 0 & 0 & \frac{11 A_z L_e^2}{210}+\frac{J_y}{5 L_e} & 0 & \frac{9 A_z L_e}{70}-\frac{6 J_y}{5 L_e} & 0 & 0 & 0 & -\frac{13 A_z L_e^2}{420}+\frac{J_y}{10} & 0 \\ + & \frac{12 E J_x}{L_e^3 \left ( 1+ K_{sx} \right )} & 0 & -\frac{6 E J_x}{L_e^2 \left ( 1+ K_{sx} \right )} & 0 & 0 & 0 & -\frac{12 E J_x}{L_e^3 \left ( 1+ K_{sx} \right )} & 0 & -\frac{6 E J_x}{L_e^2 \left ( 1+ K_{sx} \right )} & 0 & 0 \\ + & & \frac{E A_z}{L_e} & 0 & 0 & 0 & 0 & 0 & -\frac{E A_z}{L_e} & 0 & 0 & 0 \\ + & & & \frac{\left(4 + K_{sx} \right) E J_x}{L_e \left ( 1+ K_{sx} \right )} & 0 & 0 & 0 & \frac{6 E J_x}{L_e^2 \left ( 1+ K_{sx} \right )} & 0 & \frac{\left( 2-K_{sx} \right) E J_x}{L_e \left ( 1+ K_{sx} \right )} & 0 & 0 \\ + & & & & \frac{\left(4 + K_{sy} \right) E J_y}{L_e \left ( 1+ K_{sy} \right )} & 0 & -\frac{6 E J_y}{L_e^2 \left ( 1+ K_{sy} \right )} & 0 & 0 & 0 & \frac{\left( 2-K_{sy} \right) E J_y}{L_e \left ( 1+ K_{sy} \right )} & 0 \\ + & & & & & \frac{G J_z}{L_e} & 0 & 0 & 0 & 0 & 0 & -\frac{G J_z}{L_e} \\ + & & & & & & \frac{12 E J_y}{L_e^3 \left ( 1+ K_{sy} \right )} & 0 & 0 & 0 & -\frac{6 E J_y}{L_e^2 \left ( 1+ K_{sy} \right )} & 0 \\ + & & & & & & & \frac{12 E J_x}{L_e^3 \left ( 1+ K_{sx} \right )} & 0 & \frac{6 E J_x}{L_e^2 \left ( 1+ K_{sx} \right )} & 0 & 0 \\ + & & & & & & & & \frac{E A_z}{L_e} & 0 & 0 & 0 \\ + & & & & & & & & & \frac{\left(4 + K_{sx} \right) E J_x}{L_e \left ( 1+ K_{sx} \right )} & 0 & 0 \\ + & & & & & & & & & & \frac{\left(4 + K_{sy} \right) E J_y}{L_e \left ( 1+ K_{sy} \right )} & 0 \\ + & & & & & & & & & & & \frac{G J_z}{L_e}\\ + \end{array}\right] + +where :math:`A_z` is the element cross-section area, :math:`J_x, J_y, J_z` are the area second moments of +inertia with respect to principal axes of the cross section; :math:`L_e` is the +length of the undisplaced element from start-node to end-node; :math:`\rho, E, \textrm{and}\quad G` are material density, Young’s, and Shear moduli, respectively; +:math:`K_{sx}, K_{sy}` are shear correction factors as shown below (they are set to zero if +the E-B formulation is chosen): + +.. math:: :label: Ksxy + + K_{sx}= \frac{12 E J_y}{G A_{sx} L_e^2} + + K_{sy}= \frac{12 E J_x}{G A_{sy} L_e^2} + +where the shear areas along the local *x* and *y* (principal) axes are +defined as: + +.. math:: :label: Asxy + + A_{sx}= k_{ax} A_z + + A_{sy}= k_{ay} A_z + + + +and + +.. math:: :label: kaxy + + k_{ax} = k_{ay} = \dfrac{ 6 (1 + \mu)^2 \left(1 + \left( \frac{D_i}{D_o} \right)^2 \right)^2 } { \left(1+ \left( \frac{D_i}{D_o} \right)^2 \right)^2 (7 + 14 \mu + 8 \mu^2) + 4 \left( \frac{D_i}{D_o} \right)^2 (5+10 \mu +4 \mu^2)} + + + +Eq. :eq:`kaxy` is from :cite:`steinboeck2013` for hollow circular cross sections, +with :math:`\mu` denoting Poisson’s ratio. + +Before assembling the global system stiffness (*K*) and mass (*M*) +matrices, the individual :math:`{[k_e]}` and math:`{[m_e]}` are modified to the global coordinate +system via :math:`{[ \mathbf{D_c} ]}` as shown in the following equations: + +.. math:: :label: ke1 + + [k] = \begin{bmatrix} + [\mathbf{D_c}] & 0 & 0 & 0 \\ + & [\mathbf{D_c}] & 0 & 0 \\ + & & [\mathbf{D_c}] & 0 \\ + & & & [\mathbf{D_c}] + \end{bmatrix} [k_e] \begin{bmatrix} + [\mathbf{D_c}] & 0 & 0 & 0 \\ + & [\mathbf{D_c}] & 0 & 0 \\ + & & [\mathbf{D_c}] & 0 \\ + & & & [\mathbf{D_c}] + \end{bmatrix}^T + +.. math:: :label: me1 + + [m] = \begin{bmatrix} + [\mathbf{D_c}] & 0 & 0 & 0 \\ + & [\mathbf{D_c}] & 0 & 0 \\ + & & [\mathbf{D_c}] & 0 \\ + & & & [\mathbf{D_c}] + \end{bmatrix} [m_e] \begin{bmatrix} + [\mathbf{D_c}] & 0 & 0 & 0 \\ + & [\mathbf{D_c}] & 0 & 0 \\ + & & [\mathbf{D_c}] & 0 \\ + & & & [\mathbf{D_c}] + \end{bmatrix}^T + +where *m* and *k* are element matrices in the global coordinate system. + + +.. _SD_PretensionCable: + +Pretension Cable Element Formulation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +The master stiffness equations of FEM assumes that the forces vanish if +all displacements also vanish, that is, the relation between force and +displacement is linear, +:math:`\boldsymbol{f}=\boldsymbol{K}\boldsymbol{u}`. This assumption +does not hold if the material is subject to so-called initial strain, +initial stress of prestress. Such effects may be produced by temperature +changes and pretensions (or lack-of-fit fabrications). These effects are +for instance discussed in the notes of +Felippa :cite:`felippa`. + +Pretension cables may be modelled by assuming an initial elongation of a +truss element and considering the restoring force this initial +elongation may have in both the longitudinal and orthogonal direction. + + +Derivation +^^^^^^^^^^ + +A pretension cable oriented along the :math:`z`-direction is considered. +To simplify the derivation, the left point is assumed fixed and only the +right point deflects. The notations are illustrated in :numref:`fig:FEPreTension`. + +.. figure:: figs/FEPreTension.png + :alt: Pretension + :name: fig:FEPreTension + :width: 50.0% + + Notations used for the derivation of the pretension cable equation + + +The length of the element prior to the pretension is written +:math:`L_0`, and its axial stiffness is :math:`k=EA/L_0`. In this +equilibrium position the stress in the cable is zero. The user inputs +for this elements are selected as: the un-displaced joint locations +(while pre-tensioned) :math:`\boldsymbol{x}_1` and +:math:`\boldsymbol{x}_2`, the elongation stiffness :math:`EA`, and the +change in length :math:`\Delta L_0 = L_0-L_e` (:math:`<0`). The +pretension force :math:`T_0` is a derived input. The following +quantities are defined: + +.. math:: + + \begin{aligned} + L_e=\lVert\boldsymbol{x}_2-\boldsymbol{x}_1\rVert + ,\quad + \epsilon_0=\frac{T_0}{EA} + ,\quad + L_0=\frac{L_e}{1+\epsilon_0}\end{aligned} + +The different variables are defined as function of the inputs as +follows: + +.. math:: + + \begin{aligned} + L_0=L_e+\Delta L_0 + \qquad + T_0= - E A \frac{\Delta L_0}{L_0} + ,\qquad + \epsilon_0=\frac{T_0}{EA} = \frac{-\Delta L_0}{L_0} = \frac{-\Delta L_0}{L_e+\Delta L_0 }\end{aligned} + +The degrees of freedom for the deflections of the cable, +:math:`(u_x, u_z)`, are measured from a position which is not the +equilibrium position, but a position that is offset from the equilibrium +position, such that the pretensioned length of the element is +:math:`L_e>L_0`. The stress in the cable for :math:`u_z=0` is noted +:math:`\epsilon_0=(L_e-L_0)/L_0`, or :math:`L_e=L_0(1+\epsilon_0)`. The +initial tension in the cable is +:math:`\boldsymbol{T}_0=-k(L_e-L_0)\,\boldsymbol{e}_z=- E A \epsilon_0\, \boldsymbol{e}_z`. +In its deflected position, the length of the cable is: + +.. math:: + + \begin{aligned} + L_d =\sqrt{(L_e+u_z)^2 + u_x^2} + =L_e\sqrt{1+\frac{2u_z}{L_e} + \frac{u_z^2}{L-e^2}+\frac{u_x^2}{L_e^2}} + \approx L_e \left(1+\frac{u_z}{L_e}\right) + \label{eq:PreTensionLength}\end{aligned} + +where the deflections are assumed small compared to the element length +:math:`L_e`, :math:`u_x\ll L_e` and :math:`u_z\ll L_e`, and only the +first order terms are kept. The tension force in the deflected cable is +then :math:`\boldsymbol{T}_d=-k(L_d-L_0) \boldsymbol{e}_r` where the +radial vector is the vector along the deflected cable such that: + +.. math:: + + \begin{aligned} + \boldsymbol{e}_r=\cos\theta \boldsymbol{e}_z +\sin\theta \boldsymbol{e}_x + ,\quad\text{with}\quad + \cos\theta=\frac{L_e+u_z}{L_d} + \approx 1 + ,\quad + \sin\theta= \frac{u_x}{L_d} + \approx \frac{u_x}{L_e}(1-\frac{u_z}{L_e}) + \approx \frac{u_x}{L_e} + \label{eq:PreTensionRadial}\end{aligned} + +The components of the tension force are then: + +.. math:: + + \begin{aligned} + T_{d,z}&= -k(L_d-L_0)\cos\theta \approx -\frac{EA}{L_0}(L_e-L_0+u_z)\, 1\, + = -EA\epsilon_0-\frac{EA}{L_0}u_z + \nonumber + \\ + T_{d,x}&= -k(L_d-L_0)\sin\theta \approx -\frac{EA}{L_0}(L_e-L_0+u_z)\frac{u_x}{L_e} + \approx -EA\epsilon_0\frac{u_x}{L_e} + = -\frac{EA\epsilon_0}{L_0(1+\epsilon_0)}u_x + \label{eq:PreTensionForce}\end{aligned} + +Finite element formulation of a pretension cable +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The rotational degrees of freedom are omitted for conciseness since +these degrees of freedom are not considered in this cable element. The +linear formulation from is applied to both nodes of a finite element, +interpreting the force at each node as the internal force that the +element exert on the nodes. Using this convention, the pretension cable +element can be represented with an element stiffness matrix +:math:`\boldsymbol{K}_e` and an additional nodal load vector +:math:`\boldsymbol{f}_{e,0}` such that the static equilibrium equation +of the element writes +:math:`\boldsymbol{f}_e=\boldsymbol{K}_e\boldsymbol{u}+\boldsymbol{f}_{e,0}`, +with: + +.. math:: + + \begin{aligned} + \begin{bmatrix} + f_{x,1}\\ + f_{y,1}\\ + f_{z,1}\\ + f_{x,2}\\ + f_{y,2}\\ + f_{z,2}\\ + \end{bmatrix} + = + \frac{EA}{L_0} + \begin{bmatrix} + \frac{\epsilon_0}{1+\epsilon_0} & 0 & 0 & -\frac{\epsilon_0}{1+\epsilon_0} & 0 & 0 \\ + 0 & \frac{\epsilon_0}{1+\epsilon_0} & 0 & 0 & -\frac{\epsilon_0}{1+\epsilon_0} & 0 \\ + 0 & 0 & 1 & 0 & 0 & -1\\ + -\frac{\epsilon_0}{1+\epsilon_0} & 0 & 0 & \frac{\epsilon_0}{1+\epsilon_0} & 0 & 0 \\ + 0 & -\frac{\epsilon_0}{1+\epsilon_0} & 0 & 0 & \frac{\epsilon_0}{1+\epsilon_0} & 0 \\ + 0 & 0 & -1 & 0 & 0 & 1 \\ + \end{bmatrix} + \begin{bmatrix} + u_{x,1}\\ + u_{y,1}\\ + u_{z,1}\\ + u_{x,2}\\ + u_{y,2}\\ + u_{z,2}\\ + \end{bmatrix} + + + EA\epsilon_0 + \begin{bmatrix} + 0\\ + 0\\ + -1\\ + 0\\ + 0\\ + 1\\ + \end{bmatrix} + \label{eq:StiffnessMatrixCable}\end{aligned} + +The relation above is expressed in the element coordinate system. The +stiffness matrix and force vector are transferred to the global system +during the assembly process. Inserting :math:`\epsilon_0=0` in the above +equations leads to the formulation of a truss element. The linear model +above is only valid for :math:`L_d-L_0>0`, that is +:math:`(L_e-L_0+u_{z,2}-u_{z,1})>0`, and the implementation should abort +if this condition is not reached at a given time. If the cable has a +positive mass density :math:`\rho`, the mass matrix of the element is +given by: + +.. math:: + + \begin{aligned} + \boldsymbol{M}_e = \rho L_e + \left[ + \begin{array}{*{12}c} + 13/35 & 0 & 0 & & & & 9/70 & 0 & 0 & & & \\ + 0 & 13/35 & 0 & & \boldsymbol{0}_3 & & 0 & 9/70 & 0 & & \boldsymbol{0}_3 & \\ + 0 & 0 & 1/3 & & & & 0 & 0 & 1/6 & & & \\ + & & & & & & & & & & & \\ + & \boldsymbol{0}_3 & & & \boldsymbol{0}_3 & & & \boldsymbol{0}_3 & & & \boldsymbol{0}_3 & \\ + & & & & & & & & & & & \\ + 9/70 & 0 & 0 & & & & 13/35 & 0 & 0 & & & \\ + 0 & 9/70 & 0 & & \boldsymbol{0}_3 & & 0 & 13/35 & 0 & & \boldsymbol{0}_3 & \\ + 0 & 0 & 1/6 & & & & 0 & 0 & 1/3 & & & \\ + & & & & & & & & & & & \\ + & \boldsymbol{0}_3 & & & \boldsymbol{0}_3 & & & \boldsymbol{0}_3 & & & \boldsymbol{0}_3 & \\ + & & & & & & & & & & & \\ + \end{array} + \right] + \label{eq:MassMatrixPreTension}\end{aligned} + +with :math:`L_e` the *undisplaced* length of the element (not +:math:`L_0`). + +.. _SD_ControlCable: + +Controlled pretension cable +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The controller updates the value of :math:`\Delta L` at each time step, +which effectively changes the pretension properties of the cable. The +quantity :math:`\Delta L` is the change in restlength if the cable had +no pretension. Since cable extension beyond the element length +(:math:`L_e`) is not allowed in SubDyn, :math:`\Delta L` is limited to +negative values. + +At a given time, the restlength of the cable is :math:`L_r(t)` (instead +of :math:`L_0`), and the pretension force is :math:`T(t)` (instead of +:math:`T_0`). The pretension force is then given as: + +.. math:: + + \begin{aligned} + T(t)= E A \frac{-\Delta L_r(t)}{L_r(t)} = E A \frac{-\Delta L_r(t)}{L_e + \Delta L(t)} + ,\quad + T(0) =T_0= E A \frac{-\Delta L_0}{L_e + \Delta L_0} + ,\quad + \Delta L(0) = \Delta L_0\end{aligned} + +The “equations of motions” for a cable element are written: + +.. math:: + + \begin{aligned} + \boldsymbol{M}_e\boldsymbol{\ddot{u}}_e&= \boldsymbol{f}_e\end{aligned} + +If the pretension force is constant, equal to :math:`T_0` then the +element force is: + +.. math:: + + \begin{aligned} + \boldsymbol{f}_e=\boldsymbol{f}_e (t,T_0) &=-\boldsymbol{K}_c(T_0) \boldsymbol{u}_e + \boldsymbol{f}_c(T_0)+ \boldsymbol{f}_g + \label{eq:CableEqMotionT0}\end{aligned} + +where :math:`\boldsymbol{f}_c(T_0)` and :math:`\boldsymbol{K}_c(T_0)` +are given in . If the pretension force is varying with time +(:math:`T=T(t)`), then the force is: + +.. math:: + + \begin{aligned} + \boldsymbol{f}_e (t) =-\boldsymbol{K}_c(T) \boldsymbol{u}_e + \boldsymbol{f}_c(T)+ \boldsymbol{f}_g + \label{eq:VaryingCableA}\end{aligned} + +where is evaluated with :math:`\epsilon=\frac{T}{EA}` and +:math:`L=\frac{L_e}{1+\epsilon}`. We seek to express , as a correction +term added to the equation of a constant pretension cable (i.e. , with +:math:`T(0)=T_0`). We add :math:`\pm\boldsymbol{f}_e(t,T_0)` to , +leading to: + +.. math:: + + \begin{aligned} + \boldsymbol{f}_e (t) &= \left [-\boldsymbol{K}_c(T_0) \boldsymbol{u}_e+ \boldsymbol{f}_c(T_0) + \boldsymbol{f}_g \right] - \left [-\boldsymbol{K}_c(T_0) \boldsymbol{u}_e + \boldsymbol{f}_c(T_0) + \boldsymbol{f}_g \right] + \left [-\boldsymbol{K}_c(T) \boldsymbol{u}_e + \boldsymbol{f}_c(T) + \boldsymbol{f}_g\right]\nonumber \\ + &= \left [-\underbrace{\boldsymbol{K}_c(T_0) \boldsymbol{u}_e}_{\text{in }CB}+ \underbrace{\boldsymbol{f}_c(T_0) + \boldsymbol{f}_g}_{\text{in } F_G} \right] +\boldsymbol{f}_{c,\text{control}}(T)\end{aligned} + +where :math:`\boldsymbol{f}_{c,\text{control}}` is the correction term +accounting for the time variation of :math:`T`: + +.. math:: + + \begin{aligned} + \boldsymbol{f}_{c,\text{control}}(T) &= \left( \boldsymbol{K}_c(T_0)-\boldsymbol{K}_c(T)\right) \boldsymbol{u}_e + \boldsymbol{f}_c(T) - \boldsymbol{f}_c(T_0)\end{aligned} + +This equation is transformed to the global system using the direction +cosine matrices of the element. The part involving +:math:`\boldsymbol{u}` introduces non-linearities, and is currently +neglected. Using , the additional control force for a given element is: + +.. math:: + + \begin{aligned} + \boldsymbol{f}_{c,\text{control}}(T) &\approx \boldsymbol{f}_c(T) - \boldsymbol{f}_c(T_0) = (T-T_0) + \begin{bmatrix} + 0\\ + 0\\ + -1\\ + 0\\ + 0\\ + 1\\ + \end{bmatrix} \end{aligned} + + + + + + + + + + + +Constraints introduced by Rotational Joints +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As mentioned in :numref:`SD_FEM_Process`, the account of constraints is done via a direct elimination technique. +The technique is implemented by computing a transformation matrix :math:`\boldsymbol{T}` +which gives the relationship between the reduced set of DOF (accounting for constraints) +and the full set of DOFs. +When no constraints are present this matrix is the identity matrix. +This section describes how the :math:`\boldsymbol{T}` matrix is obtained for rotational joints. + + +**Formulation** +Joints between two nodes :math:`k` and :math:`l` are +here considered. Before accounting for the constraint introduced by the +joints, :math:`12` degrees of freedom are present: +:math:`(\boldsymbol{u}_k,\boldsymbol{\theta}_k,\boldsymbol{u}_l,\boldsymbol{\theta}_l)`. +After application of the constraints, the new set of degrees of freedom +is noted +:math:`(\boldsymbol{\tilde{u}}_{kl}, \boldsymbol{\tilde{\theta}}_{kl})`. +The degrees of freedom retained for each joint type is shown in the table below. The +meaning of the different :math:`\theta`-variable will be made explicit +in the subsequent paragraphs. + +.. table:: Nodal degrees of freedom (DOF) for different joint types. + + ============== =================================== ===================================== =================================== ===================================================================================== + **Joint type** :math:`\boldsymbol{n}_\text{c}` :math:`\boldsymbol{n}_\text{DOF}` :math:`\boldsymbol{\tilde{u}}_{kl}` :math:`\boldsymbol{\tilde{\theta}}_{kl}` + ============== =================================== ===================================== =================================== ===================================================================================== + Cantilever :math:`6` :math:`12 \to 6` :math:`u_x,u_y,u_z` :math:`\theta_x,\theta_y,\theta_k` + Pin :math:`5` :math:`12 \to 7` :math:`u_x,u_y,u_z` :math:`\theta_1,\theta_2,\theta_3,\theta_4` + Universal :math:`4` :math:`12 \to 8` :math:`u_x,u_y,u_z` :math:`\theta_1,\theta_2,\theta_3,\theta_4,\theta_5` + Ball :math:`3` :math:`12 \to 9` :math:`u_x,u_y,u_z` :math:`\theta_{x,k},\theta_{y,k},\theta_{z,k},\theta_{x,l},\theta_{y,l},\theta_{z,l}` + ============== =================================== ===================================== =================================== ===================================================================================== + +For all the joints considered, the translational DOF of the two nodes +are made equal, which may be formally expressed as: + +.. math:: + + \begin{aligned} + \begin{bmatrix} + \boldsymbol{u}_{k} \\ + \boldsymbol{u}_{l} + \end{bmatrix} + = + \begin{bmatrix} + \boldsymbol{I}_3 \\ + \boldsymbol{I}_3 \\ + \end{bmatrix} + \boldsymbol{\tilde u}_{kl}\end{aligned} + +Since this relation is the same for all the joints, the relation between +the degrees of freedom is taken care in the assembly step. +The constraints of each joints will hence be expressed in the following form: + +.. math:: + + \begin{aligned} + \begin{bmatrix} + \boldsymbol{\theta}_{k} \\ + \boldsymbol{\theta}_{l} + \end{bmatrix} + =\boldsymbol{T}_{kl} + \boldsymbol{\tilde\theta}_{kl} + \label{eq:RotationalDOFJoint}\end{aligned} + +**Cantilever joint** For a cantilever joint between two elements, the reduction is: + +.. math:: + + \begin{aligned} + \begin{bmatrix} + \boldsymbol{\theta}_{k} \\ + \boldsymbol{\theta}_{l} + \end{bmatrix} + = + \boldsymbol{T}_{kl} + \boldsymbol{\tilde\theta}_{kl} + ,\qquad + \text{with} + \quad + \boldsymbol{\tilde\theta}_{kl} + = + \begin{bmatrix} + \boldsymbol{\theta}_{k} \\ + \end{bmatrix} + ,\qquad + \boldsymbol{T}_{kl}= + \begin{bmatrix} + \boldsymbol{I}_3 \\ + \boldsymbol{I}_3 \\ + \end{bmatrix}\end{aligned} + +This relationship is taken care of during the assembly process directly, and readily extended to :math:`n` elements. + +**Ball/spherical joint** For a spherical joint between two elements, the reduction is as follows: + +.. math:: + + \begin{aligned} + \begin{bmatrix} + \boldsymbol{\theta}_{k} \\ + \boldsymbol{\theta}_{l} + \end{bmatrix} + = + \boldsymbol{T}_{kl} + \boldsymbol{\tilde\theta}_{kl} + ,\qquad + \text{with} + \quad + \boldsymbol{\tilde\theta}_{kl} + = + \begin{bmatrix} + \boldsymbol{\theta}_{k} \\ + \boldsymbol{\theta}_{l} \\ + \end{bmatrix} + ,\qquad + \boldsymbol{T}_{kl}= + \begin{bmatrix} + \boldsymbol{I}_3 & \boldsymbol{0} \\ + \boldsymbol{0} & \boldsymbol{I}_3 \\ + \end{bmatrix}\end{aligned} + +For :math:`n` elements :math:`[e_1,\cdots, e_n]` connected by a ball +joint (constraint :math:`c`), the relationship is extended as follows: + +.. math:: + + \begin{aligned} + \begin{bmatrix} + \boldsymbol{\theta}_{e_1} \\ + \cdots\\ + \boldsymbol{\theta}_{e_n} + \end{bmatrix} + = + \boldsymbol{T}^c + \boldsymbol{\tilde\theta}^c + ,\qquad + \text{with} + \quad + \boldsymbol{\tilde\theta}^c + = + \begin{bmatrix} + \boldsymbol{\theta}_{e_1} \\ + \cdots\\ + \boldsymbol{\theta}_{e_n} \\ + \end{bmatrix} + ,\qquad + \boldsymbol{T}^c = + \begin{bmatrix} + \boldsymbol{I}_3 & & \boldsymbol{0} \\ + \ & \ddots & \\ + \boldsymbol{0} & & \boldsymbol{I}_3 \\ + \end{bmatrix} + \label{eq:BallJointMulti}\end{aligned} + +**Pin/revolute joint**   A pin joint is characterized by a direction +around which no moment is transferred. The unit vector indicating this +direction is noted :math:`\boldsymbol{\hat{p}}`. Two orthogonal vectors +:math:`\boldsymbol{p}_1` and :math:`\boldsymbol{p}_2` are then defined, +forming an orthonormal base with :math:`\hat{p}`, oriented arbitrarily (see :numref:`fig:FEJointPin`). + +.. figure:: figs/FEJointPin.png + :alt: Pin joint + :name: fig:FEJointPin + :width: 40.0% + + Notations used for the derivation of the pin-joint constraint + + +The variables :math:`\tilde{\theta}_1..\tilde{\theta}_4` are then +defined as: + +.. math:: + + \begin{aligned} + \tilde{\theta}_1&= + \boldsymbol{p}_1^t\cdot\boldsymbol{\theta}_k + = + \boldsymbol{p}_1^t\cdot\boldsymbol{\theta}_l \\ + \tilde{\theta}_2&= + \boldsymbol{p}_2^t\cdot\boldsymbol{\theta}_k + = + \boldsymbol{p}_2^t\cdot\boldsymbol{\theta}_l \\ + \tilde{\theta}_3&= + \boldsymbol{\hat{p}}^t \cdot\boldsymbol{\theta}_k\\ + \tilde{\theta}_4&= + \boldsymbol{\hat{p}}^t \cdot\boldsymbol{\theta}_l\end{aligned} + +which may be written in matrix form as: + +.. math:: + + \begin{aligned} + \begin{bmatrix} + \tilde{\theta}_1 \\ + \tilde{\theta}_2 \\ + \tilde{\theta}_3 \\ + \tilde{\theta}_4 \\ + \end{bmatrix} + = + \boldsymbol{A} + \begin{bmatrix} + \boldsymbol{\theta}_k \\ + \boldsymbol{\theta}_l \\ + \end{bmatrix} + = + \begin{bmatrix} + \boldsymbol{p}_1^t/2 & \boldsymbol{p}_1^t/2 \\ + \boldsymbol{p}_2^t/2 & \boldsymbol{p}_2^t/2 \\ + \boldsymbol{\hat{p}}^t & \boldsymbol{0} \\ + \boldsymbol{0} & \boldsymbol{\hat{p}}^t \\ + \end{bmatrix} + \begin{bmatrix} + \boldsymbol{\theta}_k \\ + \boldsymbol{\theta}_l \\ + \end{bmatrix}\end{aligned} + +The relations are inverted using a pseudo inverse, defined as +:math:`\boldsymbol{A}^{-1^\ast}=\boldsymbol{A}^t(\boldsymbol{A}\boldsymbol{A}^t)^{-1}`. +Using the pseudo-inverse, this equation is rewritten in the form of as: + +.. math:: + + \begin{aligned} + \begin{bmatrix} + \boldsymbol{\theta}_{k} \\ + \boldsymbol{\theta}_{l} + \end{bmatrix} + = + \boldsymbol{T}_{kl} + \boldsymbol{\tilde\theta}_{kl} + ,\qquad + \text{with} + \quad + = + \boldsymbol{\tilde\theta}_{kl} + \begin{bmatrix} + \tilde{\theta}_1 \\ + \tilde{\theta}_2 \\ + \tilde{\theta}_3 \\ + \tilde{\theta}_4 \\ + \end{bmatrix} + ,\qquad + \boldsymbol{T}_{kl}= + \begin{bmatrix} + \boldsymbol{p}_1^t/2 & \boldsymbol{p}_1^t/2 \\ + \boldsymbol{p}_2^t/2 & \boldsymbol{p}_2^t/2 \\ + \boldsymbol{\hat{p}}^t & \boldsymbol{0} \\ + \boldsymbol{0} & \boldsymbol{\hat{p}}^t \\ + \end{bmatrix}^{-1^\ast}\end{aligned} + +If :math:`n` elements :math:`[e_1,\cdots, e_n]`, are connected at a pin +joint (constraint :math:`c`), the relationship is extended as follows: + +.. math:: + + \begin{aligned} + \begin{bmatrix} + \boldsymbol{\theta}_{e_1} \\ + \cdots\\ + \boldsymbol{\theta}_{e_n} + \end{bmatrix} + = + \boldsymbol{T}^c + \boldsymbol{\tilde\theta}^c + ,\qquad + \text{with} + \quad + \boldsymbol{\tilde\theta}^c + = + \begin{bmatrix} + \tilde{\theta}_1 \\ + \tilde{\theta}_2 \\ + \tilde{\theta}_{e_1} \\ + \cdots \\ + \tilde{\theta}_{e_n} \\ + \end{bmatrix} + ,\qquad + \boldsymbol{T}^c = + \begin{bmatrix} + \boldsymbol{p}_1^t/n & \cdots &\boldsymbol{p}_1^t/n \\ + \boldsymbol{p}_2^t/n & \cdots &\boldsymbol{p}_2^t/n \\ + \boldsymbol{\hat{p}}^t & & \boldsymbol{0} \\ + & \ddots & \\ + \boldsymbol{0} & & \boldsymbol{\hat{p}}^t \\ + \end{bmatrix}^{-1^\ast} + \label{eq:PinJointMulti}\end{aligned} + +**Universal joint** A universal joint transfers the rotational moment +around two misaligned axes. Such joints are connecting only two +elements, labelled :math:`j` and :math:`k`, and the axes are taken as +the :math:`z` axis of each element. The axis vectors are expressed in +the global coordinates system and written :math:`\boldsymbol{\hat{z}}_j` +and :math:`\boldsymbol{\hat{z}}_k`. Similar notations are used for the +:math:`x` and :math:`y` axes. The DOF corresponding to the shared +rotation between the two axes is written :math:`\tilde{\theta}_1`. Each +element has two additional DOFs that are free to rotate, noted +:math:`\tilde{\theta}_x` and :math:`\tilde{\theta}_y`. The constraint +relationship between the original DOFs and the reduced DOFs is obtained +by projecting the rotational DOFs of each element against the different +axes. The relations are inverted using the pseudo-inverse, defined as +:math:`\boldsymbol{A}^{-1^\ast}=\boldsymbol{A}^t(\boldsymbol{A}\boldsymbol{A}^t)^{-1}`. +The constraints are then defined with: + +.. math:: + + \begin{aligned} + \boldsymbol{\tilde\theta}_c + = + \begin{bmatrix} + \tilde{\theta}_1 \\ + \tilde{\theta}_{x_j} \\ + \tilde{\theta}_{y_j} \\ + \tilde{\theta}_{x_k} \\ + \tilde{\theta}_{y_k} \\ + \end{bmatrix} + ,\quad + \boldsymbol{T}_c= + \begin{bmatrix} + \boldsymbol{\hat{z}}_j/2 & \boldsymbol{\hat{z}}_k/2 \\ + \boldsymbol{\hat{x}}_j & 0 \\ + \boldsymbol{\hat{y}}_j & 0 \\ + 0 & \boldsymbol{\hat{x}}_k \\ + 0 & \boldsymbol{\hat{y}}_k \\ + \end{bmatrix}^{-1^\ast}\end{aligned} + +.. math:: + + \begin{aligned} + \tilde{\theta}_c + = + \begin{Bmatrix} + \tilde{\theta}_1 \\ + \tilde{\theta}_{x,{e_1}} \\ + \tilde{\theta}_{y,{e_1}} \\ + \vdots\\ + \tilde{\theta}_{x,{e_n}} \\ + \tilde{\theta}_{y,{e_n}} \\ + \end{Bmatrix} + ,\quad + T_c= + \begin{bmatrix} + \hat{z}_{e_1}^t/2 & \cdots & \hat{z}_{e_n}^t/n \\ + \hat{x}_{e_1}^t & & 0 \\ + \hat{y}_{e_1}^t & & 0 \\ + 0 & \ddots & 0 \\ + 0 & & \hat{x}_{e_n}^t \\ + 0 & \cdots & \hat{y}_{e_n}^t \\ + \end{bmatrix}^{-1^\ast}\end{aligned} + + + + + + + + + + + + + + +.. _SD_RigidLinks: + + +Rigid-links +~~~~~~~~~~~ + +Rigid links and rigid elements impose a relationship between several +degrees of freedom, and as such, can be treated as *linear* *multipoint* +constraints. Rigid members can be used to join dissimilar elements +together or model a link of large stiffness between two elastic bodies +(see Cook :cite:`cook`). Mass properties for +rigid link may be provided in the input file, in which case the mass +matrix of a beam element is used for this rigid link. + +A rigid link between the nodes :math:`j` and :math:`k` is considered, +referred to as the element :math:`j-k`. The six degrees of freedom of a +given node, three displacements and three rotations, are noted +:math:`\boldsymbol{x}=[u_x,u_y,u_z,\theta_x,\theta_y,\theta_z]^t` in the +global system. The fact that the nodes :math:`j` and :math:`k` are rigidly connected is +formally expressed as follows: + +.. math:: :label: RigidLinkElem + + \begin{aligned} + \boldsymbol{x}_k= \boldsymbol{A}_{jk} \boldsymbol{x}_j + ,\qquad + \boldsymbol{A}_{jk}= + \begin{bmatrix} + 1 & 0 & 0 & 0 & \phantom{-} (z_k-z_j) & -(y_k-y_j) \\ + 0 & 1 & 0 & -(z_k-z_j) & 0 & \phantom{-} (x_k-x_j) \\ + 0 & 0 & 1 & \phantom{-} (y_k-y_j) & -(x_k-x_j) & 0 \\ + 0 & 0 & 0 & 1 & 0 & 0 \\ + 0 & 0 & 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 0 & 0 & 1 \\ + \end{bmatrix} + ,\qquad + \begin{bmatrix} + \boldsymbol{x}_j\\ + \boldsymbol{x}_k'\\ + \end{bmatrix} + = + \boldsymbol{T} + \boldsymbol{x}_j + = + \begin{bmatrix} + \boldsymbol{I}_6\\ + \boldsymbol{A}_{jk}'\\ + \end{bmatrix} + \boldsymbol{x}_j + \end{aligned} + +where the nodal coordinates :math:`(x,y,z)` are expressed in the global +system. The matrix :math:`\boldsymbol{T}` expresses the relation between +the condensed coordinates and the original coordinates. + +In the general case, several joints may be coupled together with rigid +links. An assembly of :math:`n` joints is here assumed with the 6-DOFs +of each joints written :math:`\boldsymbol{x}_1,\cdots,\boldsymbol{x}_n`. +It is further assumed that the first joint is selected as leader. For each +joint :math:`j\in \{2,\cdots,n\}` a matrix :math:`\boldsymbol{A}_{1j}` +is formed according to :eq:`RigidLinkElem`. +The matrices are built using the global coordinates of +each joint pairs. For this given rigid assembly (or constraint +:math:`c`), the relation between the joint DOFs and the reduced leader +DOF is: + +.. math:: + + \begin{aligned} + \boldsymbol{x}^c = \boldsymbol{T}^c \boldsymbol{\tilde{x}}^c + \quad + \text{with} + \quad + \boldsymbol{x}^c= + \begin{bmatrix} + \boldsymbol{x}_1\\ + \boldsymbol{x}_2\\ + \cdots\\ + \boldsymbol{x}_n\\ + \end{bmatrix} + ,\quad + \boldsymbol{T}^c= + \begin{bmatrix} + \boldsymbol{I}_6\\ + \boldsymbol{A}_{12}\\ + \cdots\\ + \boldsymbol{A}_{1n}\\ + \end{bmatrix} + ,\quad + \boldsymbol{\tilde{x}}^c=\boldsymbol{x}_1 + \label{eq:RigidLinkGlobMulti}\end{aligned} + +SubDyn detects rigid link assemblies and selects a leader node for the assembly. +If one of the node is an interface node, it is selected as a leader node. +The following restriction apply: the follower node cannot be a boundary node. + +The constraint are applied after the full system has been assembled. + + + + + + + +.. _GenericCBReduction: + +Craig-Bampton Reduction (theory) +-------------------------------- + +Full system +~~~~~~~~~~~ + + +The FEM equations of motion of SubDyn are written as follows: + +.. math:: :label: main + + [M] \{ \ddot{U} \} +[C] \{ \dot{U} \} + [K] \{ U \} = \{ F \} + + +where :math:`{[M]}` and :math:`{[K]}` are the global mass and stiffness matrices of the substructure +beam frame, assembled from the element mass and stiffness matrices. +Additionally, :math:`{[M]}` and :math:`{[K]}` contain the contribution from any specified :math:`{[M_{SSI}]}` and :math:`{[K_{SSI}]}` that +are directly added to the proper partially restrained node DOF rows and +column indexed elements. + +:math:`{{U}}` and :math:`{{F}}` are the displacements and external forces along all of the DOFs of +the assembled system. The damping matrix :math:`{[C]}` is not assembled from the +element contributions, because those are normally unknown, but can be specified in different ways, as discussed in :numref:`SD_DampingSpecifications`. +A derivative with respect to time is represented by a dot, so that :math:`{\dot{U}}` and :math:`{\ddot{U}}` are +the first- and second-time derivatives of :math:`{{U}}`, respectively. + +The number of DOFs associated with Eq. :eq:`main` can easily grow to the thousands +for typical beam frame substructures. That factor, combined with the +need for time-domain simulations of turbine dynamics, may seriously slow +down the computational efficiency of aeroelastic codes such as FAST +(note that a typical wind turbine system model in ElastoDyn has about 20 +DOFs). For this reason, a C-B methodology was used to recharacterize the +substructure finite-element model into a reduced DOF model that +maintains the fundamental low-frequency response modes of the structure. +With the C-B method, the DOFs of the substructure can be reduced to +about 10 (user defined, see also Section :numref:`CBguide`). This system reduction method +was first introduced by :cite:`hurty1964` and later expanded by :cite:`craig1968`. + + +CB-reduced system +~~~~~~~~~~~~~~~~~ +In this section we present the generic Craig-Bampton technique. +The specific application in SubDyn is presented in following sections. +In a C-B reduction, the structure nodes are separated into two +groups: 1) the boundary nodes (identified with a subscript “\ *R*\ ” in +what follows) that include the nodes fully restrained at the base of the +structure and the interface nodes; and 2) the interior nodes (or +leftover nodes, identified with a subscript “\ *L*\ ”). Note that the DOFs of partially restrained or “free” +nodes at the base of the structure are included in the “L” subset in +this version of SubDyn that contains SSI capabilities. + +The derivation of the system reduction is shown below. The system equation of motion of Eq. :eq:`main` can be partitioned as +follows: + +.. math:: :label: main2 + + \begin{bmatrix} + M_{RR} & M_{RL} \\ + M_{LR} & M_{LL} + \end{bmatrix} + \begin{bmatrix} + \ddot{U}_R \\ + \ddot{U}_L + \end{bmatrix} + + \begin{bmatrix} + C_{RR} & C_{RL} \\ + C_{LR} & C_{LL} \\ + \end{bmatrix} + \begin{bmatrix} + \dot{U}_R \\ + \dot{U}_L + \end{bmatrix} + + \begin{bmatrix} + K_{RR} & K_{RL} \\ + K_{LR} & K_{LL} \\ + \end{bmatrix} + \begin{bmatrix} + U_R \\ + U_L \\ + \end{bmatrix} = + \begin{bmatrix} + F_R \\ + F_L \\ + \end{bmatrix} + +where the subscript *R* denotes the boundary DOFs (there are *R* DOFs), and +the subscript *L* the interior DOFs (there are *L* DOFs). +In Eq. :eq:`main2`, the applied forces include external forces (e.g., hydrodynamic +forces and those transmitted through the TP to the substructure), gravity and pretension forces which are considered static forces lumped at each node. + +The fundamental assumption of the C-B method is that the contribution to +the displacement of the interior nodes can be simply approximated by a +subset :math:`q_m` ( :math:`{q_m \leq L}` ) of the interior generalized DOFs ( :math:`q_L` ). The relationship +between physical DOFs and generalized DOFs can be written as: + +.. math:: :label: CB1 + + \begin{bmatrix} + U_R \\ + U_L + \end{bmatrix} = + \begin{bmatrix} + I & 0 \\ + \Phi_R & \Phi_L + \end{bmatrix} + \begin{bmatrix} + U_R \\ + q_L + \end{bmatrix} + +where *I* is the identity matrix; :math:`{\Phi_R}` is the (*L*\ ×\ *R*) matrix of Guyan modes, +which represents the +physical displacements of the interior nodes for static, rigid body +motions at the boundary (interface nodes’ DOFs, because the restrained +nodes DOFs are locked by definition). By considering the homogeneous, +static version of :eq:`main2`, the second row can be manipulated to yield: + +.. math:: :label: CB2 + + [K_{LR}] {U_R} + [K_{LL}]{U_L} ={0} + +Rearranging and considering yields: + +.. math:: :label: PhiR + + \Phi_R = -K_{LL}^{-1} K_{LR} + +where the brackets have been removed for simplicity. +If the structure is unconstrained, the matrix :math:`{\Phi_R}` +corresponds to rigid body modes, ensuring that the internal nodes follow the rigid body +displacements imposed by the interface DOFs. This has been verified analytically using the +stiffness matrix of a single beam element. +:math:`{\Phi_L}` (*L*\ ×\ *L* matrix) represents the internal eigenmodes, i.e., the +natural modes of the system restrained at the boundary (interface and +bottom nodes), and can be obtained by solving the eigenvalue problem: + +.. math:: :label: PhiL1 + + K_{LL} \Phi_L = \omega^2 M_{LL} \Phi_L + +The eigenvalue problem in Eq. :eq:`PhiL1` leads to the reduced basis of generalized +modal DOFs :math:`q_m`, which are chosen as the first few (*m*) eigenvectors that +are arranged by increasing eigenfrequencies. :math:`\Phi_L` is mass normalized, so +that: + +.. math:: :label: PhiL2 + + \Phi_L^T M_{LL} \Phi_L = I + +By then reducing the number of generalized DOFs to *m* ( :math:`{\le L}`), +:math:`{\Phi_m}` is the matrix (:math:`{(L\times m)}` ) +chosen to denote the truncated set of :math:`{\Phi_L}` (keeping *m* of the total internal +modes, hence *m* columns), and :math:`{\Omega_m}` is the diagonal (*m*\ ×\ *m*) matrix +containing the corresponding eigenfrequencies (i.e., :math:`\Phi_m^T K_{LL} \Phi_m=\Omega_m^2`). +In SubDyn, the user +decides how many modes to retain, including possibly zero or all modes. +Retaining zero modes corresponds to a Guyan (static) reduction; +retaining all modes corresponds to keeping the full finite-element +model. + +The C-B transformation is therefore represented by the coordinate transformation matrix +:math:`T_{\Phi_m}` as: + +.. math:: :label: CB3 + + \begin{bmatrix} + U_R \\ + U_L \\ + \end{bmatrix} = + T_{\Phi_m} + \begin{bmatrix} + U_R \\ + q_m \\ + \end{bmatrix} + ,\qquad + T_{\Phi_m} = + \begin{bmatrix} + I & 0 \\ + \Phi_R & \Phi_m + \end{bmatrix} + +By using Eq. :eq:`CB3`, the interior DOFs are hence transformed from physical +DOFs to modal DOFs. By pre-multiplying both sides of Eq. :eq:`main2` by :math:`T_{\Phi_m}^T` on the left and :math:`T_{\Phi_m}` on the right, and making use of Eq. :eq:`PhiL2`, Eq. :eq:`main2` can be rewritten as: + +.. math:: :label: main3 + + \begin{bmatrix} + M_{BB} & M_{Bm} \\ + M_{mB} & I + \end{bmatrix} + \begin{bmatrix} + \ddot{U}_R \\ + \ddot{q}_m + \end{bmatrix} + + \begin{bmatrix} + C_{BB} & C_{Bm} \\ + C_{mB} & C_{mm} + \end{bmatrix} + \begin{bmatrix} + \dot{U}_R \\ + \dot{q}_m + \end{bmatrix} + + \begin{bmatrix} + K_{BB} & 0 \\ + 0 & K_{mm} + \end{bmatrix} + \begin{bmatrix} + U_R \\ + q_m + \end{bmatrix} = + \begin{bmatrix} + F_B \\ + F_m + \end{bmatrix} + +where + +.. math:: :label: partitions + :nowrap: + + \begin{align} + M_{BB} &= M_{RR} + M_{RL} \Phi_R + \Phi_R^T M_{LR} + \Phi_R^T M_{LL} \Phi_R \\ + C_{BB} &= C_{RR} + C_{RL} \Phi_R + \Phi_R^T C_{LR} + \Phi_R^T C_{LL} \Phi_R \nonumber \\ + K_{BB} &= K_{RR} + K_{RL} \Phi_R \nonumber \\ + M_{mB} &= \Phi_m^T M_{LR} + \Phi_m^T M_{LL} \Phi_R \nonumber \\ + C_{mB} &= \Phi_m^T C_{LR} + \Phi_m^T C_{LL} \Phi_R \nonumber \\ + K_{mm} & =\Phi_m^T K_{LL} \Phi_m = \Omega_m^2 \nonumber \\ + C_{mm} &= \Phi_m^T C_{LL} \Phi_m \nonumber \\ + F_B &= F_R +\Phi_R^T F_L \nonumber\\ + F_m &= \Phi_m^T F_L \nonumber + \end{align} + +and :math:`M_{Bm} = M_{mB}^T`, :math:`C_{Bm} =C_{mB}^T`. + + + +FEM formulation in SubDyn +------------------------- + + +.. _TP2Interface: + +Boundary nodes: fixed DOFs and rigid connection to TP +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In this section we present the treatment of the boundary nodes: fixed DOFs are eliminated, and interface DOFs are condensed via a rigid connection to the TP reference point. + +The boundary nodes are partitioned into those at the interface, :math:`{\bar{U}_R}`, +and those at the bottom, which are fixed: + +.. math:: :label: UR + + U_R = \begin{bmatrix} + \bar{U}_R \\ + 0 + \end{bmatrix} + + +The overhead bar here and below denotes matrices/vectors after the +fixed-bottom boundary conditions are applied. + +The interface nodes are +assumed to be rigidly connected among one another and to the TP reference point, hence it is convenient to use +rigid-body TP DOFs (one node with 6 DOFs at the TP reference point) in +place of the interface DOFs. The interface DOFs, :math:`{\bar{U}_R}`, and the TP DOFs are +related to each other as follows: + +.. math:: :label: UTP + + \bar{U}_R = T_I U_{TP} + +where :math:`T_I` is a :math:`{\left(6 NIN \right) \times 6}` matrix, :math:`NIN` is the number of interface nodes, and :math:`{U_{TP}}` is the 6 DOFs +of the rigid transition piece. The matrix :math:`T_I` can be written as follows: + +.. math:: :label: TI + + T_I= \begin{bmatrix} + 1 & 0 & 0 & 0 & \Delta Z_1 & - \Delta Y_1 \\ + 0 & 1 & 0 & -\Delta Z_1 & 0 & - \Delta X_1 \\ + 0 & 0 & 1 & \Delta Y_1 & - \Delta X_1 & 0 \\ + 0 & 0 & 0 & 1 & 0 & 0 \\ + 0 & 0 & 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 0 & 0 & 1 \\ + \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\ + 1 & 0 & 0 & 0 & \Delta Z_i & - \Delta Y_i \\ + 0 & 1 & 0 & -\Delta Z_i & 0 & - \Delta X_i \\ + 0 & 0 & 1 & \Delta Y_i & - \Delta X_i & 0 \\ + 0 & 0 & 0 & 1 & 0 & 0 \\ + 0 & 0 & 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 0 & 0 & 1 \\ + \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\ + \end{bmatrix}, \left( i= 1, 2, \cdots,NIN \right) + +with + +.. math:: :label: DXYZ + :nowrap: + + \begin{align} + \Delta X_i &= X_{INi} - X_{TP} \nonumber\\ + \Delta Y_i &= Y_{INi} - Y_{TP} \\ + \Delta Z_i &= Z_{INi} - Z_{TP} \nonumber + \end{align} + + +where :math:`{ \left( X_{INi}, Y_{INi}, Z_{INi} \right) }` are the coordinates +of the :math:`{i^{th}}` interface node and :math:`{ \left( X_{TP}, Y_{TP}, Z_{TP} \right) }` +are the coordinates of the TP reference point within the global coordinate system. + +In terms of TP DOFs, the system equation of motion :eq:`main3` after the boundary +constraints are applied (the rows and columns corresponding to the DOFs +of the nodes that are restrained at the seabed are removed from the +equation of motion) becomes: + +.. math:: :label: main4 + + \begin{bmatrix} + \tilde{M}_{BB} & \tilde{M}_{Bm} \\ + \tilde{M}_{mB} & I + \end{bmatrix} + \begin{bmatrix} + \ddot{U}_{TP} \\ + \ddot{q}_m + \end{bmatrix} + + \begin{bmatrix} + \tilde{C}_{BB} & \tilde{C}_{Bm} \\ + \tilde{C}_{mB} & C_{mm} + \end{bmatrix} + \begin{bmatrix} + \dot{U}_{TP} \\ + \dot{q}_m + \end{bmatrix} + + \begin{bmatrix} + \tilde{K}_{BB} & 0 \\ + 0 & K_{mm} + \end{bmatrix} + \begin{bmatrix} + U_{TP} \\ + q_m + \end{bmatrix} = + \begin{bmatrix} + \tilde{F}_{TP} \\ + F_m + \end{bmatrix} + + +with + +.. math:: :label: tilde_partitions0 + :nowrap: + + \begin{align} + \tilde{M}_{BB} &= T_I^T \bar{M}_{BB} T_I, \quad + \tilde{C}_{BB} = T_I^T \bar{C}_{BB} T_I, \quad + \tilde{K}_{BB} = T_I^T \bar{K}_{BB} T_I \\ + \tilde{M}_{Bm} &= T_I^T \bar{M}_{Bm}, \quad + \tilde{C}_{Bm} = T_I^T \bar{C}_{Bm} \nonumber \\ + \tilde{F}_{TP} &= T_I^T F_B \nonumber + \end{align} + +.. \tilde{F}_{TP} &= F_{TP} + T_I^T \left[ \bar{F}_{HDR}+ \bar{F}_{Rg} + \bar{\Phi}_{R}^T \left( F_{L,e} + F_{L,g} \right) \right] \nonumber \\ +.. \tilde{C}_{mm} &= C_{mm}, \quad +.. \tilde{K}_{mm} = K_{mm} = \Omega_m^2\nonumber \\ +.. \tilde{F}_{m} &= \Phi_m^T \left( F_{L,e} + F_{L,g} \right) \nonumber + +and :math:`\tilde{M}_{mB}= \tilde{M}_{Bm}^T`, :math:`\tilde{C}_{mB} = \tilde{C}_{Bm}^T`. + +Equation :eq:`main4` represents the equations of motion of the substructure after +the C-B reduction. The total DOFs of the substructure are reduced from +(6 x total number of nodes) to (6 + *m*). + +During initialization, SubDyn calculates: the parameter matrices :math:`{\tilde{M}_{BB}, \tilde{M}_{mB}, \tilde{M}_{Bm}, \tilde{K}_{BB}, \Phi_m, \Phi_R, T_I}`; constant load arrays ; and the internal frequency matrix :math:`\Omega_m` . The +substructure response at each time step can then be obtained by using +the state-space formulation discussed in the next section. + + +Floating or fixed-bottom structure +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Different formulations are used in SubDyn depending if the structure is "fixed-bottom" or "floating". + +The structure is considered to be "floating" if there is no reaction nodes. + +The structure is considered to be "fixed-bottom" in any other case. + + + +.. _SD_Loads: + +Loads +~~~~~ + +In this section, we detail the loads acting on the boundary (*R*) and interior (*L*) nodes, and the transition piece (*TP*) node. + +External loads that are accounted for by SubDyn, such as the gravity loads or the pretension loads, are noted with the subscript *g*. +External loads acting on the substructure and coming from additional modules, constisting for instance of hydrodynamic, mooring or soil loads, are noted with the subscript *e*. +The coupling loads that ElastoDyn would transmit to SubDyn are noted with the subscript *cpl*. +In the modular implementation, SubDyn does not receive these coupling loads from ElastoDyn, but instead receives displacements of the transition piece, and outputs the corresponding loads. This will be relevant for the state-space formulation, but for the purpose of this section, the coupling loads can be thought to be coming from ElastoDyn. + +The external loads at the boundary nodes (*R*) consist of the SubDyn gravitational and cable loads (*g*), the ElastoDyn coupling loads (*cpl*), and the external loads from other modules (*e*): + +.. math:: :label: FR + + F_R =F_{R,e} + F_{R,g} + F_{R, \text{cpl}} + +The external loads acting on the internal nodes are similarly decomposed: + +.. math:: :label: FL + + F_L =F_{L,e} + F_{L,g} + +The loads at the transition piece node (*TP*) are related to the interface boundary nodes (:math:`\bar{R}`) via the transformation matrix :math:`T_I`, which assumes that the :math:`\bar{R}` and *TP* nodes are rigidly connected: + +.. math:: :label: FTP1 + + F_{TP} = T_I^T \bar{F}_{R} + +In particular, the coupling force exchanged between ElastoDyn and SubDyn is: + +.. math:: :label: FTP1cpl + + F_{TP,cpl} = T_I^T \bar{F}_{R,\textit{cpl}} + + +The Guyan TP force, :math:`\tilde{F}_{TP}`, and the CB force, :math:`F_m`, given in Eq. :eq:`tilde_partitions0` are then decomposed as follows: + +.. math:: :label: FTPtilde + + \tilde{F}_{TP} &= F_{TP,cpl} + T_I^T \left[ \bar{F}_{R,e}+ \bar{F}_{R,g} + \bar{\Phi}_{R}^T \left( F_{L,e} + F_{L,g} \right) \right] + + F_m &= \Phi_m^t \left(F_{L,e} + F_{L,g}\right) + + + + + + + +.. _SD_Rotated Loads: +.. _SD_ExtraMoment: + +Corrections to the baseline formulation ("GuyanLoadCorrection") +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The baseline FEM implementation needs to be corrected to account for the fact that loads are provided to SubDyn at the displaced positions, and to account for the rigid body motions in the floating case. +The corrections are activated by setting the parameter **GuyanLoadCorrection** to True. + + + +**Rotation of coordinate system for floating** + +In the floating case, the FEM formulation needs to be rotated to the body frame. This is done when **GuyanLoadCorrection** is set to True. The CB and static modes are solved in a rotating frame of reference, that follows the rigid-body rotation of the Guyan modes. More details on this special case is found in section :numref:`SD_summary`. + + +**Additional lever arm from external loads** + +The external loads that are applied on the substructure are computed at the location of the deflected stucture. +On the other hand, the finite element formulation expect loads to be provided relative to the undeflected position of the structure, or, if rigid body motions are present, relative to a reference undeflected position (see Figure :numref:`sd_fig_extramoment`). +Nodal forces at a displaced node can be directly applied to the reference nodal position, but the mapping introduces a moment at the reference nodal position. + +The parameter **GuyanLoadCorrection** in the input file is used to account for this extra nodal moment occurring due to the fact that the finite element loads are expected to be expressed at a reference position and not at the displaced position. + +The mapping of nodal forces is done as follows when the parameter **GuyanLoadCorrection** is set to True. +First, a reference undeflected position of the structure is defined, with two possible configurations whether the structure is "fixed" at the sea bed, or not. The two configurations are illustrated in Figure :numref:`sd_fig_extramoment`. + +.. _sd_fig_extramoment: + +.. figure:: figs/extramoment.png + :width: 90% + + Illustration for the additional moment occurring due to the distance between the deflected position of the structure and the reference position used for the finite element representation. For simplicity, the loads are assumed to act at the Guyan position instead of the true deflected position. + +Second, the external loads are assumed to be applied on the "Guyan" deflected structure, instead of the fully deflected structure. The Craig-Bampton displacements are omitted to avoid the non-linear dependency between the input loads and the Craig-Bampton states. +With this assumption, the external loads at the Guyan position are mapped to the reference position. + +The additional moment is included for all external forces, including the gravitational forces. +For a given node :math:`i \in [R,L]`, and nodal force :math:`f_i=f_{i,g} +f_{i,e}`, the following additional moment is computed: + +.. math:: + + \Delta m_i= \Delta u_i \times \left[ f_i,g + f_i,e \right] + +with the vector :math:`\Delta u_i=\{\Delta u_{ix},\Delta u_{iy},\Delta u_{iz}\}`, defined differently depending on the reference position (fixed or free) and whether the node is an internal (*L*) or boundary node (*R*): + +.. math:: :label: eqextramom + :nowrap: + + \begin{align} + \text{(fixed bottom:)}\qquad + \Delta u_{ij} = [\bar{\Phi}_{R}T_I]_{ij} U_{TP} \quad \text{for } i\in L + \ + &\text{, and, } + \quad + \Delta u_{ij} = [T_{I}]_{ij} U_{TP} \quad \text{for } i \in \bar{R} + \\ + \text{(free/floating:)}\qquad + \Delta u_{ij} = [\bar{\Phi}_{R}T_I]_{ij} U_{TP} - U_{TP} \quad \text{for } i\in L + \ + &\text{, and, } + \quad + \Delta u_{ij} = [T_{I}]_{ij} U_{TP} - U_{TP} \quad \text{for } i \in \bar{R} + \end{align} + + +where :math:`j \in [x,y,z]` and the subscript :math:`ij` in :math:`[\bar{\Phi}_R T_I]_{ij}` indicates the row corresponding to node i and translational degree of freedom j. +Boundary DOFs that are fixed have no displacements and thus no extra moment contribution. Boundary DOFs that are free are part of the internal DOF *L* in the implementation. +The gravitational and cable forces at each node (that were computed at the initialization and stored in the constant vector :math:`F_G`) are used to obtain :math:`f_{i,g}`. It is noted that the *g*-contribution to the moment , :math:`\Delta m_i`, is not a constant and needs to be computed at each time step. + +To avoid adding more notations, all the load vectors used in this document will have the additional moment implicitely included when **GuyanLoadCorrection=True**. +This applies e.g.: to :math:`F_{R,e}, F_{L,e}, F_{R,g}, F_{L,g}`, where the following replacement is implied: + +.. math:: + + F_{R,e} + = \begin{Bmatrix} + \vdots\\ + f_{ix, e}\\ + f_{iy, e}\\ + f_{iz, e}\\ + m_{ix, e}\\ + m_{iy, e}\\ + m_{iz, e}\\ + \vdots\\ + \end{Bmatrix} + \quad + \longrightarrow + \quad + F_{R,e} = + \begin{Bmatrix} + \vdots\\ + f_{ix, e}\\ + f_{iy, e}\\ + f_{iz, e}\\ + m_{ix, e} + \Delta m_{ix, e}\\ + m_{iy, e} + \Delta m_{iy, e}\\ + m_{iz, e} + \Delta m_{iz, e}\\ + \vdots\\ + \end{Bmatrix} + \ + \text{(GuyanLoadCorrection=True)} + + + +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). +Similar considerations apply for Eq. :eq:`bigY2`. + + +The coupling load :math:`F_{{TP},cpl}` given in Eq. :eq:`bigY1` corresponds to the rection force at the TP reference position. +In the "free boundary condition" case, there is no need to correct this output load since the reference position is at the deflected position. +For the "fixed boundary condition" case, the reference position does not correspond to the deflected position, so the reaction moment needs to be transfered to the deflected position as follows: + +.. math:: + + F_{TP,cpl} + = + \begin{Bmatrix} + f_{TP,cpl} \\ + m_{TP,cpl} \\ + \end{Bmatrix} + \quad + \longrightarrow + \quad + F_{TP,cpl} = + \begin{Bmatrix} + f_{TP,cpl} \\ + m_{TP,cpl} -u_{TP} \times f_{TP,cpl} \\ + \end{Bmatrix} + \ + \text{(GuyanLoadCorrection=True and Fixed BC)} + +The output equation :math:`y_1= -F_{TP,cpl}` is then modified to include this extra contribution. + + +.. _SD_DampingSpecifications: + +Damping specifications +~~~~~~~~~~~~~~~~~~~~~~ + + +There are three ways to specify the damping associated with the motion +of the interface node in SubDyn: no damping, Rayleigh damping or user defined 6x6 matrix. + +NOTE: Damping associated with joints is not documented yet and would change the developments below. + +When **GuyanDampMod=0**, SubDyn assumes zero damping for the Guyan modes, and modal damping for the CB modes, with no cross couplings: + +.. math:: :label: dampingassumptions + + C_{BB} = \tilde{C}_{BB} &=0 + + C_{Bm} =C_{mB} = \tilde{C}_{Bm}=\tilde{C}_{mB}&=0 + + C_{mm} = \tilde{C}_{mm} &= 2\zeta \Omega_m + +In other words, the only damping matrix term retained is the one +associated with internal DOF damping. This assumption has implications +on the damping at the interface with the turbine system, as discussed in +Section :ref:`TowerTurbineCpling`. The diagonal (*m*\ ×\ *m*) :math:`\zeta` matrix contans the modal +damping ratios corresponding to each retained internal mode. In SubDyn, +the user provides damping ratios (in percent of critical damping +coefficients) for the retained modes. + +When **GuyanDampMod=1**, SubDyn assumes Rayleigh Damping for the Guyan modes, and modal damping for the CB modes, with no cross couplings: + + +.. math:: :label: dampingRayleigh + + \tilde{C}_{BB}&=\alpha \tilde{M}_{BB} + \beta \tilde{K}_{BB} + + \tilde{C}_{Bm}=\tilde{C}_{mB}&=0 + + \tilde{C}_{mm} &= 2\zeta \Omega_m + +where :math:`\alpha` and :math:`\beta` are the mass and stiffness proportional Rayleigh damping coefficients. The damping is directly applied to the tilde matrices, that is, the matrices related to the 6 DOF of the TP node. + +The case **GuyanDampMod=2**, is similar to the previous case, except that the user specifies the :math:`6\times6` terms of :math:`\tilde{C}_{BB}`. + + + +.. _sim: +.. _SD_SIM: + +Static-Improvement Method +~~~~~~~~~~~~~~~~~~~~~~~~~ +To account for the effects of static gravity (member self-weight) and +buoyancy forces, one would have to include all of the structural axial +modes in the C-B reduction. This inclusion often translates into +hundreds of modes to be retained for practical problems. An alternative +method is thus promoted to reduce this limitation and speed up SubDyn. +This method is denoted as SIM, and computes two static solutions at each +time step: one based on the full system stiffness matrix and one based +on the reduced stiffness matrix. The dynamic solution then proceeds as +described in the previous sections, and at each time step the +time-varying dynamic solution is superimposed on the difference between +the two static solutions, which amounts to quasi-statically accounting +for the contribution of those modes not directly included within the +dynamic solution. + +The SIM formulation provides a correction for the displacements of the +internal nodes. The uncorrected displacements are now noted :math:`{\hat{U}}_{L}`, while +the corrected displacements are noted :math:`U_L`. The SIM correction +consists in an additional term :math:`U_L` obtained by adding the total +static deflection of all the internal +DOFs (:math:`U_{L0}`), and subtracting the static deflection associated +with C-B modes (:math:`U_{L0m}`), as cast in :eq:`SIM` : + +.. math:: :label: SIM + + U_L = \hat{U}_L + U_{L,\text{SIM}} =\hat{U}_L+ \underbrace{U_{L0} - U_{L0m}}_{U_{L,\text{SIM}}} = \underbrace{\Phi_R U_R + \Phi_m q_m}_{\hat{U}_L} + \underbrace{\Phi_L q_{L0}}_{U_{L0}} - \underbrace{\Phi_m q_{m0}}_{U_{L0m}} + + +.. where the expression for :math:`U_{L0}` and :math:`U_{L0m}` will be derived in the next paragraph. + will be derived in the next paragraph. Eq. :eq:`SIM` can be rewritten as: + \begin{bmatrix} + U_R \\ + U_L + \end{bmatrix} = + \begin{bmatrix} + I & 0 & 0 & 0 \\ + \Phi_R & \Phi_m & \Phi_L & -\Phi_m + \end{bmatrix} + \begin{bmatrix} + U_R \\ + q_m \\ + q_{L0} \\ + q_{m0} + \end{bmatrix} + with: + U_{L0} = \Phi_L q_{L0}, \qquad U_{L0m} = \Phi_m q_{m0} + +where :math:`{q_{m0}}` and :math:`{q_{L0}}` are the *m* and *L* modal coefficients that are assumed to be +operating in a static fashion. These coefficients are +calculated under the C-B hypothesis that the boundary nodes are fixed. +The static displacement vectors can be calculated as follows: + + +.. math:: :label: SIM3 + + K_{LL} U_{L0} = F_{L,e} + F_{L,g} + +By pre-multiplying both sides times , Eq. :eq:`SIM3` can be +rewritten as: :math:`{\Phi_L^T K_{LL} \Phi_L q_{L0} = \Phi_L^T \left( F_{L,e} + F_{L,g} \right) = \tilde{F}_L }` or, recalling that :math:`{\Phi_L^T K_{LL} \Phi_L = \Omega_L^2}`, as: :math:`{\Omega_L^2 q_{L0} =\tilde{F}_L }`, or equivalently in terms of :math:`U_{L0}`: + +.. math:: :label: UL02 + + U_{L0} = \Phi_L \left[ \Omega_L^2 \right]^{-1} \tilde{F}_L + +Similarly: + +.. math:: :label: UL0m2 + + K_{LL} U_{L0m} = F_{L,e} + F_{L,g} \quad\rightarrow \quad U_{L0m} = \Phi_m \left[ \Omega_m^2 \right]^{-1} \tilde{F}_m + +with :math:`\tilde{F}_m =\Phi_m^T(F_{L,e} + F_{L,g})`. +Note that: :math:`{ \dot{U}_{L0} = \dot{q}_{L0} = \dot{U}_{L0m} = \dot{q}_{m0} =0 }` and :math:`{ \ddot{U}_{L0} = \ddot{q}_{L0} = \ddot{U}_{L0m} = \ddot{q}_{m0} =0 }`. + +In the floating case the loads :math:`F_L` is rotated to the body coordinate system when "GuyanLoadCorrection" is True (see :numref:`SD_ExtraMoment` for more details and :numref:`SD_summary` for the final equations used). + + + + + + + + +.. _SSformulation: + +State-Space Formulation +----------------------- + +A state-space formulation of the substructure structural dynamics +problem was devised to integrate SubDyn within the FAST modularization +framework. The state-space formulation was developed in terms of inputs, +outputs, states, and parameters. The notations highlighted here are +consistent with those used in Jonkman (2013). Inputs (identified by *u*) +are a set of values supplied to SubDyn that, along with the states, are +needed to calculate future states and the system’s output. Outputs (*y*) +are a set of values calculated by and returned from SubDyn that depend +on the states, inputs, and/or parameters through output equations (with +functions *Y*). States are a set of internal values of SubDyn that are +influenced by the inputs and used to calculate future state values and +the output. In SubDyn, only continuous states are considered. Continuous +states (*x*) are states that are differentiable in time and +characterized by continuous time differential equations (with functions +*X*). Parameters (*p*) are a set of internal system values that are +independent of the states and inputs. Furthermore, parameters can be +fully defined at initialization and characterize the system’s state +equations and output equations. + +In SubDyn, the inputs are defined as: + +.. math:: :label: inputs + + u = \begin{bmatrix} + u_1 \\ + u_2 \\ + u_3 \\ + u_4 \\ + u_5 \\ + \end{bmatrix} = \begin{bmatrix} + U_{TP} \\ + \dot{U}_{TP} \\ + \ddot{U}_{TP} \\ + F_{L,e} \\ + F_{R,e} \\ + \end{bmatrix} + + +where :math:`F_L` are the hydrodynamic forces on every interior node of the +substructure from HydroDyn, and :math:`F_{HDR}` are the analogous forces at the boundary +nodes; :math:`{ U_{TP},\dot{U}_{TP},\text{ and } \ddot{U}_{TP}}` are TP deflections (6 DOFs), velocities, and +accelerations, respectively. For SubDyn in stand-alone mode (uncoupled +from FAST), :math:`F_{L,e}` and :math:`F_{R,e}` are assumed to be zero. + +In first-order form, the states are defined as: + +.. math:: :label: states + + x = \begin{bmatrix} + x_1 \\ + x_2 \\ + \end{bmatrix} + = \begin{bmatrix} + q_m \\ + \dot{q}_m \\ + \end{bmatrix} + + +From the system equation of motion, the state equation corresponding to +Eq. :eq:`main4` can be written as a standard linear system state equation: + +.. math:: :label: state_eq + + \dot{x} = X = A x +Bu + F_X + +These state matrices are obtained by isolating the mode accelerations, :math:`\ddot{q}_m` from the second block row of Eq. :eq:`main4` as: + +.. math:: :label: ddotqm + :nowrap: + + \begin{align} + \ddot{q}_m = \underbrace{\Phi_m^T(F_{L,e} + F_{L,g})}_{F_m} + - \tilde{M}_{mB} \ddot{U}_{TP} + - \tilde{C}_{mB} \dot{U}_{TP} + - \tilde{C}_{mm} \dot{q}_m + - \tilde{K}_{mm} q_m + \end{align} + +leading to the following identification: + +.. math:: :label: ABFx + + A = \begin{bmatrix} + 0 & I \\ + -\tilde{K}_{mm} & -\tilde{C}_{mm} + \end{bmatrix} + ,\quad + B = \begin{bmatrix} + 0 & 0 & 0 & 0 & 0 \\ + 0 & -\tilde{C}_{mB} & -\tilde{M}_{mB} & \Phi_m^T & 0 + \end{bmatrix} + ,\qquad + F_X = \begin{bmatrix} + 0 \\ + \Phi_m^T F_{L,g} + \end{bmatrix} + + +In SubDyn, the outputs to the ElastoDyn module are the coupling (reaction) forces at the transition piece :math:`F_{TP,cpl}`: + +.. math:: :label: smally1 + + y1 = Y_1 =-F_{TP,cpl} + +By examining Eq. :eq:`main4` and Eq. :eq:`FTPtilde`, the force is extracted from the first block row as: + + +.. math:: :label: FTP2 + :nowrap: + + \begin{align} + F_{TP,cpl} =& \tilde{M}_{BB}\ddot{U}_{TP} + \tilde{M}_{Bm} \ddot{q}_m + \\ + &+ \tilde{C}_{BB}\dot{U}_{TP} + \tilde{C}_{Bm} \dot{q}_m + + \tilde{K}_{BB} U_{TP} + - T_I^T \left(\bar{F}_{R,e} + \bar{F}_{R,g} + \bar{\Phi}_R(F_{L,e} + F_{L,g}) \right) + \nonumber + \end{align} + + +Inserting the expression of :math:`\ddot{q}_m` into :math:`F_{TP}` leads to: + +.. math:: :label: FTP3 + :nowrap: + + \begin{align} + F_{TP,cpl} =& + \left[ - \tilde{M}_{Bm}\tilde{K}_{mm} \right] q_m + +\left[\tilde{C}_{Bm}- \tilde{M}_{Bm}\tilde{C}_{mm} \right] \dot{q}_m + \\ + &+\left[\tilde{K}_{BB} \right] U_{TP} + +\left[\tilde{C}_{BB} -\tilde{M}_{Bm} \tilde{C}_{mB} \right] \dot{U}_{TP} + +\left[\tilde{M}_{BB} -\tilde{M}_{Bm} \tilde{M}_{mB} \right] \ddot{U}_{TP} + \nonumber \\ + &+\left[\tilde{M}_{Bm}\Phi_m^T - T_I^T \bar{\Phi}_R^T \right] \left(F_{L,e} + F_{L,g}\right) + +\left[ -T_I^T \right]\left(\bar{F}_{R,e} + \bar{F}_{R,g}\right) + \nonumber + \end{align} + + +The output equation for :math:`y_1` can now be identified as: + +.. math:: :label: bigY1 + + -Y_1 = F_{TP,cpl} = C_1 x + D_1 \bar{u} + F_{Y1} + +where + + +.. math:: :label: C1D1FY1u + :nowrap: + + \begin{align} + C_1 &= \begin{bmatrix} + -\tilde{M}_{Bm} \tilde{K}_{mm} & \tilde{C}_{Bm}-\tilde{M}_{Bm} \tilde{C}_{mm} + \end{bmatrix} + \nonumber\\ + D_1 &= \begin{bmatrix} + \tilde{K}_{BB} & \tilde{C}_{BB} -\tilde{M}_{Bm} \tilde{C}_{mB} & \tilde{M}_{BB} - \tilde{M}_{Bm} \tilde{M}_{mB} & \tilde{M}_{Bm} \Phi_m^T - T_I^T \bar{\Phi}_R^T & -T_I^T + \end{bmatrix} + \nonumber\\ + F_{Y1} &= \begin{bmatrix} \tilde{M}_{Bm} \Phi_m^T F_{L,g} - T_I^T \left( \bar{F}_{R,g} + \bar{\Phi}_R^T F_{L,g} \right) \end{bmatrix} + \\ + \bar{u} &= \begin{bmatrix} + U_{TP} \\ + \dot{U}_{TP} \\ + \ddot{U}_{TP} \\ + F_{L,e} \\ + \bar{F}_{R,e} + \end{bmatrix} + \nonumber + \end{align} + + +Note that the overbar is used on the input vector to denote that the +forces apply to the interface nodes only. + +The outputs to HydroDyn and other modules are the deflections, +velocities, and accelerations of the substructure: + +.. math:: :label: y2 + + y_2= Y_2 = \begin{bmatrix} + \bar{U}_R \\ + U_L \\ + \dot{\bar{U}}_R \\ + \dot{U}_L \\ + \ddot{\bar{U}}_R \\ + \ddot{U}_L \\ + \end{bmatrix} + + + +From the CB coordinate transformation (Eq. :eq:`CB3`), and the link between boundary nodes and TP node (Eq. :eq:`UTP`) the motions are given as: + +.. math:: :label: y2motions + + \bar{U}_R &= T_I U_{TP} + ,\qquad + \bar{U}_L = \bar{\Phi}_R \bar{U}_R + \Phi_m q_m + \boldsymbol{U_{L,SIM}} + + \dot{\bar{U}}_R &= T_I \dot{U}_{TP} + ,\qquad + \dot{\bar{U}}_L = \bar{\Phi}_R \dot{\bar{U}}_R + \Phi_m \dot{q}_m + + \ddot{\bar{U}}_R &= T_I \ddot{U}_{TP} + ,\qquad + \ddot{\bar{U}}_L = \bar{\Phi}_R \ddot{\bar{U}}_R + \Phi_m \ddot{q}_m + +The expression for :math:`y2motions` contains the optional SIM contribution (see :numref:`SD_SIM`). +Using the expression of :math:`\ddot{q}_m` from Eq. :eq:`ddotqm`, the internal accelerations are: + + +.. math:: :label: y2internalacc + + \ddot{\bar{U}}_L = \bar{\Phi}_R T_I \ddot{U}_{TP} + \Phi_m\left[\Phi_m^T(F_{L,e} + F_{L,g}) + - \tilde{M}_{mB} \ddot{U}_{TP} + - \tilde{C}_{mB} \dot{U}_{TP} + - \tilde{C}_{mm} \dot{q}_m + - \tilde{K}_{mm} q_m \right] + + +In the floating case, the Guyan part of the motion are replaced by the analytical rigid body motion (see details in section :numref:`SD_summary`). + + +The output equation for :math:`y_2`: can then be written as: + +.. math:: :label: bigY2 + + Y_2 = C_2 x + D_2 u + F_{Y2} + + +where + +.. math:: :label: C2D2FY2 + + C_2 &= \begin{bmatrix} + 0 & 0 \\ + \Phi_m & 0 \\ + 0 & 0 \\ + 0 & \Phi_m \\ + 0 & 0 \\ + -\Phi_m \tilde{K}_{mm} & -\Phi_m \tilde{C}_{mm} \\ + \end{bmatrix} + + D_2 &= \begin{bmatrix} + T_I & 0 & 0 & 0 & 0 \\ + \bar{\Phi}_R T_I & 0 & 0 & 0 & 0 \\ + 0 & T_I & 0 & 0 & 0 \\ + 0 & \bar{\Phi}_R T_I & 0 & 0 & 0 \\ + 0 & 0 & T_I & 0 & 0 \\ + 0 & -\Phi_m \tilde{C}_{mB} & \bar{\Phi}_R T_I - \Phi_m \tilde{M}_{mB} & \Phi_m \Phi_m^T & 0 + \end{bmatrix} + + F_{Y2}& = \begin{bmatrix} + 0 \\ + \boldsymbol{U_{L,\text{SIM}}} \\ + 0 \\ + 0 \\ + 0 \\ + 0 \\ + \Phi_m \Phi_m^T F_{L,g} + \end{bmatrix} + + + + + + +Outputs and Time Integration +---------------------------- + + + +.. _SD_MemberForce: + +Nodal Loads Calculation +~~~~~~~~~~~~~~~~~~~~~~~~ + +We start by introducing how element loads are computed, before detailling how nodal loads are obtained. + +**Element Loads**: + +SubDyn calculates 12-vector element loads in the element coordinate system using the global motion of the element: + + +.. math:: :label: el_loads + + \text{Element Inertia load:} ~~ F_{I,12}^e &= [D_{c,12}]^T [m] \ddot{U}_{e,12} + + \text{Element Stiffness load:} ~~ F_{S,12}^e &= [D_{c,12}]^T [k] \left[ \hat{U}_e + U_{L,\text{SIM}} \right]_{12} + +where [*k*] and [*m*] are element stiffness and mass matrices expressed in the global frame, +:math:`D_{c,12}` is a 12x12 matrix of DCM for a given element, +the subscript 12 indicates that the 12 degrees of freedom of the element are considered, +and :math:`U_e` and :math:`\ddot{U}_e` are element nodal deflections and accelerations respectively, +which can be obtained from Eq. :eq:`y2` and may contain the static displacement contribution :math:`U_{L,\text{SIM}}`. There is no good way to quantify the damping forces for each element, so +the element damping forces are not calculated. + +**Nodal loads** + +For a given element node, the loads are the 6-vector with index 1-6 or 7-12 for the first or second node respectively. By convention, the 6-vector is multiplied by -1 for the first node and +1 for the second node of the element: + +.. math:: :label: nd_loads + + F_{6}^{n_1} = - F_{12}^e(1:6) + ,\quad + F_{6}^{n_2} = + F_{12}^e(7:12) + +The above applies for the inertial and stiffness loads. + + +**Member nodal loads requested by the user** + +The user can output nodal loads for a set of members (see :numref:`SD_Member_Output`). + +For the user requested member nodal outputs, the loads are either: 1) the appropriate 6-vector at the member end nodes, or, 2) the average of the 6-vectors from the two elements surrounding a node for the nodes in the middle of a member. When averaging is done, the 12-vectors of both surrounding elements are expressed using the DCM of the member where outputs are requested. + + +**"AllOuts" nodal loads** + +For "AllOuts" nodal outputs, the loads are not averaged and the 6-vector (with the appropriate signs) are directly written to file. + +**Reaction nodal loads** +(See :numref:`SD_Reaction`) + + + + +.. _SD_Reaction: + +Reaction Calculation +~~~~~~~~~~~~~~~~~~~~ + +The reactions at the base of the structure are the nodal loads at the +base nodes. + + + + +Additionally, the user may request an overall reaction +:math:`\overrightarrow{R}` (six forces and moments) lumped at the center +of the substructure (tower centerline) and mudline, i.e., at the +reference point (0,0,-**WtrDpth**) in the global reference frame, with +**WtrDpth** denoting the water depth. + +To obtain this overall reaction, the forces and moments at the :math:`N_\text{React}` restrained +nodes are expressed in the global coordinate frame and gathered into the vector :math:`F_{\text{React}}`, which is a (6*N\ :sub:`React`) array. +For a given reaction node, the 6-vector of loads is obtained by summing the nodal load contributions from all the elements connected to that node expressed in the global frame (no account of the sign is done here), and subtracting the external loads (:math:`F_{HDR}`) applied on this node. +The loads from all nodes, :math:`F_{\text{React}}`, are then rigidly-transferred to :math:`(0,0,-\text{WtrDpth})` to obtain the overall six-element array :math:`\overrightarrow{R}`: + +.. math:: :label: reaction + + \overrightarrow{R} = \begin{bmatrix} + F_{X} \\ + \vdots \\ + M_{Z} \\ + \end{bmatrix} = T_{\text{React}} F_{\text{React}} + +where :math:`T_{\text{React}}` is a +( :math:`{6×6 N_{\text{React}}}` ) matrix, as follows: + +.. math:: :label: Treact + + T_{\text{React}} = \begin{bmatrix} + 1 & 0 & 0 & 0 & 0 & 0 & \cdots & 1 & 0 & 0 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 & 0 & 0 & \cdots & 0 & 1 & 0 & 0 & 0 & 0 \\ + 0 & 0 & 1 & 0 & 0 & 0 & \cdots & 0 & 0 & 1 & 0 & 0 & 0 \\ + 0 & -\Delta Z_1 & \Delta Y_1 & 1 & 0 & 0 & \cdots & 0 & -\Delta Z_{Nreact} & \Delta Y_{Nreact} & 1 & 0 & 0 \\ + \Delta Z_1 & 0 & -\Delta X_1 & 0 & 1 & 0 & \cdots & \Delta Z_{Nreact} & 0 & -\Delta X_{Nreact} & 0 & 1 & 0 \\ + \Delta Y_1 & \Delta X_1 & 0 & 0 & 0 & 1 & \cdots & \Delta Y_{Nreact} & \Delta X_{Nreact} & 0 & 0 & 0 & 1 + \end{bmatrix} + +where :math:`{X_i,~Y_i}`, and :math:`Z_i` (:math:`{i = 1 .. N_{\text{React}}}`) are coordinates of +the boundary nodes with respect to the reference point. + + + +.. _TimeIntegration: + +Time Integration +~~~~~~~~~~~~~~~~~ + +At time :math:`{t=0}`, the initial states are specified as initial conditions (all +assumed to be zero in SubDyn) and the initial inputs are supplied to +SubDyn. During each subsequent time step, the inputs and states are +known values, with the inputs :math:`u(t)` coming from ElastoDyn and HydroDyn, and +the states :math:`x(t)` known from the previous time-step integration. All of the +parameter matrices are calculated in the SubDyn initiation module. With +known :math:`u(t)` and :math:`x(t)`, :math:`{\dot{x}(t)}` can be calculated using the state equation :math:`{\dot{x}(t)=X(u,x,t)}` (see Eq. :eq:`state_eq`), and +the outputs :math:`y_1(t)` and :math:`y_2(t)` can be calculated solving Eqs. :eq:`bigY1` and :eq:`bigY2`. The element forces +can also be calculated using Eq. :eq:`el_loads`. The next time-step states :math:`{x(t + \Delta t)}` are +obtained by integration: + +.. math:: :label: integration + + \left [ u(t), \dot{x}(t), x(t) \right ] \xrightarrow[]{\text{Integrate}} x(t + \Delta t) + + +For loose coupling, SubDyn uses its own integrator, whereas for tight +coupling, the states from all the modules will be integrated +simultaneously using an integrator in the glue-code. SubDyn’s built-in +time integrator options for loose coupling are: + +- Fourth-order explicit Runge-Kutta + +- Fourth-order explicit Adams-Bashforth predictor + +- Fourth-order explicit Adams-Bashforth-Moulton predictor-corrector + +- Implicit second-order Adams-Moulton. + +For more information, consult any numerical methods reference, e.g., +:cite:`chapra2010`. + + + + + +.. _SD_summary: + +Summary of the formulation implemented +-------------------------------------- + +This section summarizes the equations currently implemented in SubDyn, with the distinction between floating and fixed bottom cases. +We introduce the operators :math:`R_{g2b}` (rotation global to body) and :math:`R_{b2g}` (rotation body to global), which act on the array on the right of the operator. The operators rotate the individual 3-vectors present in an array. When applied to load vectors (e.g. :math:`F_L`), the rotations actually is applied to the loads on the full system, before the loads are transferred to the reduced system by use of the :math:`\boldsymbol{T}` matrix. + + +State equation +~~~~~~~~~~~~~~ + +**Fixed-bottom case** + +.. math:: + :nowrap: + + \begin{align} + \ddot{q}_m = \Phi_m^T F_L + - \tilde{M}_{mB} \ddot{U}_{TP} + - \tilde{C}_{mm} \dot{q}_m + - \tilde{K}_{mm} q_m + \end{align} + +Note: :math:`F_L` contains the "extra moment" if user-requested with **GuyanLoadCorrection**. + +**Floating case without "GuyanLoadCorrection"** + +.. math:: + :nowrap: + + \begin{align} + \ddot{q}_m = \Phi_m^T F_L + - \tilde{M}_{mB} \ddot{U}_{TP} + - \tilde{C}_{mm} \dot{q}_m + - \tilde{K}_{mm} q_m + \end{align} + +Notes: :math:`F_L` *does not* contain the "extra moment". + + +**Floating case with "GuyanLoadCorrection"** + +.. math:: + :nowrap: + + \begin{align} + \ddot{q}_m = \Phi_m^T R_{g2b} F_L + - \tilde{M}_{mB} R_{g2b} \ddot{U}_{TP} + - \tilde{C}_{mm} \dot{q}_m + - \tilde{K}_{mm} q_m + \end{align} + +Notes: :math:`F_L` *does not* contain the "extra moment". The (external + gravity) loads and the acceleration of the TP are rotated to the body coordinate system. + + +Output: interface reaction +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Fixed bottom case** + +.. math:: + :nowrap: + + \begin{align} + -Y_1 =F_{TP,cpl} = + \begin{Bmatrix} + f_{TP,cpl} \\ + m_{TP,cpl} \\ + \end{Bmatrix} + & = + \left[ - \tilde{M}_{Bm}\tilde{K}_{mm} \right] q_m + +\left[- \tilde{M}_{Bm}\tilde{C}_{mm} \right] \dot{q}_m + \\ + &+\left[\tilde{K}_{BB} \right] U_{TP} + +\left[\tilde{C}_{BB} \right] \dot{U}_{TP} + +\left[\tilde{M}_{BB} -\tilde{M}_{Bm} \tilde{M}_{mB} \right] \ddot{U}_{TP} + \nonumber \\ + &+\left[\tilde{M}_{Bm}\Phi_m^T\right] F_L +\left[- T_I^T \bar{\Phi}_R^T \right] F_{L} + +\left[ -T_I^T \right] \bar{F}_R + \nonumber + \end{align} + +Note: :math:`F_L` and :math:`\bar{F}_R` contains the "extra moment" if user-requested. +If this is the case, the following additional term is added to the moment part of :math:`Y_1`, +:math:`m_{Y_1,\text{extra}}=u_{TP} \times f_{TP,cpl}`. + + + +**Floating case without "GuyanLoadCorrection"** + +.. math:: + :nowrap: + + \begin{align} + -Y_1 =F_{TP,cpl} =& + \left[ - \tilde{M}_{Bm}\tilde{K}_{mm} \right] q_m + + \left[- \tilde{M}_{Bm}\tilde{C}_{mm} \right] \dot{q}_m + \\ + &+\left[\tilde{K}_{BB} \right] U_{TP} + +\left[\tilde{C}_{BB} \right] \dot{U}_{TP} + +\left[\tilde{M}_{BB} -\tilde{M}_{Bm} \tilde{M}_{mB} \right] \ddot{U}_{TP} + \nonumber \\ + &+ \left[\tilde{M}_{Bm}\Phi_m^T\right] F_L +\left[- T_I^T \bar{\Phi}_R^T \right] F_{L} + +\left[-T_I^T \right] \bar{F}_R + \nonumber + \end{align} + +Note: :math:`F_L` and :math:`\bar{F}_R` *do not* contain the "extra moment". + + +**Floating case with "GuyanLoadCorrection"** + +.. math:: + :nowrap: + + \begin{align} + -Y_1 =F_{TP,cpl} =& + R_{b2g}\left[ - \tilde{M}_{Bm}\tilde{K}_{mm} \right] q_m + + R_{b2g}\left[- \tilde{M}_{Bm}\tilde{C}_{mm} \right] \dot{q}_m + \\ + &+\left[\tilde{K}_{BB} \right] U_{TP} + +\left[\tilde{C}_{BB} \right] \dot{U}_{TP} + +\left[\tilde{M}_{BB} -\tilde{M}_{Bm} \tilde{M}_{mB} \right] \ddot{U}_{TP} + \nonumber \\ + &+ R_{b2g}\left[\tilde{M}_{Bm}\Phi_m^T\right] R_{g2b} F_L +\left[- T_I^T \bar{\Phi}_R^T \right] F_{L,\text{extra}} + +\left[-T_I^T \right] \bar{F}_{R,\text{extra}} + \nonumber + \end{align} + + +Notes: 1) :math:`F_{L,\text{extra}}` and :math:`F_{R,\text{extra}}` contain the "extra moment" in the Guyan contribution; 2) For the Craig-Bampton contribution, the loads are rotated to the body coordinate system using the operator :math:`R_{g2b}` (global to body); 3) The rotation :math:`R_{b2g}\tilde{M}_{Bm} \tilde{M}_{mB}R_{g2b}` is not carried out since it introduced stability issues. + +Output: nodal motions +~~~~~~~~~~~~~~~~~~~~~ + +**Fixed-bottom case** + +.. math:: :label: + + \bar{U}_R &= T_I U_{TP} + ,\qquad + \bar{U}_L = \bar{\Phi}_R \bar{U}_R + \Phi_m q_m + U_{L,\text{SIM}} + + \dot{\bar{U}}_R &= T_I \dot{U}_{TP} + ,\qquad + \dot{\bar{U}}_L = \bar{\Phi}_R \dot{\bar{U}}_R + \Phi_m \dot{q}_m + + \ddot{\bar{U}}_R &= T_I \ddot{U}_{TP} + ,\qquad + \ddot{\bar{U}}_L = \bar{\Phi}_R \ddot{\bar{U}}_R + \Phi_m\left[\Phi_m^T F_L + - \tilde{M}_{mB} \ddot{U}_{TP} + - \tilde{C}_{mm} \dot{q}_m + - \tilde{K}_{mm} q_m \right] + + +Note: :math:`F_L` contains the "extra moment" if user-requested with **GuyanLoadCorrection**. + + + +**Floating case** + +.. math:: :label: + + \bar{U}_R &= U_{R,\text{rigid}} + ,\qquad + \bar{U}_L = U_{L,\text{rigid}} + 0\cdot R_{b2g} \left(\Phi_m q_m + U_{L,\text{SIM}}\right) + + \dot{\bar{U}}_R &= \dot{U}_{R,\text{rigid}} + ,\qquad + \dot{\bar{U}}_L = \dot{U}_{L,\text{rigid}} + R_{b2g} \Phi_m \dot{q}_m + + \ddot{\bar{U}}_R &= \ddot{U}_{R,\text{rigid}} + ,\qquad + \ddot{\bar{U}}_L = \ddot{U}_{L,\text{rigid}} + R_{b2g}\Phi_m\left[\Phi_m^T R_{g2b} F_L + - \tilde{M}_{mB} R_{g2b}\ddot{U}_{TP} + - \tilde{C}_{mm} \dot{q}_m + - \tilde{K}_{mm} q_m \right] + +where: 1) :math:`F_L` does not contain the extra moment, 2) the operators :math:`R_{g2b}` and :math:`R_{b2g}` are when GuyanLoadCorrection is True, 3) the elastic displacements were set to 0 for stability purposes (assuming that these are small) 4) the Guyan motion is computed using the exact rigid body motions. For a given node :math:`P`, located at the position :math:`r_{IP,0}` from the interface in the undisplaced configuration, the position (from the interface point), displacement, translational velocity and acceleration due to the rigid body motion are: + + +.. math:: + r_{IP} &= R_{b2g} r_{IP,0} + ,\quad + u_P = r_{IP} - r_{IP,0} + u_{TP} + ,\quad + + \dot{u}_P &= \dot{u}_{TP} + \omega_{TP} \times r_{IP} + ,\quad + \ddot{u}_P= \ddot{u}_{TP} + \dot{\omega}_{TP} \times r_{IP} + \omega_{TP} \times (\omega_{TP} \times r_{IP}) + +where :math:`\omega_{TP}` is the angular velocity at the transition piece. The small angle rotations, angular velocities and accelerations of each nodes, due to the rigid body rotation, are the same as the interface values, :math:`\theta_{TP}`, :math:`\omega_{TP}` and :math:`\dot{\omega}_{TP}`, so that: + +.. math:: + U_{P,\text{rigid}} = \{u_P \ ; \theta_{TP}\}^T + ,\quad + \dot{U}_{P,\text{rigid}} = \{\dot{u}_P \ ; \omega_{TP}\}^T + ,\quad + \ddot{U}_{P,\text{rigid}} = \{\ddot{u}_P \ ; \dot{\omega}_{TP}\}^T + +where :math:`P` is a point belonging to the R- or L-set of nodes. + + +Outputs to file: +~~~~~~~~~~~~~~~~ + +**Motions**: nodal motions written to file are in global coordinates, and for the floating case they contain the elastic motion :math:`\bar{U}_L = U_{L,\text{rigid}} + \Phi_m q_m + U_{L,\text{SIM}}` (whereas these elastic motions are not returned to the glue code) + + +**Loads**: + +Nodal loads are written to file in the element coordinate system. The procedure are the same for fixed-bottom and floating cases. + diff --git a/docs/source/user/subdyn/zrefs.rst b/docs/source/user/subdyn/zrefs.rst new file mode 100644 index 0000000000..1139eba4b4 --- /dev/null +++ b/docs/source/user/subdyn/zrefs.rst @@ -0,0 +1,9 @@ +.. only:: html + + References + ---------- + +.. bibliography:: references_SD.bib + + + diff --git a/glue-codes/openfast/CMakeLists.txt b/glue-codes/openfast/CMakeLists.txt index 6bf9914d02..f4e4e4485a 100644 --- a/glue-codes/openfast/CMakeLists.txt +++ b/glue-codes/openfast/CMakeLists.txt @@ -18,7 +18,9 @@ add_executable(openfast src/FAST_Prog.f90) target_link_libraries(openfast openfast_postlib foamfastlib) set_property(TARGET openfast PROPERTY LINKER_LANGUAGE Fortran) -if (${CMAKE_Fortran_COMPILER_ID} STREQUAL "GNU" AND ${CMAKE_Fortran_COMPILER_ID} STREQUAL "RELEASE") +string(TOUPPER ${CMAKE_Fortran_COMPILER_ID} _compiler_id) +string(TOUPPER ${CMAKE_BUILD_TYPE} _build_type) +if (${_compiler_id} STREQUAL "GNU" AND ${_build_type} STREQUAL "RELEASE") # With variable tracking enabled, the compile step frequently aborts on large modules and # restarts with this option off. Disabling in Release mode avoids this problem when compiling with # full optimizations, but leaves it enabled for RelWithDebInfo which adds both -O2 and -g flags. diff --git a/glue-codes/simulink/src/FAST_SFunc.c b/glue-codes/simulink/src/FAST_SFunc.c index 7f60897e47..f2cc1a6131 100644 --- a/glue-codes/simulink/src/FAST_SFunc.c +++ b/glue-codes/simulink/src/FAST_SFunc.c @@ -51,6 +51,8 @@ static int NumAddInputs = 0; // number of additional inputs static int NumOutputs = 1; static int ErrStat = 0; static char ErrMsg[INTERFACE_STRING_LENGTH]; // make sure this is the same size as IntfStrLen in FAST_Library.f90 +static int ErrStat2 = 0; +static char ErrMsg2[INTERFACE_STRING_LENGTH]; // make sure this is the same size as IntfStrLen in FAST_Library.f90 static char InputFileName[INTERFACE_STRING_LENGTH]; // make sure this is the same size as IntfStrLen in FAST_Library.f90 static int n_t_global = -2; // counter to determine which fixed-step simulation time we are at currently (start at -2 for initialization) static int AbortErrLev = ErrID_Fatal; // abort error level; compare with NWTC Library @@ -448,8 +450,10 @@ static void mdlTerminate(SimStruct *S) FAST_End(&iTurb, &tr); n_t_global = -2; } - FAST_DeallocateTurbines(&ErrStat, ErrMsg); - + FAST_DeallocateTurbines(&ErrStat2, ErrMsg2); + if (ErrStat2 != ErrID_None){ + ssPrintf("\n%s\n", ErrMsg2); + } } diff --git a/modules/aerodyn/src/AeroDyn.f90 b/modules/aerodyn/src/AeroDyn.f90 index 8ca53c7fae..b49447d26b 100644 --- a/modules/aerodyn/src/AeroDyn.f90 +++ b/modules/aerodyn/src/AeroDyn.f90 @@ -225,9 +225,12 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut integer(IntKi) :: errStat2 ! temporary error status of the operation character(ErrMsgLen) :: errMsg2 ! temporary error message - type(AD_InputFile) :: InputFileData ! Data stored in the module's input file + type(FileInfoType) :: FileInfo_In !< The derived type for holding the full input file for parsing -- we may pass this in the future + type(AD_InputFile) :: InputFileData ! Data stored in the module's input file after parsing + character(1024) :: PriPath !< Primary path + character(1024) :: EchoFileName integer(IntKi) :: UnEcho ! Unit number for the echo file - + character(*), parameter :: RoutineName = 'AD_Init' @@ -245,27 +248,46 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut call DispNVD( AD_Ver ) - - p%NumBlades = InitInp%NumBlades ! need this before reading the AD input file so that we know how many blade files to read - !bjj: note that we haven't validated p%NumBlades before using it below! + + ! set a few parameters needed while reading the input file + call ValidateNumBlades( InitInp%NumBlades, ErrStat2, ErrMsg2 ) + if (Failed()) return; + p%NumBlades = InitInp%NumBlades p%RootName = TRIM(InitInp%RootName)//'.AD' - - ! Read the primary AeroDyn input file - call ReadInputFiles( InitInp%InputFile, InputFileData, interval, p%RootName, p%NumBlades, UnEcho, ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if (ErrStat >= AbortErrLev) then - call Cleanup() - return - end if - - + + CALL GetPath( InitInp%InputFile, PriPath ) ! Input files will be relative to the path where the primary input file is located. + + ! ----------------------------------------------------------------- + ! Read the primary AeroDyn input file, or copy from passed input + if (InitInp%UsePrimaryInputFile) then + ! Read the entire input file, minus any comment lines, into the FileInfo_In + ! data structure in memory for further processing. + call ProcessComFile( InitInp%InputFile, FileInfo_In, ErrStat2, ErrMsg2 ) + else + call NWTC_Library_CopyFileInfoType( InitInp%PassedPrimaryInputData, FileInfo_In, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) + endif + if (Failed()) return; + + + ! For diagnostic purposes, the following can be used to display the contents + ! of the FileInfo_In data structure. + ! call Print_FileInfo_Struct( CU, FileInfo_In ) ! CU is the screen -- different number on different systems. + + ! Parse the FileInfo_In structure of data from the inputfile into the InitInp%InputFile structure + CALL ParsePrimaryFileInfo( PriPath, InitInp%InputFile, p%RootName, p%NumBlades, interval, FileInfo_In, InputFileData, UnEcho, ErrStat2, ErrMsg2 ) + if (Failed()) return; + + + ! ----------------------------------------------------------------- + ! Read the AeroDyn blade files, or copy from passed input +!FIXME: add handling for passing of blade files and other types of files. + call ReadInputFiles( InitInp%InputFile, InputFileData, interval, p%RootName, p%NumBlades, UnEcho, ErrStat2, ErrMsg2 ) + if (Failed()) return; + + ! Validate the inputs call ValidateInputData( InitInp, InputFileData, p%NumBlades, ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if (ErrStat >= AbortErrLev) then - call Cleanup() - return - end if + if (Failed()) return; !............................................................................................ ! Define parameters @@ -273,33 +295,20 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut ! Initialize AFI module (read Airfoil tables) call Init_AFIparams( InputFileData, p%AFI, UnEcho, p%NumBlades, ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if (ErrStat >= AbortErrLev) then - call Cleanup() - return - end if + if (Failed()) return; ! set the rest of the parameters call SetParameters( InitInp, InputFileData, p, ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if (ErrStat >= AbortErrLev) then - call Cleanup() - return - end if + if (Failed()) return; !............................................................................................ ! Define and initialize inputs here !............................................................................................ call Init_u( u, p, InputFileData, InitInp, errStat2, errMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if (ErrStat >= AbortErrLev) then - call Cleanup() - return - end if + if (Failed()) return; - ! !............................................................................................ ! Initialize the BEMT module (also sets other variables for sub module) @@ -311,11 +320,7 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut if (p%WakeMod /= WakeMod_FVW) then call Init_BEMTmodule( InputFileData, u, m%BEMT_u(1), p, x%BEMT, xd%BEMT, z%BEMT, & OtherState%BEMT, m%BEMT_y, m%BEMT, ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if (ErrStat >= AbortErrLev) then - call Cleanup() - return - end if + if (Failed()) return; call BEMT_CopyInput( m%BEMT_u(1), m%BEMT_u(2), MESH_NEWCOPY, ErrStat2, ErrMsg2 ) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -326,7 +331,7 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut !............................................................................................ if (p%CompAA) then call Init_AAmodule( InitInp, InputFileData, u, m%AA_u, p, x%AA, xd%AA, z%AA, OtherState%AA, m%AA_y, m%AA, ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (Failed()) return; end if endif @@ -341,15 +346,11 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut if (.not. allocated(m%FVW_u)) Allocate(m%FVW_u(3)) !size(u))) call Init_FVWmodule( InputFileData, u, m%FVW_u(1), p, x%FVW, xd%FVW, z%FVW, & OtherState%FVW, m%FVW_y, m%FVW, ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if (ErrStat >= AbortErrLev) then - call Cleanup() - return - end if + if (Failed()) return; ! populate the rest of the FVW_u so that extrap-interp will work do i=2,3 !size(u) call FVW_CopyInput( m%FVW_u(1), m%FVW_u(i), MESH_NEWCOPY, ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (Failed()) return; enddo endif @@ -358,11 +359,7 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut ! Define outputs here !............................................................................................ call Init_y(y, u, p, errStat2, errMsg2) ! do this after input meshes have been initialized - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if (ErrStat >= AbortErrLev) then - call Cleanup() - return - end if + if (Failed()) return; !............................................................................................ @@ -372,20 +369,20 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut ! many states are in the BEMT module, which were initialized in BEMT_Init() call Init_MiscVars(m, p, u, y, errStat2, errMsg2) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (Failed()) return; !............................................................................................ ! Initialize other states !............................................................................................ ! The wake from FVW is stored in other states. This may not be the best place to put it! call Init_OtherStates(m, p, OtherState, errStat2, errMsg2) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (Failed()) return; !............................................................................................ ! Define initialization output here !............................................................................................ call AD_SetInitOut(p, InputFileData, InitOut, errStat2, errMsg2) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (Failed()) return; ! after setting InitOut variables, we really don't need the airfoil coordinates taking up ! space in AeroDyn @@ -401,7 +398,7 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut !............................................................................................ if (InitInp%Linearize) then call Init_Jacobian(InputFileData, p, u, y, m, InitOut, ErrStat2, ErrMsg2) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (Failed()) return; end if !............................................................................................ @@ -409,7 +406,7 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut !............................................................................................ if (InputFileData%SumPrint) then call AD_PrintSum( InputFileData, p, u, y, ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (Failed()) return; end if !............................................................................................ @@ -423,11 +420,14 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut call Cleanup() contains + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + if (Failed) call Cleanup() + end function Failed subroutine Cleanup() - CALL AD_DestroyInputFile( InputFileData, ErrStat2, ErrMsg2 ) IF ( UnEcho > 0 ) CLOSE( UnEcho ) - end subroutine Cleanup end subroutine AD_Init @@ -517,7 +517,7 @@ subroutine Init_MiscVars(m, p, u, y, errStat, errMsg) call AllocAry( m%Y_Twr, p%NumTwrNds, 'm%Y_Twr', ErrStat2, ErrMsg2 ) call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) ! save blade calculations for output: -if (p%TwrPotent /= TwrPotent_none .or. p%TwrShadow) then +if (p%TwrPotent /= TwrPotent_none .or. p%TwrShadow /= TwrShadow_none) then call AllocAry( m%TwrClrnc, p%NumBlNds, p%NumBlades, 'm%TwrClrnc', ErrStat2, ErrMsg2 ) call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) end if @@ -940,15 +940,17 @@ subroutine SetParameters( InitInp, InputFileData, p, ErrStat, ErrMsg ) p%CompAA = InputFileData%CompAA - ! p%numBlades = InitInp%numBlades ! this was set earlier because it was necessary + ! NOTE: In the following we use InputFileData%BladeProps(1)%NumBlNds as the number of aero nodes on EACH blade, + ! but if AD changes this, then it must be handled in the Glue-code linearization code, too (and elsewhere?) ! p%NumBlNds = InputFileData%BladeProps(1)%NumBlNds - if (p%TwrPotent == TwrPotent_none .and. .not. p%TwrShadow .and. .not. p%TwrAero) then + if (p%TwrPotent == TwrPotent_none .and. p%TwrShadow == TwrShadow_none .and. .not. p%TwrAero) then p%NumTwrNds = 0 else p%NumTwrNds = InputFileData%NumTwrNds call move_alloc( InputFileData%TwrDiam, p%TwrDiam ) call move_alloc( InputFileData%TwrCd, p%TwrCd ) + call move_alloc( InputFileData%TwrTI, p%TwrTI ) end if p%AirDens = InputFileData%AirDens @@ -1398,7 +1400,7 @@ subroutine SetInputs(p, u, m, indx, errStat, errMsg) ErrStat = ErrID_None ErrMsg = "" - if (p%TwrPotent /= TwrPotent_none .or. p%TwrShadow) then + if (p%TwrPotent /= TwrPotent_none .or. p%TwrShadow /= TwrShadow_none) then call TwrInfl( p, u, m, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) else @@ -1692,7 +1694,7 @@ subroutine SetInputsForFVW(p, u, m, errStat, errMsg) m%FVW_u(tIndx)%V_wind = u(tIndx)%InflowWakeVel ! Applying tower shadow to V_wind based on r_wind positions ! NOTE: m%DisturbedInflow also contains tower shadow and we need it for CalcOutput - if (p%TwrPotent /= TwrPotent_none .or. p%TwrShadow) then + if (p%TwrPotent /= TwrPotent_none .or. p%TwrShadow /= TwrShadow_none) then if (p%FVW%TwrShadowOnWake) then call TwrInflArray( p, u(tIndx), m, m%FVW%r_wind, m%FVW_u(tIndx)%V_wind, ErrStat, ErrMsg ) if (ErrStat >= AbortErrLev) return @@ -1921,6 +1923,16 @@ subroutine SetOutputsFromFVW(u, p, OtherState, x, xd, m, y, ErrStat, ErrMsg) end subroutine SetOutputsFromFVW !---------------------------------------------------------------------------------------------------------------------------------- !> This routine validates the inputs from the AeroDyn input files. +SUBROUTINE ValidateNumBlades( NumBl, ErrStat, ErrMsg ) + integer(IntKi), intent(in) :: NumBl !< Number of blades + integer(IntKi), intent(out) :: ErrStat !< Error status + character(*), intent(out) :: ErrMsg !< Error message + ErrStat = ErrID_None + ErrMsg = '' + if (NumBl > MaxBl .or. NumBl < 1) call SetErrStat( ErrID_Fatal, 'Number of blades must be between 1 and '//trim(num2lstr(MaxBl))//'.', ErrStat, ErrMsg, 'ValidateNumBlades' ) +END SUBROUTINE ValidateNumBlades +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine validates the inputs from the AeroDyn input files. SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) !.................................................................................................................................. @@ -1942,7 +1954,6 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) ErrMsg = "" - if (NumBl > MaxBl .or. NumBl < 1) call SetErrStat( ErrID_Fatal, 'Number of blades must be between 1 and '//trim(num2lstr(MaxBl))//'.', ErrSTat, ErrMsg, RoutineName ) if (InputFileData%DTAero <= 0.0) call SetErrStat ( ErrID_Fatal, 'DTAero must be greater than zero.', ErrStat, ErrMsg, RoutineName ) if (InputFileData%WakeMod /= WakeMod_None .and. InputFileData%WakeMod /= WakeMod_BEMT .and. InputFileData%WakeMod /= WakeMod_DBEMT .and. InputFileData%WakeMod /= WakeMod_FVW) then call SetErrStat ( ErrID_Fatal, 'WakeMod must be '//trim(num2lstr(WakeMod_None))//' (none), '//trim(num2lstr(WakeMod_BEMT))//' (BEMT), '// & @@ -1956,6 +1967,29 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) if (InputFileData%TwrPotent /= TwrPotent_none .and. InputFileData%TwrPotent /= TwrPotent_baseline .and. InputFileData%TwrPotent /= TwrPotent_Bak) then call SetErrStat ( ErrID_Fatal, 'TwrPotent must be 0 (none), 1 (baseline potential flow), or 2 (potential flow with Bak correction).', ErrStat, ErrMsg, RoutineName ) end if + if (InputFileData%TwrShadow /= TwrShadow_none .and. InputFileData%TwrShadow /= TwrShadow_Powles .and. InputFileData%TwrShadow /= TwrShadow_Eames) then + call SetErrStat ( ErrID_Fatal, 'TwrShadow must be 0 (none), 1 (Powles tower shadow modle), or 2 (Eames tower shadow model).', ErrStat, ErrMsg, RoutineName ) + end if + + ! The following limits are recommended by Juliet Simpson (University of Virginia) + ! E-mail recommendation: + ! To test the limits of the model, I've been running steady simulations + ! with a range of TI inputs. It looks like the model starts to break down + ! (or at least break the trend of higher TI's) when the TI drops below + ! 0.05. On the other end, the model seems to work up to TI~1 without + ! breaking down (I checked up to TI=0.99). However, the results aren't + ! very physically realistic after ~0.35 because it approaches a constant + ! velocity deficit across the rotor plane, rather than returning to zero + ! deficit a short distance laterally from the tower. I'm not sure what + ! the goal of the limits would be, so it's hard for me to say what the + ! upper cut off should be. If you want it to be physical, perhaps a low + ! cut off (around 0.4?). If you want it to just not break, and let people + ! interpret for themselves if it's physical for their scenario, then it + ! could go to TI~1. I'd recommend imposing limits of 0.05= 1.0) call SetErrStat ( ErrID_Fatal, 'The turbulence intensity for the Eames tower shadow model must be greater than 0.05 and less than 1.', ErrStat, ErrMsg, RoutineName ) + if ( maxval(InputFileData%TwrTI) > 0.4 .and. maxval(InputFileData%TwrTI) < 1.0) call SetErrStat ( ErrID_Warn, 'The turbulence intensity for the Eames tower shadow model above 0.4 may return unphysical results. Interpret with caution.', ErrStat, ErrMsg, RoutineName ) + endif if (InputFileData%AirDens <= 0.0) call SetErrStat ( ErrID_Fatal, 'The air density (AirDens) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) if (InputFileData%KinVisc <= 0.0) call SetErrStat ( ErrID_Fatal, 'The kinesmatic viscosity (KinVisc) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) @@ -2033,7 +2067,7 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) ! ............................. ! check tower mesh data: ! ............................. - if (InputFileData%TwrPotent /= TwrPotent_none .or. InputFileData%TwrShadow .or. InputFileData%TwrAero ) then + if (InputFileData%TwrPotent /= TwrPotent_none .or. InputFileData%TwrShadow /= TwrShadow_none .or. InputFileData%TwrAero ) then if (InputFileData%NumTwrNds < 2) call SetErrStat( ErrID_Fatal, 'There must be at least two nodes on the tower.',ErrStat, ErrMsg, RoutineName ) @@ -2154,6 +2188,7 @@ SUBROUTINE Init_AFIparams( InputFileData, p_AFI, UnEc, NumBl, ErrStat, ErrMsg ) AFI_InitInputs%InCol_Cl = InputFileData%InCol_Cl AFI_InitInputs%InCol_Cd = InputFileData%InCol_Cd AFI_InitInputs%InCol_Cm = InputFileData%InCol_Cm + IF (.not. InputFileData%UseBlCm) AFI_InitInputs%InCol_Cm = 0 ! Don't try to use Cm if flag set to false AFI_InitInputs%InCol_Cpmin = InputFileData%InCol_Cpmin AFI_InitInputs%AFTabMod = InputFileData%AFTabMod !AFITable_1 @@ -2720,6 +2755,7 @@ SUBROUTINE TwrInfl( p, u, m, ErrStat, ErrMsg ) real(ReKi) :: zbar ! local z^ component of r_TowerBlade (distance from tower to blade) normalized by tower radius real(ReKi) :: theta_tower_trans(3,3) ! transpose of local tower orientation expressed as a DCM real(ReKi) :: TwrCd ! local tower drag coefficient + real(ReKi) :: TwrTI ! local tower TI (for Eames tower shadow model) real(ReKi) :: W_tower ! local relative wind speed normal to the tower real(ReKi) :: BladeNodePosition(3) ! local blade node position @@ -2730,6 +2766,7 @@ SUBROUTINE TwrInfl( p, u, m, ErrStat, ErrMsg ) real(ReKi) :: v_TwrPotent ! transverse velocity deficit fraction from tower potential flow real(ReKi) :: denom ! denominator + real(ReKi) :: exponential ! exponential term real(ReKi) :: v(3) ! temp vector integer(IntKi) :: j, k ! loop counters for elements, blades @@ -2755,7 +2792,7 @@ SUBROUTINE TwrInfl( p, u, m, ErrStat, ErrMsg ) BladeNodePosition = u%BladeMotion(k)%Position(:,j) + u%BladeMotion(k)%TranslationDisp(:,j) - call getLocalTowerProps(p, u, BladeNodePosition, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, m%TwrClrnc(j,k), ErrStat2, ErrMsg2) + call getLocalTowerProps(p, u, BladeNodePosition, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrTI, m%TwrClrnc(j,k), ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) if (ErrStat >= AbortErrLev) return @@ -2787,16 +2824,22 @@ SUBROUTINE TwrInfl( p, u, m, ErrStat, ErrMsg ) v_TwrPotent = 0.0_ReKi end if - if ( p%TwrShadow .and. xbar > 0.0_ReKi .and. abs(zbar) < 1.0_ReKi) then - denom = sqrt( sqrt( xbar**2 + ybar**2 ) ) - if ( abs(ybar) < denom ) then - u_TwrShadow = -TwrCd / denom * cos( PiBy2*ybar / denom )**2 - else - u_TwrShadow = 0.0_ReKi - end if - else - u_TwrShadow = 0.0_ReKi - end if + u_TwrShadow = 0.0_ReKi + select case (p%TwrShadow) + case (TwrShadow_Powles) + if ( xbar > 0.0_ReKi .and. abs(zbar) < 1.0_ReKi) then + denom = sqrt( sqrt( xbar**2 + ybar**2 ) ) + if ( abs(ybar) < denom ) then + u_TwrShadow = -TwrCd / denom * cos( PiBy2*ybar / denom )**2 + end if + end if + case (TwrShadow_Eames) + if ( xbar > 0.0_ReKi .and. abs(zbar) < 1.0_ReKi) then + exponential = ( ybar / (TwrTI * xbar) )**2 + denom = TwrTI * xbar * sqrt( TwoPi ) + u_TwrShadow = -TwrCd / denom * exp ( -0.5_ReKi * exponential ) + end if + end select v(1) = (u_TwrPotent + u_TwrShadow)*W_tower v(2) = v_TwrPotent*W_tower @@ -2827,12 +2870,14 @@ SUBROUTINE TwrInflArray( p, u, m, Positions, Inflow, ErrStat, ErrMsg ) real(ReKi) :: zbar ! local z^ component of r_TowerBlade (distance from tower to blade) normalized by tower radius real(ReKi) :: theta_tower_trans(3,3) ! transpose of local tower orientation expressed as a DCM real(ReKi) :: TwrCd ! local tower drag coefficient + real(ReKi) :: TwrTI ! local tower TI (for Eames tower shadow model) real(ReKi) :: W_tower ! local relative wind speed normal to the tower real(ReKi) :: Pos(3) ! current point real(ReKi) :: u_TwrShadow ! axial velocity deficit fraction from tower shadow real(ReKi) :: u_TwrPotent ! axial velocity deficit fraction from tower potential flow real(ReKi) :: v_TwrPotent ! transverse velocity deficit fraction from tower potential flow real(ReKi) :: denom ! denominator + real(ReKi) :: exponential ! exponential term real(ReKi) :: v(3) ! temp vector integer(IntKi) :: i ! loop counters for points real(ReKi) :: TwrClrnc ! local tower clearance @@ -2849,17 +2894,17 @@ SUBROUTINE TwrInflArray( p, u, m, Positions, Inflow, ErrStat, ErrMsg ) call CheckTwrInfl( u, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); if (ErrStat >= AbortErrLev) return !$OMP PARALLEL default(shared) - !$OMP do private(i,Pos,r_TowerBlade,theta_tower_trans,W_tower,xbar,ybar,zbar,TwrCd,TwrClrnc,TwrDiam,found,denom,u_TwrPotent,v_TwrPotent,u_TwrShadow,v) schedule(runtime) + !$OMP do private(i,Pos,r_TowerBlade,theta_tower_trans,W_tower,xbar,ybar,zbar,TwrCd,TwrTI,TwrClrnc,TwrDiam,found,denom,u_TwrPotent,v_TwrPotent,u_TwrShadow,v) schedule(runtime) do i = 1, size(Positions,2) Pos=Positions(1:3,i) ! Find nearest line2 element or node of the tower (see getLocalTowerProps) ! values are found for the deflected tower, returning theta_tower, W_tower, xbar, ybar, zbar, and TowerCd: ! option 1: nearest line2 element - call TwrInfl_NearestLine2Element(p, u, Pos, r_TowerBlade, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrDiam, found) + call TwrInfl_NearestLine2Element(p, u, Pos, r_TowerBlade, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrTI, TwrDiam, found) if ( .not. found) then ! option 2: nearest node - call TwrInfl_NearestPoint(p, u, Pos, r_TowerBlade, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrDiam) + call TwrInfl_NearestPoint(p, u, Pos, r_TowerBlade, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrTI, TwrDiam) end if TwrClrnc = TwoNorm(r_TowerBlade) - 0.5_ReKi*TwrDiam @@ -2892,16 +2937,22 @@ SUBROUTINE TwrInflArray( p, u, m, Positions, Inflow, ErrStat, ErrMsg ) v_TwrPotent = 0.0_ReKi end if - if ( p%TwrShadow .and. xbar > 0.0_ReKi .and. abs(zbar) < 1.0_ReKi) then - denom = sqrt( sqrt( xbar**2 + ybar**2 ) ) - if ( abs(ybar) < denom ) then - u_TwrShadow = -TwrCd / denom * cos( PiBy2*ybar / denom )**2 - else - u_TwrShadow = 0.0_ReKi - end if - else - u_TwrShadow = 0.0_ReKi - end if + u_TwrShadow = 0.0_ReKi + select case (p%TwrShadow) + case (TwrShadow_Powles) + if ( xbar > 0.0_ReKi .and. abs(zbar) < 1.0_ReKi) then + denom = sqrt( sqrt( xbar**2 + ybar**2 ) ) + if ( abs(ybar) < denom ) then + u_TwrShadow = -TwrCd / denom * cos( PiBy2*ybar / denom )**2 + end if + end if + case (TwrShadow_Eames) + if ( xbar > 0.0_ReKi .and. abs(zbar) < 1.0_ReKi) then + exponential = ( ybar / (TwrTI * xbar) )**2 + denom = TwrTI * xbar * sqrt( TwoPi ) + u_TwrShadow = -TwrCd / denom * exp ( -0.5_ReKi * exponential ) + end if + end select v(1) = (u_TwrPotent + u_TwrShadow)*W_tower v(2) = v_TwrPotent*W_tower @@ -2916,7 +2967,7 @@ END SUBROUTINE TwrInflArray !---------------------------------------------------------------------------------------------------------------------------------- !> This routine returns the tower constants necessary to compute the tower influence. !! if u%TowerMotion does not have any nodes there will be serious problems. I assume that has been checked earlier. -SUBROUTINE getLocalTowerProps(p, u, BladeNodePosition, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrClrnc, ErrStat, ErrMsg) +SUBROUTINE getLocalTowerProps(p, u, BladeNodePosition, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrTI, TwrClrnc, ErrStat, ErrMsg) !.................................................................................................................................. TYPE(AD_InputType), INTENT(IN ) :: u !< Inputs at Time t TYPE(AD_ParameterType), INTENT(IN ) :: p !< Parameters @@ -2927,6 +2978,7 @@ SUBROUTINE getLocalTowerProps(p, u, BladeNodePosition, theta_tower_trans, W_towe REAL(ReKi) ,INTENT( OUT) :: ybar !< local y^ component of r_TowerBlade normalized by tower radius REAL(ReKi) ,INTENT( OUT) :: zbar !< local z^ component of r_TowerBlade normalized by tower radius REAL(ReKi) ,INTENT( OUT) :: TwrCd !< local tower drag coefficient + REAL(ReKi) ,INTENT( OUT) :: TwrTI !< local tower TI (for Eames tower shadow model) REAL(ReKi) ,INTENT( OUT) :: TwrClrnc !< tower clearance for potential output INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None @@ -2944,13 +2996,13 @@ SUBROUTINE getLocalTowerProps(p, u, BladeNodePosition, theta_tower_trans, W_towe ! .............................................. ! option 1: nearest line2 element ! .............................................. - call TwrInfl_NearestLine2Element(p, u, BladeNodePosition, r_TowerBlade, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrDiam, found) + call TwrInfl_NearestLine2Element(p, u, BladeNodePosition, r_TowerBlade, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrTI, TwrDiam, found) if ( .not. found) then ! .............................................. ! option 2: nearest node ! .............................................. - call TwrInfl_NearestPoint(p, u, BladeNodePosition, r_TowerBlade, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrDiam) + call TwrInfl_NearestPoint(p, u, BladeNodePosition, r_TowerBlade, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrTI, TwrDiam) end if @@ -2967,7 +3019,7 @@ END SUBROUTINE getLocalTowerProps !! That is, for each node of the blade mesh, an orthogonal projection is made onto all possible Line2 elements of the tower mesh and !! the line2 element of the tower mesh that is the minimum distance away is found. !! Adapted from modmesh_mapping::createmapping_projecttoline2() -SUBROUTINE TwrInfl_NearestLine2Element(p, u, BladeNodePosition, r_TowerBlade, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrDiam, found) +SUBROUTINE TwrInfl_NearestLine2Element(p, u, BladeNodePosition, r_TowerBlade, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrTI, TwrDiam, found) !.................................................................................................................................. TYPE(AD_InputType), INTENT(IN ) :: u !< Inputs at Time t TYPE(AD_ParameterType), INTENT(IN ) :: p !< Parameters @@ -2979,6 +3031,7 @@ SUBROUTINE TwrInfl_NearestLine2Element(p, u, BladeNodePosition, r_TowerBlade, th REAL(ReKi) ,INTENT( OUT) :: ybar !< local y^ component of r_TowerBlade normalized by tower radius REAL(ReKi) ,INTENT( OUT) :: zbar !< local z^ component of r_TowerBlade normalized by tower radius REAL(ReKi) ,INTENT( OUT) :: TwrCd !< local tower drag coefficient + REAL(ReKi) ,INTENT( OUT) :: TwrTI !< local tower TI (Eames tower shadow model) REAL(ReKi) ,INTENT( OUT) :: TwrDiam !< local tower diameter logical ,INTENT( OUT) :: found !< whether a mapping was found with this option @@ -3060,6 +3113,7 @@ SUBROUTINE TwrInfl_NearestLine2Element(p, u, BladeNodePosition, r_TowerBlade, th TwrDiam = elem_position2*p%TwrDiam(n1) + elem_position*p%TwrDiam(n2) TwrCd = elem_position2*p%TwrCd( n1) + elem_position*p%TwrCd( n2) + TwrTI = elem_position2*p%TwrTI( n1) + elem_position*p%TwrTI( n2) ! z_hat @@ -3103,7 +3157,7 @@ END SUBROUTINE TwrInfl_NearestLine2Element !! Find the nearest-neighbor node in the tower Line2-element domain (following an approach similar to the point_to_point mapping !! search for motion and scalar quantities). That is, for each node of the blade mesh, the node of the tower mesh that is the minimum !! distance away is found. -SUBROUTINE TwrInfl_NearestPoint(p, u, BladeNodePosition, r_TowerBlade, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrDiam) +SUBROUTINE TwrInfl_NearestPoint(p, u, BladeNodePosition, r_TowerBlade, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrTI, TwrDiam) !.................................................................................................................................. TYPE(AD_InputType), INTENT(IN ) :: u !< Inputs at Time t TYPE(AD_ParameterType), INTENT(IN ) :: p !< Parameters @@ -3115,6 +3169,7 @@ SUBROUTINE TwrInfl_NearestPoint(p, u, BladeNodePosition, r_TowerBlade, theta_tow REAL(ReKi) ,INTENT( OUT) :: ybar !< local y^ component of r_TowerBlade normalized by tower radius REAL(ReKi) ,INTENT( OUT) :: zbar !< local z^ component of r_TowerBlade normalized by tower radius REAL(ReKi) ,INTENT( OUT) :: TwrCd !< local tower drag coefficient + REAL(ReKi) ,INTENT( OUT) :: TwrTI !< local tower TI (for Eeames tower shadow model) REAL(ReKi) ,INTENT( OUT) :: TwrDiam !< local tower diameter ! local variables @@ -3171,6 +3226,7 @@ SUBROUTINE TwrInfl_NearestPoint(p, u, BladeNodePosition, r_TowerBlade, theta_tow V_rel_tower = u%InflowOnTower(:,n1) - u%TowerMotion%TranslationVel(:,n1) TwrDiam = p%TwrDiam(n1) TwrCd = p%TwrCd( n1) + TwrTI = p%TwrTI( n1) ! z_hat theta_tower_trans(:,3) = u%TowerMotion%Orientation(3,:,n1) @@ -4164,7 +4220,15 @@ SUBROUTINE AD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, index = index + 1 end do end do + + do k=1,p%NumBlades + do j = 1, size(u%UserProp,1) ! Number of nodes for a blade + u_op(index) = u%UserProp(j,k) + index = index + 1 + end do + end do + END IF IF ( PRESENT( y_op ) ) THEN @@ -4459,7 +4523,8 @@ SUBROUTINE Init_Jacobian_u( InputFileData, p, u, InitOut, ErrStat, ErrMsg) nu = u%TowerMotion%NNodes * 9 & ! 3 Translation Displacements + 3 orientations + 3 Translation velocities at each node + u%hubMotion%NNodes * 9 & ! 3 Translation Displacements + 3 orientations + 3 Rotation velocities at each node + size( u%InflowOnBlade) & - + size( u%InflowOnTower) + + size( u%InflowOnTower) & + + size( u%UserProp) do i=1,p%NumBlades nu = nu + u%BladeMotion(i)%NNodes * 15 & ! 3 Translation Displacements + 3 orientations + 3 Translation velocities + 3 Rotation velocities + 3 TranslationAcc at each node @@ -4587,11 +4652,20 @@ SUBROUTINE Init_Jacobian_u( InputFileData, p, u, InitOut, ErrStat, ErrMsg) end do !j end do !i + !Module/Mesh/Field: u%UserProp(:,:) = 29,30,31; + do k=1,size(u%UserProp,2) ! p%NumBlades + do i=1,size(u%UserProp,1) ! numNodes + p%Jac_u_indx(index,1) = 28 + k + p%Jac_u_indx(index,2) = 1 !component index: this is a scalar, so 1, but is never used + p%Jac_u_indx(index,3) = i !Node: i + index = index + 1 + end do !i + end do !k !...................................... ! default perturbations, p%du: !...................................... - call allocAry( p%du, 28, 'p%du', ErrStat2, ErrMsg2) ! 28 = number of unique values in p%Jac_u_indx(:,1) + call allocAry( p%du, 31, 'p%du', ErrStat2, ErrMsg2) ! 31 = number of unique values in p%Jac_u_indx(:,1) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) perturb = 2*D2R @@ -4625,9 +4699,10 @@ SUBROUTINE Init_Jacobian_u( InputFileData, p, u, InitOut, ErrStat, ErrMsg) do k=1,p%NumBlades p%du(24 + k) = perturb_b(k) ! u%InflowOnBlade(:,:,k) = 24 + k end do - p%du(28) = perturb_t ! u%InflowOnTower(:,:) = 22 - - + p%du(28) = perturb_t ! u%InflowOnTower(:,:) = 28 + do k=1,p%NumBlades + p%du(28+k) = perturb ! u%UserProp(:,:) = 29,30,31 + end do !..................... ! get names of linearized inputs !..................... @@ -4641,7 +4716,9 @@ SUBROUTINE Init_Jacobian_u( InputFileData, p, u, InitOut, ErrStat, ErrMsg) InitOut%IsLoad_u = .false. ! None of AeroDyn's inputs are loads InitOut%RotFrame_u = .false. - + do k=0,p%NumBlades*p%NumBlNds-1 + InitOut%RotFrame_u(nu - k ) = .true. ! UserProp(:,:) + end do index = 1 FieldMask = .false. FieldMask(MASKID_TRANSLATIONDISP) = .true. @@ -4903,7 +4980,12 @@ SUBROUTINE Perturb_u( p, n, perturb_sign, u, du ) CASE (28) !Module/Mesh/Field: u%InflowOnTower(:,:) = 28; u%InflowOnTower(fieldIndx,node) = u%InflowOnTower(fieldIndx,node) + du * perturb_sign - + CASE (29) !Module/Mesh/Field: u%UserProp(:,1) = 29; + u%UserProp(node,1) = u%UserProp(node,1) + du * perturb_sign + CASE (30) !Module/Mesh/Field: u%UserProp(:,2) = 30; + u%UserProp(node,2) = u%UserProp(node,2) + du * perturb_sign + CASE (31) !Module/Mesh/Field: u%UserProp(:,3) = 31; + u%UserProp(node,3) = u%UserProp(node,3) + du * perturb_sign END SELECT END SUBROUTINE Perturb_u diff --git a/modules/aerodyn/src/AeroDyn_IO.f90 b/modules/aerodyn/src/AeroDyn_IO.f90 index 90465ed21e..f66e3a93df 100644 --- a/modules/aerodyn/src/AeroDyn_IO.f90 +++ b/modules/aerodyn/src/AeroDyn_IO.f90 @@ -1636,7 +1636,7 @@ SUBROUTINE Calc_WriteOutput( p, u, m, y, OtherState, xd, indx, ErrStat, ErrMsg ) endif ! blade node tower clearance (requires tower influence calculation): - if (p%TwrPotent /= TwrPotent_none .or. p%TwrShadow) then + if (p%TwrPotent /= TwrPotent_none .or. p%TwrShadow /= TwrShadow_none) then do k=1,p%numBlades do beta=1,p%NBlOuts j=p%BlOutNd(beta) @@ -1915,7 +1915,7 @@ SUBROUTINE ReadInputFiles( InputFileName, InputFileData, Default_DT, OutFileRoot CHARACTER(*), INTENT(IN) :: InputFileName ! Name of the input file CHARACTER(*), INTENT(IN) :: OutFileRoot ! The rootname of all the output files written by this routine. - TYPE(AD_InputFile), INTENT(OUT) :: InputFileData ! Data stored in the module's input file + TYPE(AD_InputFile), INTENT(INOUT) :: InputFileData ! Data stored in the module's input file INTEGER(IntKi), INTENT(OUT) :: UnEcho ! Unit number for the echo file INTEGER(IntKi), INTENT(IN) :: NumBlades ! Number of blades for this model @@ -1939,16 +1939,6 @@ SUBROUTINE ReadInputFiles( InputFileName, InputFileData, Default_DT, OutFileRoot UnEcho = -1 InputFileData%DTAero = Default_DT ! the glue code's suggested DT for the module (may be overwritten in ReadPrimaryFile()) - ! get the primary/platform input-file data - ! sets UnEcho, ADBlFile - - CALL ReadPrimaryFile( InputFileName, InputFileData, ADBlFile, OutFileRoot, UnEcho, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - ! get the blade input-file data @@ -1959,8 +1949,9 @@ SUBROUTINE ReadInputFiles( InputFileName, InputFileData, Default_DT, OutFileRoot RETURN END IF +!FIXME: add options for passing the blade files. This routine will need restructuring to handle that. DO I=1,NumBlades - CALL ReadBladeInputs ( ADBlFile(I), InputFileData%BladeProps(I), UnEcho, ErrStat2, ErrMsg2 ) + CALL ReadBladeInputs ( InputFileData%ADBlFile(I), InputFileData%BladeProps(I), UnEcho, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName//TRIM(':Blade')//TRIM(Num2LStr(I))) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -1985,621 +1976,357 @@ END SUBROUTINE Cleanup END SUBROUTINE ReadInputFiles !---------------------------------------------------------------------------------------------------------------------------------- -SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnEc, ErrStat, ErrMsg ) -! This routine reads in the primary AeroDyn input file and places the values it reads in the InputFileData structure. -! It opens and prints to an echo file if requested. -!.................................................................................................................................. - - - implicit none +!> This routine parses the input file data stored in FileInfo_In and places it in the InputFileData structure for validating. +SUBROUTINE ParsePrimaryFileInfo( PriPath, InputFile, RootName, NumBlades, interval, FileInfo_In, InputFileData, UnEc, ErrStat, ErrMsg ) + implicit none ! Passed variables - integer(IntKi), intent(out) :: UnEc ! I/O unit for echo file. If > 0, file is open for writing. - integer(IntKi), intent(out) :: ErrStat ! Error status - - character(*), intent(out) :: ADBlFile(MaxBl) ! name of the files containing blade inputs - character(*), intent(in) :: InputFile ! Name of the file containing the primary input data - character(*), intent(out) :: ErrMsg ! Error message - character(*), intent(in) :: OutFileRoot ! The rootname of the echo file, possibly opened in this routine + character(*), intent(in ) :: PriPath !< primary path + CHARACTER(*), intent(in ) :: InputFile !< Name of the file containing the primary input data + CHARACTER(*), intent(in ) :: RootName !< The rootname of the echo file, possibly opened in this routine + integer(IntKi), intent(in ) :: NumBlades !< Number of blades we expect -- from InitInp + real(DBKi), intent(in ) :: interval !< timestep + type(AD_InputFile), intent(inout) :: InputFileData !< All the data in the AD15 primary input file + type(FileInfoType), intent(in ) :: FileInfo_In !< The derived type for holding the file information. + integer(IntKi), intent( out) :: UnEc !< The local unit number for this module's echo file + integer(IntKi), intent( out) :: ErrStat !< Error status + CHARACTER(ErrMsgLen), intent( out) :: ErrMsg !< Error message - type(AD_InputFile), intent(inout) :: InputFileData ! All the data in the AeroDyn input file - ! Local variables: - real(ReKi) :: TmpAry(3) ! array to help read tower properties table - integer(IntKi) :: I ! loop counter - integer(IntKi) :: UnIn ! Unit number for reading file - - integer(IntKi) :: ErrStat2, IOS ! Temporary Error status - logical :: Echo ! Determines if an echo file should be written - character(ErrMsgLen) :: ErrMsg2 ! Temporary Error message - character(ErrMsgLen) :: ErrMsg_NoAllBldNdOuts ! Temporary Error message - character(1024) :: PriPath ! Path name of the primary file - character(1024) :: FTitle ! "File Title": the 2nd line of the input file, which contains a description of its contents - character(200) :: Line ! Temporary storage of a line from the input file (to compare with "default") - character(*), parameter :: RoutineName = 'ReadPrimaryFile' - - - ! Initialize some variables: - ErrStat = ErrID_None - ErrMsg = "" - - UnEc = -1 - Echo = .FALSE. - CALL GetPath( InputFile, PriPath ) ! Input files will be relative to the path where the primary input file is located. - - - CALL AllocAry( InputFileData%OutList, MaxOutPts, "Outlist", ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! Allocate array for holding the list of node outputs - CALL AllocAry( InputFileData%BldNd_OutList, BldNd_MaxOutPts, "BldNd_Outlist", ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! Get an available unit number for the file. - - CALL GetNewUnit( UnIn, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! Open the Primary input file. - - CALL OpenFInpFile ( UnIn, InputFile, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - - ! Read the lines up/including to the "Echo" simulation control variable - ! If echo is FALSE, don't write these lines to the echo file. - ! If Echo is TRUE, rewind and write on the second try. - - I = 1 !set the number of times we've read the file - DO - !----------- HEADER ------------------------------------------------------------- - - CALL ReadCom( UnIn, InputFile, 'File header: Module Version (line 1)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ReadStr( UnIn, InputFile, FTitle, 'FTitle', 'File Header: File Description (line 2)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - !----------- GENERAL OPTIONS ---------------------------------------------------- - - CALL ReadCom( UnIn, InputFile, 'Section Header: General Options', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! Echo - Echo input to ".AD.ech". - - CALL ReadVar( UnIn, InputFile, Echo, 'Echo', 'Echo flag', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - - IF (.NOT. Echo .OR. I > 1) EXIT !exit this loop - - ! Otherwise, open the echo file, then rewind the input file and echo everything we've read - - I = I + 1 ! make sure we do this only once (increment counter that says how many times we've read this file) - - CALL OpenEcho ( UnEc, TRIM(OutFileRoot)//'.ech', ErrStat2, ErrMsg2, AD_Ver ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - IF ( UnEc > 0 ) WRITE (UnEc,'(/,A,/)') 'Data from '//TRIM(AD_Ver%Name)//' primary input file "'//TRIM( InputFile )//'":' - - REWIND( UnIn, IOSTAT=ErrStat2 ) - IF (ErrStat2 /= 0_IntKi ) THEN - CALL SetErrStat( ErrID_Fatal, 'Error rewinding file "'//TRIM(InputFile)//'".', ErrStat, ErrMsg, RoutineName ) - CALL Cleanup() - RETURN - END IF - - END DO - - IF (NWTC_VerboseLevel == NWTC_Verbose) THEN - CALL WrScr( ' Heading of the '//TRIM(AD_Ver%Name)//' input file: ' ) - CALL WrScr( ' '//TRIM( FTitle ) ) - END IF - - - ! DTAero - Time interval for aerodynamic calculations {or default} (s): - Line = "" - CALL ReadVar( UnIn, InputFile, Line, "DTAero", "Time interval for aerodynamic calculations {or default} (s)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL Conv2UC( Line ) - IF ( INDEX(Line, "DEFAULT" ) /= 1 ) THEN ! If it's not "default", read this variable; otherwise use the value already stored in InputFileData%DTAero - READ( Line, *, IOSTAT=IOS) InputFileData%DTAero - CALL CheckIOS ( IOS, InputFile, 'DTAero', NumType, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - END IF - - ! WakeMod - Type of wake/induction model {0=none, 1=BEMT, 2=DBEMT, 3=FVW} (-): - CALL ReadVar( UnIn, InputFile, InputFileData%WakeMod, "WakeMod", "Type of wake/induction model {0=none, 1=BEMT, 2=DBEMT, 3=FVW} (-)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! AFAeroMod - Type of airfoil aerodynamics model {1=steady model, 2=Beddoes-Leishman unsteady model} (-): - CALL ReadVar( UnIn, InputFile, InputFileData%AFAeroMod, "AFAeroMod", "Type of airfoil aerodynamics model {1=steady model, 2=Beddoes-Leishman unsteady model} (-)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! TwrPotent - Type tower influence on wind based on potential flow around the tower {0=none, 1=baseline potential flow, 2=potential flow with Bak correction} (switch) : - CALL ReadVar( UnIn, InputFile, InputFileData%TwrPotent, "TwrPotent", "Type tower influence on wind based on potential flow around the tower {0=none, 1=baseline potential flow, 2=potential flow with Bak correction} (-)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! TwrShadow - Calculate tower influence on wind based on downstream tower shadow? (flag) : - CALL ReadVar( UnIn, InputFile, InputFileData%TwrShadow, "TwrShadow", "Calculate tower influence on wind based on downstream tower shadow? (flag)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! TwrAero - Calculate tower aerodynamic loads? (flag): - CALL ReadVar( UnIn, InputFile, InputFileData%TwrAero, "TwrAero", "Calculate tower aerodynamic loads? (flag)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! FrozenWake - Assume frozen wake during linearization? (flag): - CALL ReadVar( UnIn, InputFile, InputFileData%FrozenWake, "FrozenWake", "Assume frozen wake during linearization? (flag)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - - ! CavitCheck - Perform cavitation check? (flag): - CALL ReadVar( UnIn, InputFile, InputFileData%CavitCheck, "CavitCheck", "Perform cavitation check? (flag)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! AddedMass - Include added mass effects? (flag): -! CALL ReadVar( UnIn, InputFile, InputFileData%AddedMass, "AddedMass", "Include added mass effects? (flag)", ErrStat2, ErrMsg2, UnEc) - ! CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! CompAA - Compute AeroAcoustics? (flag): - CALL ReadVar( UnIn, InputFile, InputFileData%CompAA, "CompAA", "Compute AeroAcoustics? (flag)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! AA_Inputfile - CALL ReadVar ( UnIn, InputFile, InputFileData%AA_InputFile, "AA_Inputfile", "AeroAcoustics Input filename", ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( PathIsRelative( InputFileData%AA_InputFile ) ) InputFileData%AA_InputFile = TRIM(PriPath)//TRIM(InputFileData%AA_InputFile) - - ! Return on error at end of section - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - !----------- ENVIRONMENTAL CONDITIONS ------------------------------------------- - CALL ReadCom( UnIn, InputFile, 'Section Header: Environmental Conditions', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! AirDens - Air density (kg/m^3): - CALL ReadVar( UnIn, InputFile, InputFileData%AirDens, "AirDens", "Air density (kg/m^3)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! KinVisc - Kinematic air viscosity (m^2/s): - CALL ReadVar( UnIn, InputFile, InputFileData%KinVisc, "KinVisc", "Kinematic air viscosity (m^2/s)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! SpdSound - Speed of sound (m/s): - CALL ReadVar( UnIn, InputFile, InputFileData%SpdSound, "SpdSound", "Speed of sound (m/s)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! Patm - Atmospheric pressure (Pa): - CALL ReadVar( UnIn, InputFile, InputFileData%Patm, "Patm", "Atmospheric pressure (Pa)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - - ! Pvap - Vapour pressure of fluid (Pa): - CALL ReadVar( UnIn, InputFile, InputFileData%Pvap, "Pvap", "Vapour pressure of fluid (Pa)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! FluidDepth - Water depth above mid-hub height (m) - used for caviation check: - CALL ReadVar( UnIn, InputFile, InputFileData%FluidDepth, "FluidDepth", "Water depth above mid-hub height (MHK only, for cavitation check) (m)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - - - ! Return on error at end of section - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - !----------- BLADE-ELEMENT/MOMENTUM THEORY OPTIONS ------------------------------ - CALL ReadCom( UnIn, InputFile, 'Section Header: Blade-Element/Momentum Theory Options', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! SkewMod - Type of skewed-wake correction model {1=uncoupled, 2=Pitt/Peters, 3=coupled} (-) [unused when WakeMod={0|3}]: - CALL ReadVar( UnIn, InputFile, InputFileData%SkewMod, "SkewMod", "Type of skewed-wake correction model {1=uncoupled, 2=Pitt/Peters, 3=coupled} (-) [unused when WakeMod={0|3}]", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! SkewModFactor - Constant used in Pitt/Peters skewed wake model {or default is 15/32*pi} (-) [used only when WakeMod/={0|3} and SkewMod=2]: - Line = "" - CALL ReadVar( UnIn, InputFile, Line, "SkewModFactor", "Constant used in Pitt/Peters skewed wake model {or default} (-)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL Conv2UC( Line ) - IF ( INDEX(Line, "DEFAULT" ) /= 1 ) THEN ! If it's not "default", read this variable; otherwise use the default value 15.0_ReKi * pi / 32.0_ReKi - READ( Line, *, IOSTAT=IOS) InputFileData%SkewModFactor - CALL CheckIOS ( IOS, InputFile, 'SkewModFactor', NumType, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - ELSE - InputFileData%SkewModFactor = 15.0_ReKi * pi / 32.0_ReKi - END IF - - - ! TipLoss - Use the Prandtl tip-loss model? (flag) [unused when WakeMod={0|3}]: - CALL ReadVar( UnIn, InputFile, InputFileData%TipLoss, "TipLoss", "Use the Prandtl tip-loss model? (flag) [unused when WakeMod={0|3}]", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! HubLoss - Use the Prandtl hub-loss model? (flag) [unused when WakeMod={0|3}]: - CALL ReadVar( UnIn, InputFile, InputFileData%HubLoss, "HubLoss", "Use the Prandtl hub-loss model? (flag) [unused when WakeMod={0|3}]", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! TanInd - Include tangential induction in BEMT calculations? (flag) [unused when WakeMod={0|3}]: - CALL ReadVar( UnIn, InputFile, InputFileData%TanInd, "TanInd", "Include tangential induction in BEMT calculations? (flag) [unused when WakeMod={0|3}]", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! AIDrag - Include the drag term in the axial-induction calculation? (flag) [unused when WakeMod={0|3}]: - CALL ReadVar( UnIn, InputFile, InputFileData%AIDrag, "AIDrag", "Include the drag term in the axial-induction calculation? (flag) [unused when WakeMod={0|3}]", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! TIDrag - Include the drag term in the tangential-induction calculation? (flag) [unused when WakeMod={0|3} or TanInd=FALSE]: - CALL ReadVar( UnIn, InputFile, InputFileData%TIDrag, "TIDrag", "Include the drag term in the tangential-induction calculation? (flag) [unused when WakeMod={0|3} or TanInd=FALSE]", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! IndToler - Convergence tolerance for BEM induction factors (or "default"] (-) [unused when WakeMod={0|3}]: - Line = "" - CALL ReadVar( UnIn, InputFile, Line, "IndToler", "Convergence tolerance for BEM induction factors (-) [unused when WakeMod={0|3}]", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL Conv2UC( Line ) - IF ( INDEX(Line, "DEFAULT" ) /= 1 ) THEN ! If it's not "default", read this variable; otherwise set the value based on ReKi precision - READ( Line, *, IOSTAT=IOS) InputFileData%IndToler - CALL CheckIOS ( IOS, InputFile, 'IndToler', NumType, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - else - if (ReKi==SiKi) then - InputFileData%IndToler = 5E-5 - else - InputFileData%IndToler = 5D-10 - end if - END IF - - - ! MaxIter - Maximum number of iteration steps [unused when WakeMod={0|3}] (-): - CALL ReadVar( UnIn, InputFile, InputFileData%MaxIter, "MaxIter", "Maximum number of iteration steps (-) [unused when WakeMod={0|3}]", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! Return on error at end of section - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - !----------- DYNAMIC BLADE-ELEMENT/MOMENTUM THEORY OPTIONS ------------------------------ - CALL ReadCom( UnIn, InputFile, 'Section Header: Dynamic Blade-Element/Momentum Theory Options', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! DBEMT_Mod - Type of dynamic BEMT (DBEMT) model {1=constant tau1, 2=time-dependent tau1} (-): - CALL ReadVar( UnIn, InputFile, InputFileData%DBEMT_Mod, "DBEMT_Mod", "Type of dynamic BEMT (DBEMT) model {0=none, 1=constant tau1, 2=time-dependent tau1} (-) [used only when WakeMod=2]", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! tau1_const - time constant for DBEMT (s) [used only when WakeMod=2 and DBEMT_Mod=1]: - CALL ReadVar( UnIn, InputFile, InputFileData%tau1_const, "tau1_const", "time constant for DBEMT (s) [used only when WakeMod=2 and DBEMT_Mod=1]", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - - !----------- FREE VORTEX WAKE (FVW) THEORY OPTIONS ------------------------------ - CALL ReadCom( UnIn, InputFile, 'Section Header: Free Vortex Wake (FVW) Theory Options', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ReadVar ( UnIn, InputFile, InputFileData%FVWFileName, 'FVWFile', 'FVW input file name', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( PathIsRelative( InputFileData%FVWFileName ) ) InputFileData%FVWFileName = TRIM(PriPath)//TRIM(InputFileData%FVWFileName) + integer(IntKi) :: i !< generic counter + integer(IntKi) :: ErrStat2, IOS !< Temporary Error status + character(ErrMsgLen) :: ErrMsg2 !< Temporary Error message + character(ErrMsgLen) :: ErrMsg_NoAllBldNdOuts + integer(IntKi) :: CurLine !< current entry in FileInfo_In%Lines array + real(ReKi) :: TmpRe4(4) !< temporary 4 number array for reading values in + character(1024) :: FTitle ! "File Title": the 2nd line of the input file, which contains a description of its contents + character(*), parameter :: RoutineName = 'ParsePrimaryFileInfo' - !----------- BEDDOES-LEISHMAN UNSTEADY AIRFOIL AERODYNAMICS OPTIONS ------------- - CALL ReadCom( UnIn, InputFile, 'Section Header: Beddoes-Leishman Unsteady Airfoil Aerodynamics Options', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! UAMod - Unsteady Aero Model Switch (switch) {1=Baseline model (Original), 2=Gonzalez's variant (changes in Cn,Cc,Cm), 3=Minnema/Pierce variant (changes in Cc and Cm)} [used only when AFAreoMod=2] (-): - CALL ReadVar( UnIn, InputFile, InputFileData%UAMod, "UAMod", "Unsteady Aero Model Switch (switch) {1=Baseline model (Original), 2=Gonzalez's variant (changes in Cn,Cc,Cm), 3=Minnema/Pierce variant (changes in Cc and Cm)} [used only when AFAreoMod=2] (-)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! Initialization + ErrStat = 0 + ErrMsg = "" + UnEc = -1 ! Echo file unit. >0 when used - ! FLookup - Flag to indicate whether a lookup for f' will be calculated (TRUE) or whether best-fit exponential equations will be used (FALSE); if FALSE S1-S4 must be provided in airfoil input files [used only when AFAreoMod=2] (flag): - CALL ReadVar( UnIn, InputFile, InputFileData%FLookup, "FLookup", "Flag to indicate whether a lookup for f' will be calculated (TRUE) or whether best-fit exponential equations will be used (FALSE); if FALSE S1-S4 must be provided in airfoil input files [used only when AFAreoMod=2] (flag)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! UACutout - Angle-of-attack beyond which unsteady aerodynamics are disabled (deg) -! CALL ReadVar( UnIn, InputFile, InputFileData%UACutout, "UACutout", "Angle-of-attack beyond which unsteady aerodynamics are disabled (deg)", ErrStat2, ErrMsg2, UnEc) -! CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! Return on error at end of section - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - !----------- AIRFOIL INFORMATION ------------------------------------------------ - CALL ReadCom( UnIn, InputFile, 'Section Header: Airfoil Information', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ! AFTabMod - Interpolation method for multiple airfoil tables (-): - CALL ReadVar( UnIn, InputFile, InputFileData%AFTabMod, "AFTabMod", "Interpolation method for multiple airfoil tables (-)", ErrStat2, ErrMsg2, UnEc) + CALL AllocAry( InputFileData%OutList, MaxOutPts, "Outlist", ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - ! InCol_Alfa - The column in the airfoil tables that contains the angle of attack (-): - CALL ReadVar( UnIn, InputFile, InputFileData%InCol_Alfa, "InCol_Alfa", "The column in the airfoil tables that contains the angle of attack (-)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - ! InCol_Cl - The column in the airfoil tables that contains the lift coefficient (-): - CALL ReadVar( UnIn, InputFile, InputFileData%InCol_Cl, "InCol_Cl", "The column in the airfoil tables that contains the lift coefficient (-)", ErrStat2, ErrMsg2, UnEc) + ! Allocate array for holding the list of node outputs + CALL AllocAry( InputFileData%BldNd_OutList, BldNd_MaxOutPts, "BldNd_Outlist", ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - ! InCol_Cd - The column in the airfoil tables that contains the drag coefficient (-): - CALL ReadVar( UnIn, InputFile, InputFileData%InCol_Cd, "InCol_Cd", "The column in the airfoil tables that contains the drag coefficient (-)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - ! InCol_Cm - The column in the airfoil tables that contains the pitching-moment coefficient; use zero if there is no Cm column (-): - CALL ReadVar( UnIn, InputFile, InputFileData%InCol_Cm, "InCol_Cm", "The column in the airfoil tables that contains the pitching-moment coefficient; use zero if there is no Cm column (-)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN + !------------------------------------------------------------------------------------------------- + ! General settings + !------------------------------------------------------------------------------------------------- - ! InCol_Cpmin - The column in the airfoil tables that contains the drag coefficient; use zero if there is no Cpmin column (-): - CALL ReadVar( UnIn, InputFile, InputFileData%InCol_Cpmin, "InCol_Cpmin", "The column in the airfoil tables that contains the drag coefficient; use zero if there is no Cpmin column (-)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN + CurLine = 4 ! Skip the first three lines as they are known to be header lines and separators + call ParseVar( FileInfo_In, CurLine, 'Echo', InputFileData%Echo, ErrStat2, ErrMsg2 ) + if (Failed()) return; + + if ( InputFileData%Echo ) then + CALL OpenEcho ( UnEc, TRIM(RootName)//'.ech', ErrStat2, ErrMsg2 ) + if (Failed()) return; + WRITE(UnEc, '(A)') 'Echo file for AeroDyn 15 primary input file: '//trim(InputFile) + ! Write the first three lines into the echo file + WRITE(UnEc, '(A)') FileInfo_In%Lines(1) + WRITE(UnEc, '(A)') FileInfo_In%Lines(2) + WRITE(UnEc, '(A)') FileInfo_In%Lines(3) + + CurLine = 4 + call ParseVar( FileInfo_In, CurLine, 'Echo', InputFileData%Echo, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + endif - ! NumAFfiles - Number of airfoil files used (-): - CALL ReadVar( UnIn, InputFile, InputFileData%NumAFfiles, "NumAFfiles", "Number of airfoil files used (-)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN + ! DTAero - Time interval for aerodynamic calculations {or default} (s): + call ParseVarWDefault ( FileInfo_In, CurLine, "DTAero", InputFileData%DTAero, interval, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! WakeMod - Type of wake/induction model (switch) {0=none, 1=BEMT, 2=DBEMT, 3=OLAF} [WakeMod cannot be 2 or 3 when linearizing] + call ParseVar( FileInfo_In, CurLine, "WakeMod", InputFileData%WakeMod, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! AFAeroMod - Type of blade airfoil aerodynamics model (switch) {1=steady model, 2=Beddoes-Leishman unsteady model} [AFAeroMod must be 1 when linearizing] + call ParseVar( FileInfo_In, CurLine, "AFAeroMod", InputFileData%AFAeroMod, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! TwrPotent - Type tower influence on wind based on potential flow around the tower (switch) {0=none, 1=baseline potential flow, 2=potential flow with Bak correction} + call ParseVar( FileInfo_In, CurLine, "TwrPotent", InputFileData%TwrPotent, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! TwrShadow - Calculate tower influence on wind based on downstream tower shadow {0=none, 1=Powles model, 2=Eames model} + call ParseVar( FileInfo_In, CurLine, "TwrShadow", InputFileData%TwrShadow, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! TwrAero - Calculate tower aerodynamic loads? (flag) + call ParseVar( FileInfo_In, CurLine, "TwrAero", InputFileData%TwrAero, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! FrozenWake - Assume frozen wake during linearization? (flag) [used only when WakeMod=1 and when linearizing] + call ParseVar( FileInfo_In, CurLine, "FrozenWake", InputFileData%FrozenWake, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! CavitCheck - Perform cavitation check? (flag) [AFAeroMod must be 1 when CavitCheck=true] + call ParseVar( FileInfo_In, CurLine, "CavitCheck", InputFileData%CavitCheck, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! CompAA - Flag to compute AeroAcoustics calculation [only used when WakeMod=1 or 2] + call ParseVar( FileInfo_In, CurLine, "CompAA", InputFileData%CompAA, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! AA_InputFile - Aeroacoustics input file + call ParseVar( FileInfo_In, CurLine, "AA_InputFile", InputFileData%AA_InputFile, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + IF ( PathIsRelative( InputFileData%AA_InputFile ) ) InputFileData%AA_InputFile = TRIM(PriPath)//TRIM(InputFileData%AA_InputFile) + + !====== Environmental Conditions =================================================================== + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + ! AirDens - Air density (kg/m^3) + call ParseVar( FileInfo_In, CurLine, "AirDens", InputFileData%AirDens, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! KinVisc - Kinematic air viscosity (m^2/s) + call ParseVar( FileInfo_In, CurLine, "KinVisc", InputFileData%KinVisc, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! SpdSound - Speed of sound (m/s) + call ParseVar( FileInfo_In, CurLine, "SpdSound", InputFileData%SpdSound, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! Patm - Atmospheric pressure (Pa) [used only when CavitCheck=True] + call ParseVar( FileInfo_In, CurLine, "Patm", InputFileData%Patm, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! Pvap - Vapour pressure of fluid (Pa) [used only when CavitCheck=True] + call ParseVar( FileInfo_In, CurLine, "Pvap", InputFileData%Pvap, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! FluidDepth - Water depth above mid-hub height (m) [used only when CavitCheck=True] + call ParseVar( FileInfo_In, CurLine, "FluidDepth", InputFileData%FluidDepth, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + + !====== Blade-Element/Momentum Theory Options ====================================================== [unused when WakeMod=0 or 3] + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + ! SkewMod - Type of skewed-wake correction model (switch) {1=uncoupled, 2=Pitt/Peters, 3=coupled} [unused when WakeMod=0 or 3] + call ParseVar( FileInfo_In, CurLine, "SkewMod", InputFileData%SkewMod, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! SkewModFactor - Constant used in Pitt/Peters skewed wake model {or "default" is 15/32*pi} (-) [used only when SkewMod=2; unused when WakeMod=0 or 3] + call ParseVarWDefault( FileInfo_In, CurLine, "SkewModFactor", InputFileData%SkewModFactor, (15.0_ReKi * pi / 32.0_ReKi), ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! TipLoss - Use the Prandtl tip-loss model? (flag) [unused when WakeMod=0 or 3] + call ParseVar( FileInfo_In, CurLine, "TipLoss", InputFileData%TipLoss, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! HubLoss - Use the Prandtl hub-loss model? (flag) [unused when WakeMod=0 or 3] + call ParseVar( FileInfo_In, CurLine, "HubLoss", InputFileData%HubLoss, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! TanInd - Include tangential induction in BEMT calculations? (flag) [unused when WakeMod=0 or 3] + call ParseVar( FileInfo_In, CurLine, "TanInd", InputFileData%TanInd, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! AIDrag - Include the drag term in the axial-induction calculation? (flag) [unused when WakeMod=0 or 3] + call ParseVar( FileInfo_In, CurLine, "AIDrag", InputFileData%AIDrag, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! TIDrag - Include the drag term in the tangential-induction calculation? (flag) [unused when WakeMod=0,3 or TanInd=FALSE] + call ParseVar( FileInfo_In, CurLine, "TIDrag", InputFileData%TIDrag, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! IndToler - Convergence tolerance for BEMT nonlinear solve residual equation {or "default"} (-) [unused when WakeMod=0 or 3] + if (ReKi==SiKi) then + call ParseVarWDefault( FileInfo_In, CurLine, "IndToler", InputFileData%IndToler, real(5E-5,ReKi), ErrStat2, ErrMsg2, UnEc ) + else + call ParseVarWDefault( FileInfo_In, CurLine, "IndToler", InputFileData%IndToler, real(5D-10,ReKi), ErrStat2, ErrMsg2, UnEc ) + end if + if (Failed()) return + ! MaxIter - Maximum number of iteration steps (-) [unused when WakeMod=0] + call ParseVar( FileInfo_In, CurLine, "MaxIter", InputFileData%MaxIter, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + + !====== Dynamic Blade-Element/Momentum Theory Options ============================================== [used only when WakeMod=2] + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + ! DBEMT_Mod - Type of dynamic BEMT (DBEMT) model {1=constant tau1, 2=time-dependent tau1} (-) [used only when WakeMod=2] + call ParseVar( FileInfo_In, CurLine, "DBEMT_Mod", InputFileData%DBEMT_Mod, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! tau1_const - Time constant for DBEMT (s) [used only when WakeMod=2 and DBEMT_Mod=1] + call ParseVar( FileInfo_In, CurLine, "tau1_const", InputFileData%tau1_const, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + + !====== OLAF -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options ================== [used only when WakeMod=3] + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + ! OLAFInputFileName - Input file for OLAF [used only when WakeMod=3] + call ParseVar( FileInfo_In, CurLine, "OLAFInputFileName", InputFileData%FVWFileName, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + IF ( PathIsRelative( InputFileData%FVWFileName ) ) InputFileData%FVWFileName = TRIM(PriPath)//TRIM(InputFileData%FVWFileName) + + !====== Beddoes-Leishman Unsteady Airfoil Aerodynamics Options ===================================== [used only when AFAeroMod=2] + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + ! UAMod - Unsteady Aero Model Switch (switch) {1=Baseline model (Original), 2=Gonzalez's variant (changes in Cn,Cc,Cm), 3=Minnema/Pierce variant (changes in Cc and Cm)} [used only when AFAeroMod=2] + call ParseVar( FileInfo_In, CurLine, "UAMod", InputFileData%UAMod, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! FLookup - Flag to indicate whether a lookup for f' will be calculated (TRUE) or whether best-fit exponential equations will be used (FALSE); if FALSE S1-S4 must be provided in airfoil input files (flag) [used only when AFAeroMod=2] + call ParseVar( FileInfo_In, CurLine, "FLookup", InputFileData%FLookup, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + + !====== Airfoil Information ========================================================================= + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + ! AFTabMod - Interpolation method for multiple airfoil tables {1=1D interpolation on AoA (first table only); 2=2D interpolation on AoA and Re; 3=2D interpolation on AoA and UserProp} (-) + call ParseVar( FileInfo_In, CurLine, "AFTabMod", InputFileData%AFTabMod, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! InCol_Alfa - The column in the airfoil tables that contains the angle of attack (-) + call ParseVar( FileInfo_In, CurLine, "InCol_Alfa", InputFileData%InCol_Alfa, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! InCol_Cl - The column in the airfoil tables that contains the lift coefficient (-) + call ParseVar( FileInfo_In, CurLine, "InCol_Cl", InputFileData%InCol_Cl, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! InCol_Cd - The column in the airfoil tables that contains the drag coefficient (-) + call ParseVar( FileInfo_In, CurLine, "InCol_Cd", InputFileData%InCol_Cd, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! InCol_Cm - The column in the airfoil tables that contains the pitching-moment coefficient; use zero if there is no Cm column (-) + call ParseVar( FileInfo_In, CurLine, "InCol_Cm", InputFileData%InCol_Cm, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! InCol_Cpmin - The column in the airfoil tables that contains the Cpmin coefficient; use zero if there is no Cpmin column (-) + call ParseVar( FileInfo_In, CurLine, "InCol_Cpmin", InputFileData%InCol_Cpmin, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! NumAFfiles - Number of airfoil files used (-) + call ParseVar( FileInfo_In, CurLine, "NumAFfiles", InputFileData%NumAFfiles, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return ! Allocate space to hold AFNames ALLOCATE( InputFileData%AFNames(InputFileData%NumAFfiles), STAT=ErrStat2) IF (ErrStat2 /= 0 ) THEN CALL SetErrStat( ErrID_Fatal, "Error allocating AFNames.", ErrStat, ErrMsg, RoutineName) - CALL Cleanup() RETURN END IF - - ! AFNames - Airfoil file names (NumAFfiles lines) (quoted strings): - DO I = 1,InputFileData%NumAFfiles - CALL ReadVar ( UnIn, InputFile, InputFileData%AFNames(I), 'AFNames('//TRIM(Num2Lstr(I))//')', 'Airfoil '//TRIM(Num2Lstr(I))//' file name', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! AFNames - Airfoil file names (NumAFfiles lines) (quoted strings): -- NOTE: this line may not have a keyname with it + DO I = 1,InputFileData%NumAFfiles ! ParseChVar allows empty keynames. + call ParseVar( FileInfo_In, CurLine, "", InputFileData%AFNames(I), ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return IF ( PathIsRelative( InputFileData%AFNames(I) ) ) InputFileData%AFNames(I) = TRIM(PriPath)//TRIM(InputFileData%AFNames(I)) - END DO - - ! Return on error at end of section - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - !----------- ROTOR/BLADE PROPERTIES -------------------------------------------- - CALL ReadCom( UnIn, InputFile, 'Section Header: Rotor/Blade Properties', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! UseBlCm - Include aerodynamic pitching moment in calculations? (flag): - CALL ReadVar( UnIn, InputFile, InputFileData%UseBlCm, "UseBlCm", "Include aerodynamic pitching moment in calculations? (flag)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - IF (.not. InputFileData%UseBlCm) InputFileData%InCol_Cm = 0 ! don't use cm column is UseBlCm is false - - ! ! NumBlNds - Number of blade nodes used in the analysis (-): - !CALL ReadVar( UnIn, InputFile, InputFileData%NumBlNds, "NumBlNds", "Number of blade nodes used in the analysis (-)", ErrStat2, ErrMsg2, UnEc) - ! CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ! IF ( ErrStat >= AbortErrLev ) RETURN - - ! ADBlFile - Names of files containing distributed aerodynamic properties for each blade (see AD_BladeInputFile type): - DO I = 1,size(ADBlFile) - CALL ReadVar ( UnIn, InputFile, ADBlFile(I), 'ADBlFile('//TRIM(Num2Lstr(I))//')', 'Name of file containing distributed aerodynamic properties for blade '//TRIM(Num2Lstr(I)), ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( PathIsRelative( ADBlFile(I) ) ) ADBlFile(I) = TRIM(PriPath)//TRIM(ADBlFile(I)) - END DO - - ! Return on error at end of section - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - !----------- TOWER INFLUENCE AND AERODYNAMICS ---------------------------------- - CALL ReadCom( UnIn, InputFile, 'Section Header: Tower Influence and Aerodynamics', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! NumTwrNds - Number of tower nodes used in the analysis (-): - CALL ReadVar( UnIn, InputFile, InputFileData%NumTwrNds, "NumTwrNds", "Number of tower nodes used in the analysis (-)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN + END DO - - !....... tower properties ................... - CALL ReadCom( UnIn, InputFile, 'Section Header: Tower Property Channels', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadCom( UnIn, InputFile, 'Section Header: Tower Property Units', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! allocate space for tower inputs: + !====== Rotor/Blade Properties ===================================================================== + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + ! UseBlCm - Include aerodynamic pitching moment in calculations? (flag) + call ParseVar( FileInfo_In, CurLine, "UseBlCm", InputFileData%UseBlCm, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! Allocate space for AD blade file names -- MaxBl is usually set to 3, but if we specify more blades, this will work still. + call AllocAry( InputFileData%ADBlFile, max(MaxBl,NumBlades), 'ADBlFile', ErrStat2, ErrMsg2) + if (Failed()) return + do I =1,size(InputFileData%ADBlFile) ! We expect MaxBl blade file lines. We may want to revisit this idea later if we allow more thn 3 blades + call ParseVar( FileInfo_In, CurLine, "", InputFileData%ADBlFile(i), ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + IF ( PathIsRelative( InputFileData%ADBlFile(I) ) ) InputFileData%ADBlFile(I) = TRIM(PriPath)//TRIM(InputFileData%ADBlFile(I)) + enddo + + !====== Tower Influence and Aerodynamics ============================================================= [used only when TwrPotent/=0, TwrShadow/=0, or TwrAero=True] + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + ! NumTwrNds - Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow/=0, or TwrAero=True] + call ParseVar( FileInfo_In, CurLine, "NumTwrNds", InputFileData%NumTwrNds, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + !TwrElev TwrDiam TwrCd + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') 'Tower Table Header: '//FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + !(m) (m) (-) + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') 'Tower Table Header: '//FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + ! Allocate space for tower table CALL AllocAry( InputFileData%TwrElev, InputFileData%NumTwrNds, 'TwrElev', ErrStat2, ErrMsg2) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (Failed()) return CALL AllocAry( InputFileData%TwrDiam, InputFileData%NumTwrNds, 'TwrDiam', ErrStat2, ErrMsg2) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (Failed()) return CALL AllocAry( InputFileData%TwrCd, InputFileData%NumTwrNds, 'TwrCd', ErrStat2, ErrMsg2) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! Return on error if we didn't allocate space for the next inputs - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - DO I=1,InputFileData%NumTwrNds - call ReadAry ( UnIn, InputFile, TmpAry, 3, 'TwrNds', 'Properties for tower node ' & - //trim( Int2LStr( I ) )//'.', errStat2, errMsg2, UnEc ) - call setErrStat( errStat2, ErrMsg2 , errStat, ErrMsg , RoutineName ) - - InputFileData%TwrElev(I) = TmpAry( 1) - InputFileData%TwrDiam(I) = TmpAry( 2) - InputFileData%TwrCd(I) = TmpAry( 3) - END DO - - ! Return on error at end of section - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - !----------- OUTPUTS ----------------------------------------------------------- - CALL ReadCom( UnIn, InputFile, 'Section Header: Outputs', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! SumPrint - Generate a summary file listing input options and interpolated properties to .AD.sum? (flag): - CALL ReadVar( UnIn, InputFile, InputFileData%SumPrint, "SumPrint", "Generate a summary file listing input options and interpolated properties to .AD.sum? (flag)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! NBlOuts - Number of blade node outputs [0 - 9] (-): - CALL ReadVar( UnIn, InputFile, InputFileData%NBlOuts, "NBlOuts", "Number of blade node outputs [0 - 9] (-)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - IF ( InputFileData%NBlOuts > SIZE(InputFileData%BlOutNd) ) THEN - CALL SetErrStat( ErrID_Warn, ' Warning: number of blade output nodes exceeds '//& - TRIM(Num2LStr(SIZE(InputFileData%BlOutNd))) //'.', ErrStat, ErrMsg, RoutineName ) - InputFileData%NBlOuts = SIZE(InputFileData%BlOutNd) - END IF - + if (Failed()) return + CALL AllocAry( InputFileData%TwrTI, InputFileData%NumTwrNds, 'TwrTI', ErrStat2, ErrMsg2) + if (Failed()) return + + do I=1,InputFileData%NumTwrNds + call ParseAry ( FileInfo_In, CurLine, 'Properties for tower node '//trim( Int2LStr( I ) )//'.', TmpRe4, 4, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return; + InputFileData%TwrElev(I) = TmpRe4( 1) + InputFileData%TwrDiam(I) = TmpRe4( 2) + InputFileData%TwrCd(I) = TmpRe4( 3) + InputFileData%TwrTI(I) = TmpRe4( 4) + end do + + !====== Outputs ==================================================================================== + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + ! SumPrint - Generate a summary file listing input options and interpolated properties to ".AD.sum"? (flag) + call ParseVar( FileInfo_In, CurLine, "SumPrint", InputFileData%SumPrint, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + + ! NBlOuts - Number of blade node outputs [0 - 9] (-) + call ParseVar( FileInfo_In, CurLine, "NBlOuts", InputFileData%NBlOuts, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! Make sure we don't try to read in more than will fit in the pre-allocated BlOutNd array + if ( InputFileData%NBlOuts > SIZE(InputFileData%BlOutNd) ) THEN + CALL SetErrStat( ErrID_Warn, ' Warning: number of blade output nodes exceeds '//& + TRIM(Num2LStr(SIZE(InputFileData%BlOutNd))) //'.', ErrStat, ErrMsg, RoutineName ) + InputFileData%NBlOuts = SIZE(InputFileData%BlOutNd) + endif ! BlOutNd - Blade nodes whose values will be output (-): - CALL ReadAry( UnIn, InputFile, InputFileData%BlOutNd, InputFileData%NBlOuts, "BlOutNd", "Blade nodes whose values will be output (-)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! NTwOuts - Number of tower node outputs [0 - 9] (-): - CALL ReadVar( UnIn, InputFile, InputFileData%NTwOuts, "NTwOuts", "Number of tower node outputs [0 - 9] (-)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - IF ( InputFileData%NTwOuts > SIZE(InputFileData%TwOutNd) ) THEN - CALL SetErrStat( ErrID_Warn, ' Warning: number of tower output nodes exceeds '//& - TRIM(Num2LStr(SIZE(InputFileData%TwOutNd))) //'.', ErrStat, ErrMsg, RoutineName ) - InputFileData%NTwOuts = SIZE(InputFileData%TwOutNd) - END IF - + call ParseAry( FileInfo_In, CurLine, "BlOutNd", InputFileData%BlOutNd, InputFileData%NBlOuts, ErrStat2, ErrMsg2, UnEc) + + ! NTwOuts - Number of blade node outputs [0 - 9] (-) + call ParseVar( FileInfo_In, CurLine, "NTwOuts", InputFileData%NTwOuts, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! Make sure we don't try to read in more than will fit in the pre-allocated TwOutNd array + if ( InputFileData%NTwOuts > SIZE(InputFileData%TwOutNd) ) THEN + CALL SetErrStat( ErrID_Warn, ' Warning: number of blade output nodes exceeds '//& + TRIM(Num2LStr(SIZE(InputFileData%TwOutNd))) //'.', ErrStat, ErrMsg, RoutineName ) + InputFileData%NTwOuts = SIZE(InputFileData%TwOutNd) + endif ! TwOutNd - Tower nodes whose values will be output (-): - CALL ReadAry( UnIn, InputFile, InputFileData%TwOutNd, InputFileData%NTwOuts, "TwOutNd", "Tower nodes whose values will be output (-)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! Return on error at end of section - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - !----------- OUTLIST ----------------------------------------------------------- - CALL ReadCom( UnIn, InputFile, 'Section Header: OutList', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! OutList - List of user-requested output channels (-): - CALL ReadOutputList ( UnIn, InputFile, InputFileData%OutList, InputFileData%NumOuts, 'OutList', "List of user-requested output channels", ErrStat2, ErrMsg2, UnEc ) ! Routine in NWTC Subroutine Library - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - - ! Return on error at end of section - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - !---------------------- END OF FILE ----------------------------------------- - + call ParseAry( FileInfo_In, CurLine, "TwOutNd", InputFileData%TwOutNd, InputFileData%NTwOuts, ErrStat2, ErrMsg2, UnEc) + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + call ReadOutputListFromFileInfo( FileInfo_In, CurLine, InputFileData%OutList, & + InputFileData%NumOuts, 'OutList', "List of user-requested output channels", ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return; - !----------- OUTLIST ----------------------------------------------------------- + !====== Nodal Outputs ============================================================================== ! In case there is something ill-formed in the additional nodal outputs section, we will simply ignore it. - ErrMsg_NoAllBldNdOuts='Nodal output section of AeroDyn input file not found or improperly formatted.' - - !----------- OUTLIST for BldNd ----------------------------------------------------------- - CALL ReadCom( UnIn, InputFile, 'Section Header: OutList for Blade node channels', ErrStat2, ErrMsg2, UnEc ) - IF ( ErrStat2 >= AbortErrLev ) THEN - InputFileData%BldNd_BladesOut = 0 - InputFileData%BldNd_NumOuts = 0 - call wrscr( trim(ErrMsg_NoAllBldNdOuts) ) - CALL Cleanup() - RETURN - ENDIF + ! Expecting at least 5 more lines in the input file for this section + if (FileInfo_In%NumLines < CurLine + 5) then + ErrStat2 = ErrID_Fatal + ErrMsg2 = '' + if (FailedNodal()) return; + endif + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 - ! Number of blade nodes to output: will modify this at some point for arrays + ! BldNd_BladesOut - Number of blades to output all node information at. Up to number of blades on turbine. (-) ! TODO: In a future release, allow this to be an array of N blade numbers (change BldNd_BladesOut to an array if we do that). ! Will likely require reading this line in as a string (BldNd_BladesOut_Str) and parsing it - CALL ReadVar( UnIn, InputFile, InputFileData%BldNd_BladesOut, 'BldNd_BladesOut', 'Which blades to output node data on.'//TRIM(Num2Lstr(I)), ErrStat2, ErrMsg2, UnEc ) - IF ( ErrStat2 >= AbortErrLev ) THEN - InputFileData%BldNd_BladesOut = 0 - InputFileData%BldNd_NumOuts = 0 - call wrscr( trim(ErrMsg_NoAllBldNdOuts) ) - CALL Cleanup() - RETURN - ENDIF - - - ! Which blades to output for: will add this at some point + call ParseVar( FileInfo_In, CurLine, "BldNd_BladesOut", InputFileData%BldNd_BladesOut, ErrStat2, ErrMsg2, UnEc ) + if (FailedNodal()) return + ! BldNd_BlOutNd - Future feature will allow selecting a portion of the nodes to output. Not implemented yet. (-) ! TODO: Parse this string into an array of nodes to output at (one idea is to set an array of boolean to T/F for which nodes to output). At present, we ignore it entirely. - CALL ReadVar( UnIn, InputFile, InputFileData%BldNd_BlOutNd_Str, 'BldNd_BlOutNd_Str', 'Which nodes to output node data on.'//TRIM(Num2Lstr(I)), ErrStat2, ErrMsg2, UnEc ) - IF ( ErrStat2 >= AbortErrLev ) THEN - InputFileData%BldNd_BladesOut = 0 - InputFileData%BldNd_NumOuts = 0 - call wrscr( trim(ErrMsg_NoAllBldNdOuts) ) - CALL Cleanup() - RETURN - ENDIF + call ParseVar( FileInfo_In, CurLine, "BldNd_BlOutNd", InputFileData%BldNd_BlOutNd_Str, ErrStat2, ErrMsg2, UnEc ) + if (FailedNodal()) return + ! OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + call ReadOutputListFromFileInfo( FileInfo_In, CurLine, InputFileData%BldNd_OutList, & + InputFileData%BldNd_NumOuts, 'BldNd_OutList', "List of user-requested output nodal channel groups", ErrStat2, ErrMsg2, UnEc ) + if (FailedNodal()) return; - ! Section header for outlist - CALL ReadCom( UnIn, InputFile, 'Section Header: OutList', ErrStat2, ErrMsg2, UnEc ) - IF ( ErrStat2 >= AbortErrLev ) THEN - InputFileData%BldNd_BladesOut = 0 - InputFileData%BldNd_NumOuts = 0 - call wrscr( trim(ErrMsg_NoAllBldNdOuts) ) - CALL Cleanup() - RETURN - ENDIF - - - ! OutList - List of user-requested output channels at each node(-): - CALL ReadOutputList ( UnIn, InputFile, InputFileData%BldNd_OutList, InputFileData%BldNd_NumOuts, 'OutList', "List of user-requested output channels", ErrStat2, ErrMsg2, UnEc ) ! Routine in NWTC Subroutine Library - IF ( ErrStat2 >= AbortErrLev ) THEN - InputFileData%BldNd_BladesOut = 0 - InputFileData%BldNd_NumOuts = 0 - call wrscr( trim(ErrMsg_NoAllBldNdOuts) ) - CALL Cleanup() - RETURN - ENDIF - - - - !---------------------- END OF FILE ----------------------------------------- - - CALL Cleanup( ) RETURN - - CONTAINS - !............................................................................................................................... - SUBROUTINE Cleanup() - ! This subroutine cleans up any local variables and closes input files - !............................................................................................................................... - - IF (UnIn > 0) CLOSE ( UnIn ) - - END SUBROUTINE Cleanup - !............................................................................................................................... -END SUBROUTINE ReadPrimaryFile + !------------------------------------------------------------------------------------------------- + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'ParsePrimaryFileInfo' ) + Failed = ErrStat >= AbortErrLev + if (Failed) then + if (UnEc > -1_IntKi) CLOSE( UnEc ) + endif + end function Failed + logical function FailedNodal() + ErrMsg_NoAllBldNdOuts='AD15 Nodal Outputs: Nodal output section of AeroDyn input file not found or improperly formatted. Skipping nodal outputs.' + if (ErrStat2 >= AbortErrLev ) then + InputFileData%BldNd_BladesOut = 0 + InputFileData%BldNd_NumOuts = 0 + call wrscr( trim(ErrMsg_NoAllBldNdOuts) ) + endif + FailedNodal = ErrStat2 >= AbortErrLev + end function FailedNodal + !------------------------------------------------------------------------------------------------- +END SUBROUTINE ParsePrimaryFileInfo !---------------------------------------------------------------------------------------------------------------------------------- SUBROUTINE ReadBladeInputs ( ADBlFile, BladeKInputFileData, UnEc, ErrStat, ErrMsg ) ! This routine reads a blade input file. @@ -2813,13 +2540,18 @@ SUBROUTINE AD_PrintSum( InputFileData, p, u, y, ErrStat, ErrMsg ) ! TwrShadow - if (p%TwrShadow) then - Msg = 'Yes' - else - Msg = 'No' - end if - WRITE (UnSu,Ec_LgFrmt) p%TwrShadow, 'TwrShadow', 'Calculate tower influence on wind based on downstream tower shadow? '//TRIM(Msg) - + select case (p%TwrShadow) + case (TwrShadow_Powles) + Msg = 'Powles tower shadow model' + case (TwrShadow_Eames) + Msg = 'Eames tower shadow model with TI values from the table' + case (TwrShadow_none) + Msg = 'none' + case default + Msg = 'unknown' + end select + WRITE (UnSu,Ec_IntFrmt) p%TwrShadow, 'TwrShadow', 'Calculate tower influence on wind based on downstream tower shadow: '//TRIM(Msg) + ! TwrAero if (p%TwrAero) then @@ -3501,7 +3233,7 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) ! ..... Developer must add checking for invalid inputs here: ..... !bjj: do we want to avoid outputting this if we haven't used tower aero? - if ( p%TwrPotent == TwrPotent_none .and. .not. p%TwrShadow ) then + if ( p%TwrPotent == TwrPotent_none .and. p%TwrShadow == TwrShadow_none ) then ! BNClrnc is set only when we're computing the tower influence do i = 1,size(BNClrnc,2) ! all blades (need to do this in a loop because we need the index of InvalidOutput to be an array of rank one) diff --git a/modules/aerodyn/src/AeroDyn_Registry.txt b/modules/aerodyn/src/AeroDyn_Registry.txt index 563b6cf202..67998aa731 100644 --- a/modules/aerodyn/src/AeroDyn_Registry.txt +++ b/modules/aerodyn/src/AeroDyn_Registry.txt @@ -30,6 +30,10 @@ param ^ - IntKi TwrPotent_none - 0 - "no tower p param ^ - IntKi TwrPotent_baseline - 1 - "baseline tower potential flow" - param ^ - IntKi TwrPotent_Bak - 2 - "tower potential flow with Bak correction" - +param ^ - IntKi TwrShadow_none - 0 - "no tower shadow" - +param ^ - IntKi TwrShadow_Powles - 1 - "Powles tower shadow model" - +param ^ - IntKi TwrShadow_Eames - 2 - "Eames tower shadow model" - + # ..... Initialization data ....................................................................................................... # Define inputs that the initialization routine may need here: @@ -42,6 +46,10 @@ typedef ^ InitInputType ReKi HubPosition {3} - - "X-Y-Z reference position of hu typedef ^ InitInputType R8Ki HubOrientation {3}{3} - - "DCM reference orientation of hub" - typedef ^ InitInputType ReKi BladeRootPosition {:}{:} - - "X-Y-Z reference position of each blade root (3 x NumBlades)" m typedef ^ InitInputType R8Ki BladeRootOrientation {:}{:}{:} - - "DCM reference orientation of blade roots (3x3 x NumBlades)" - +typedef ^ InitInputType LOGICAL UsePrimaryInputFile - .TRUE. - "Read input file instead of passed data" - +typedef ^ InitInputType FileInfoType PassedPrimaryInputData - - - "Primary input file as FileInfoType (set by driver/glue code)" - + + # This is data defined in the Input File for this module (or could otherwise be passed in) # ..... Blade Input file data ..................................................................................................... @@ -77,16 +85,18 @@ typedef ^ InitOutputType ReKi TwrDiam {:} - - "Diameter of tower at node" m # ..... Input file data ........................................................................................................... # ..... Primary Input file data ................................................................................................... +typedef ^ AD_InputFile Logical Echo - - - "Echo input file to echo file" - typedef ^ AD_InputFile DbKi DTAero - - - "Time interval for aerodynamic calculations {or "default"}" s typedef ^ AD_InputFile IntKi WakeMod - - - "Type of wake/induction model {0=none, 1=BEMT, 2=DBEMT, 3=FVW}" - typedef ^ AD_InputFile IntKi AFAeroMod - - - "Type of blade airfoil aerodynamics model {1=steady model, 2=Beddoes-Leishman unsteady model}" - typedef ^ AD_InputFile IntKi TwrPotent - - - "Type tower influence on wind based on potential flow around the tower {0=none, 1=baseline potential flow, 2=potential flow with Bak correction}" - -typedef ^ AD_InputFile LOGICAL TwrShadow - - - "Calculate tower influence on wind based on downstream tower shadow?" - +typedef ^ AD_InputFile IntKi TwrShadow - - - "Calculate tower influence on wind based on downstream tower shadow {0=none, 1=Powles model, 2=Eames model}" - typedef ^ AD_InputFile LOGICAL TwrAero - - - "Calculate tower aerodynamic loads?" flag typedef ^ AD_InputFile Logical FrozenWake - - - "Flag that tells this module it should assume a frozen wake during linearization." - typedef ^ AD_InputFile Logical CavitCheck - - - "Flag that tells us if we want to check for cavitation" - typedef ^ AD_InputFile Logical CompAA - - - "Compute AeroAcoustic noise" flag typedef ^ AD_InputFile CHARACTER(1024) AA_InputFile - - - "AeroAcoustics input file name" "quoted strings" +typedef ^ AD_InputFile CHARACTER(1024) ADBlFile {:} - - "AD blade file (NumBl filenames)" "quoted strings" typedef ^ AD_InputFile ReKi AirDens - - - "Air density" kg/m^3 typedef ^ AD_InputFile ReKi KinVisc - - - "Kinematic air viscosity" m^2/s typedef ^ AD_InputFile ReKi Patm - - - "Atmospheric pressure" Pa @@ -120,6 +130,7 @@ typedef ^ AD_InputFile IntKi NumTwrNds - - - "Number of tower nodes used in the typedef ^ AD_InputFile ReKi TwrElev {:} - - "Elevation at tower node" m typedef ^ AD_InputFile ReKi TwrDiam {:} - - "Diameter of tower at node" m typedef ^ AD_InputFile ReKi TwrCd {:} - - "Coefficient of drag at tower node" - +typedef ^ AD_InputFile ReKi TwrTI {:} - - "Turbulence intensity for tower shadow at tower node" - typedef ^ AD_InputFile LOGICAL SumPrint - - - "Generate a summary file listing input options and interpolated properties to ".AD.sum"?" flag typedef ^ AD_InputFile IntKi NBlOuts - - - "Number of blade node outputs [0 - 9]" - typedef ^ AD_InputFile IntKi BlOutNd {9} - - "Blade nodes whose values will be output" - @@ -195,7 +206,7 @@ typedef ^ MiscVarType Logical CavitWarnSet {:}{:} - - "cavitation warning issu typedef ^ ParameterType DbKi DT - - - "Time step for continuous state integration & discrete state update" seconds typedef ^ ParameterType IntKi WakeMod - - - "Type of wake/induction model {0=none, 1=BEMT, 2=DBEMT, 3=FVW}" - typedef ^ ParameterType IntKi TwrPotent - - - "Type tower influence on wind based on potential flow around the tower {0=none, 1=baseline potential flow, 2=potential flow with Bak correction}" - -typedef ^ ParameterType LOGICAL TwrShadow - - - "Calculate tower influence on wind based on downstream tower shadow?" - +typedef ^ ParameterType IntKi TwrShadow - - - "Calculate tower influence on wind based on downstream tower shadow {0=none, 1=Powles model, 2=Eames model}" - typedef ^ ParameterType LOGICAL TwrAero - - - "Calculate tower aerodynamic loads?" flag typedef ^ ParameterType Logical FrozenWake - - - "Flag that tells this module it should assume a frozen wake during linearization." - typedef ^ ParameterType Logical CavitCheck - - - "Flag that tells us if we want to check for cavitation" - @@ -205,6 +216,7 @@ typedef ^ ParameterType IntKi NumBlNds - - - "Number of nodes on each blade" - typedef ^ ParameterType IntKi NumTwrNds - - - "Number of nodes on the tower" - typedef ^ ParameterType ReKi TwrDiam {:} - - "Diameter of tower at node" m typedef ^ ParameterType ReKi TwrCd {:} - - "Coefficient of drag at tower node" - +typedef ^ ParameterType ReKi TwrTI {:} - - "Turbulence intensity for tower shadow at tower node" - typedef ^ ParameterType ReKi AirDens - - - "Air density" kg/m^3 typedef ^ ParameterType ReKi KinVisc - - - "Kinematic air viscosity" m^2/s typedef ^ ParameterType ReKi SpdSound - - - "Speed of sound" m/s diff --git a/modules/aerodyn/src/AeroDyn_Types.f90 b/modules/aerodyn/src/AeroDyn_Types.f90 index 28487fc89c..c3ac68c372 100644 --- a/modules/aerodyn/src/AeroDyn_Types.f90 +++ b/modules/aerodyn/src/AeroDyn_Types.f90 @@ -49,6 +49,9 @@ MODULE AeroDyn_Types INTEGER(IntKi), PUBLIC, PARAMETER :: TwrPotent_none = 0 ! no tower potential flow [-] INTEGER(IntKi), PUBLIC, PARAMETER :: TwrPotent_baseline = 1 ! baseline tower potential flow [-] INTEGER(IntKi), PUBLIC, PARAMETER :: TwrPotent_Bak = 2 ! tower potential flow with Bak correction [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: TwrShadow_none = 0 ! no tower shadow [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: TwrShadow_Powles = 1 ! Powles tower shadow model [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: TwrShadow_Eames = 2 ! Eames tower shadow model [-] ! ========= AD_InitInputType ======= TYPE, PUBLIC :: AD_InitInputType CHARACTER(1024) :: InputFile !< Name of the input file [-] @@ -60,6 +63,8 @@ MODULE AeroDyn_Types REAL(R8Ki) , DIMENSION(1:3,1:3) :: HubOrientation !< DCM reference orientation of hub [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: BladeRootPosition !< X-Y-Z reference position of each blade root (3 x NumBlades) [m] REAL(R8Ki) , DIMENSION(:,:,:), ALLOCATABLE :: BladeRootOrientation !< DCM reference orientation of blade roots (3x3 x NumBlades) [-] + LOGICAL :: UsePrimaryInputFile = .TRUE. !< Read input file instead of passed data [-] + TYPE(FileInfoType) :: PassedPrimaryInputData !< Primary input file as FileInfoType (set by driver/glue code) [-] END TYPE AD_InitInputType ! ======================= ! ========= AD_BladePropsType ======= @@ -101,16 +106,18 @@ MODULE AeroDyn_Types ! ======================= ! ========= AD_InputFile ======= TYPE, PUBLIC :: AD_InputFile + LOGICAL :: Echo !< Echo input file to echo file [-] REAL(DbKi) :: DTAero !< Time interval for aerodynamic calculations {or "default"} [s] INTEGER(IntKi) :: WakeMod !< Type of wake/induction model {0=none, 1=BEMT, 2=DBEMT, 3=FVW} [-] INTEGER(IntKi) :: AFAeroMod !< Type of blade airfoil aerodynamics model {1=steady model, 2=Beddoes-Leishman unsteady model} [-] INTEGER(IntKi) :: TwrPotent !< Type tower influence on wind based on potential flow around the tower {0=none, 1=baseline potential flow, 2=potential flow with Bak correction} [-] - LOGICAL :: TwrShadow !< Calculate tower influence on wind based on downstream tower shadow? [-] + INTEGER(IntKi) :: TwrShadow !< Calculate tower influence on wind based on downstream tower shadow {0=none, 1=Powles model, 2=Eames model} [-] LOGICAL :: TwrAero !< Calculate tower aerodynamic loads? [flag] LOGICAL :: FrozenWake !< Flag that tells this module it should assume a frozen wake during linearization. [-] LOGICAL :: CavitCheck !< Flag that tells us if we want to check for cavitation [-] LOGICAL :: CompAA !< Compute AeroAcoustic noise [flag] CHARACTER(1024) :: AA_InputFile !< AeroAcoustics input file name [quoted strings] + CHARACTER(1024) , DIMENSION(:), ALLOCATABLE :: ADBlFile !< AD blade file (NumBl filenames) [quoted strings] REAL(ReKi) :: AirDens !< Air density [kg/m^3] REAL(ReKi) :: KinVisc !< Kinematic air viscosity [m^2/s] REAL(ReKi) :: Patm !< Atmospheric pressure [Pa] @@ -143,6 +150,7 @@ MODULE AeroDyn_Types REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwrElev !< Elevation at tower node [m] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwrDiam !< Diameter of tower at node [m] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwrCd !< Coefficient of drag at tower node [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwrTI !< Turbulence intensity for tower shadow at tower node [-] LOGICAL :: SumPrint !< Generate a summary file listing input options and interpolated properties to ".AD.sum"? [flag] INTEGER(IntKi) :: NBlOuts !< Number of blade node outputs [0 - 9] [-] INTEGER(IntKi) , DIMENSION(1:9) :: BlOutNd !< Blade nodes whose values will be output [-] @@ -224,7 +232,7 @@ MODULE AeroDyn_Types REAL(DbKi) :: DT !< Time step for continuous state integration & discrete state update [seconds] INTEGER(IntKi) :: WakeMod !< Type of wake/induction model {0=none, 1=BEMT, 2=DBEMT, 3=FVW} [-] INTEGER(IntKi) :: TwrPotent !< Type tower influence on wind based on potential flow around the tower {0=none, 1=baseline potential flow, 2=potential flow with Bak correction} [-] - LOGICAL :: TwrShadow !< Calculate tower influence on wind based on downstream tower shadow? [-] + INTEGER(IntKi) :: TwrShadow !< Calculate tower influence on wind based on downstream tower shadow {0=none, 1=Powles model, 2=Eames model} [-] LOGICAL :: TwrAero !< Calculate tower aerodynamic loads? [flag] LOGICAL :: FrozenWake !< Flag that tells this module it should assume a frozen wake during linearization. [-] LOGICAL :: CavitCheck !< Flag that tells us if we want to check for cavitation [-] @@ -234,6 +242,7 @@ MODULE AeroDyn_Types INTEGER(IntKi) :: NumTwrNds !< Number of nodes on the tower [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwrDiam !< Diameter of tower at node [m] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwrCd !< Coefficient of drag at tower node [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwrTI !< Turbulence intensity for tower shadow at tower node [-] REAL(ReKi) :: AirDens !< Air density [kg/m^3] REAL(ReKi) :: KinVisc !< Kinematic air viscosity [m^2/s] REAL(ReKi) :: SpdSound !< Speed of sound [m/s] @@ -338,6 +347,10 @@ SUBROUTINE AD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrSt END IF DstInitInputData%BladeRootOrientation = SrcInitInputData%BladeRootOrientation ENDIF + DstInitInputData%UsePrimaryInputFile = SrcInitInputData%UsePrimaryInputFile + CALL NWTC_Library_Copyfileinfotype( SrcInitInputData%PassedPrimaryInputData, DstInitInputData%PassedPrimaryInputData, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE AD_CopyInitInput SUBROUTINE AD_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) @@ -355,6 +368,7 @@ SUBROUTINE AD_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) IF (ALLOCATED(InitInputData%BladeRootOrientation)) THEN DEALLOCATE(InitInputData%BladeRootOrientation) ENDIF + CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedPrimaryInputData, ErrStat, ErrMsg ) END SUBROUTINE AD_DestroyInitInput SUBROUTINE AD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -409,6 +423,25 @@ SUBROUTINE AD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 2*3 ! BladeRootOrientation upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%BladeRootOrientation) ! BladeRootOrientation END IF + Int_BufSz = Int_BufSz + 1 ! UsePrimaryInputFile + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! PassedPrimaryInputData: size of buffers for each call to pack subtype + CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedPrimaryInputData, ErrStat2, ErrMsg2, .TRUE. ) ! PassedPrimaryInputData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! PassedPrimaryInputData + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! PassedPrimaryInputData + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! PassedPrimaryInputData + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -505,6 +538,36 @@ SUBROUTINE AD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg END DO END DO END IF + IntKiBuf(Int_Xferred) = TRANSFER(InData%UsePrimaryInputFile, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedPrimaryInputData, ErrStat2, ErrMsg2, OnlySize ) ! PassedPrimaryInputData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF END SUBROUTINE AD_PackInitInput SUBROUTINE AD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -618,6 +681,48 @@ SUBROUTINE AD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err END DO END DO END IF + OutData%UsePrimaryInputFile = TRANSFER(IntKiBuf(Int_Xferred), OutData%UsePrimaryInputFile) + Int_Xferred = Int_Xferred + 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackfileinfotype( Re_Buf, Db_Buf, Int_Buf, OutData%PassedPrimaryInputData, ErrStat2, ErrMsg2 ) ! PassedPrimaryInputData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END SUBROUTINE AD_UnPackInitInput SUBROUTINE AD_CopyBladePropsType( SrcBladePropsTypeData, DstBladePropsTypeData, CtrlCode, ErrStat, ErrMsg ) @@ -2492,6 +2597,7 @@ SUBROUTINE AD_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrSt ! ErrStat = ErrID_None ErrMsg = "" + DstInputFileData%Echo = SrcInputFileData%Echo DstInputFileData%DTAero = SrcInputFileData%DTAero DstInputFileData%WakeMod = SrcInputFileData%WakeMod DstInputFileData%AFAeroMod = SrcInputFileData%AFAeroMod @@ -2502,6 +2608,18 @@ SUBROUTINE AD_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrSt DstInputFileData%CavitCheck = SrcInputFileData%CavitCheck DstInputFileData%CompAA = SrcInputFileData%CompAA DstInputFileData%AA_InputFile = SrcInputFileData%AA_InputFile +IF (ALLOCATED(SrcInputFileData%ADBlFile)) THEN + i1_l = LBOUND(SrcInputFileData%ADBlFile,1) + i1_u = UBOUND(SrcInputFileData%ADBlFile,1) + IF (.NOT. ALLOCATED(DstInputFileData%ADBlFile)) THEN + ALLOCATE(DstInputFileData%ADBlFile(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%ADBlFile.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputFileData%ADBlFile = SrcInputFileData%ADBlFile +ENDIF DstInputFileData%AirDens = SrcInputFileData%AirDens DstInputFileData%KinVisc = SrcInputFileData%KinVisc DstInputFileData%Patm = SrcInputFileData%Patm @@ -2592,6 +2710,18 @@ SUBROUTINE AD_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrSt END IF END IF DstInputFileData%TwrCd = SrcInputFileData%TwrCd +ENDIF +IF (ALLOCATED(SrcInputFileData%TwrTI)) THEN + i1_l = LBOUND(SrcInputFileData%TwrTI,1) + i1_u = UBOUND(SrcInputFileData%TwrTI,1) + IF (.NOT. ALLOCATED(DstInputFileData%TwrTI)) THEN + ALLOCATE(DstInputFileData%TwrTI(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%TwrTI.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputFileData%TwrTI = SrcInputFileData%TwrTI ENDIF DstInputFileData%SumPrint = SrcInputFileData%SumPrint DstInputFileData%NBlOuts = SrcInputFileData%NBlOuts @@ -2639,6 +2769,9 @@ SUBROUTINE AD_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(InputFileData%ADBlFile)) THEN + DEALLOCATE(InputFileData%ADBlFile) +ENDIF IF (ALLOCATED(InputFileData%AFNames)) THEN DEALLOCATE(InputFileData%AFNames) ENDIF @@ -2657,6 +2790,9 @@ SUBROUTINE AD_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) IF (ALLOCATED(InputFileData%TwrCd)) THEN DEALLOCATE(InputFileData%TwrCd) ENDIF +IF (ALLOCATED(InputFileData%TwrTI)) THEN + DEALLOCATE(InputFileData%TwrTI) +ENDIF IF (ALLOCATED(InputFileData%OutList)) THEN DEALLOCATE(InputFileData%OutList) ENDIF @@ -2700,6 +2836,7 @@ SUBROUTINE AD_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! Echo Db_BufSz = Db_BufSz + 1 ! DTAero Int_BufSz = Int_BufSz + 1 ! WakeMod Int_BufSz = Int_BufSz + 1 ! AFAeroMod @@ -2710,6 +2847,11 @@ SUBROUTINE AD_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 1 ! CavitCheck Int_BufSz = Int_BufSz + 1 ! CompAA Int_BufSz = Int_BufSz + 1*LEN(InData%AA_InputFile) ! AA_InputFile + Int_BufSz = Int_BufSz + 1 ! ADBlFile allocated yes/no + IF ( ALLOCATED(InData%ADBlFile) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ADBlFile upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%ADBlFile)*LEN(InData%ADBlFile) ! ADBlFile + END IF Re_BufSz = Re_BufSz + 1 ! AirDens Re_BufSz = Re_BufSz + 1 ! KinVisc Re_BufSz = Re_BufSz + 1 ! Patm @@ -2780,6 +2922,11 @@ SUBROUTINE AD_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg IF ( ALLOCATED(InData%TwrCd) ) THEN Int_BufSz = Int_BufSz + 2*1 ! TwrCd upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%TwrCd) ! TwrCd + END IF + Int_BufSz = Int_BufSz + 1 ! TwrTI allocated yes/no + IF ( ALLOCATED(InData%TwrTI) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! TwrTI upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrTI) ! TwrTI END IF Int_BufSz = Int_BufSz + 1 ! SumPrint Int_BufSz = Int_BufSz + 1 ! NBlOuts @@ -2829,6 +2976,8 @@ SUBROUTINE AD_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Db_Xferred = 1 Int_Xferred = 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%Echo, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 DbKiBuf(Db_Xferred) = InData%DTAero Db_Xferred = Db_Xferred + 1 IntKiBuf(Int_Xferred) = InData%WakeMod @@ -2837,7 +2986,7 @@ SUBROUTINE AD_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%TwrPotent Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%TwrShadow, IntKiBuf(1)) + IntKiBuf(Int_Xferred) = InData%TwrShadow Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%TwrAero, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 @@ -2851,6 +3000,23 @@ SUBROUTINE AD_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg IntKiBuf(Int_Xferred) = ICHAR(InData%AA_InputFile(I:I), IntKi) Int_Xferred = Int_Xferred + 1 END DO ! I + IF ( .NOT. ALLOCATED(InData%ADBlFile) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ADBlFile,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ADBlFile,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ADBlFile,1), UBOUND(InData%ADBlFile,1) + DO I = 1, LEN(InData%ADBlFile) + IntKiBuf(Int_Xferred) = ICHAR(InData%ADBlFile(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF ReKiBuf(Re_Xferred) = InData%AirDens Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%KinVisc @@ -3009,6 +3175,21 @@ SUBROUTINE AD_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ReKiBuf(Re_Xferred) = InData%TwrCd(i1) Re_Xferred = Re_Xferred + 1 END DO + END IF + IF ( .NOT. ALLOCATED(InData%TwrTI) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrTI,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrTI,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%TwrTI,1), UBOUND(InData%TwrTI,1) + ReKiBuf(Re_Xferred) = InData%TwrTI(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF IntKiBuf(Int_Xferred) = TRANSFER(InData%SumPrint, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 @@ -3101,6 +3282,8 @@ SUBROUTINE AD_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 + OutData%Echo = TRANSFER(IntKiBuf(Int_Xferred), OutData%Echo) + Int_Xferred = Int_Xferred + 1 OutData%DTAero = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 OutData%WakeMod = IntKiBuf(Int_Xferred) @@ -3109,7 +3292,7 @@ SUBROUTINE AD_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Int_Xferred = Int_Xferred + 1 OutData%TwrPotent = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%TwrShadow = TRANSFER(IntKiBuf(Int_Xferred), OutData%TwrShadow) + OutData%TwrShadow = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%TwrAero = TRANSFER(IntKiBuf(Int_Xferred), OutData%TwrAero) Int_Xferred = Int_Xferred + 1 @@ -3123,6 +3306,26 @@ SUBROUTINE AD_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err OutData%AA_InputFile(I:I) = CHAR(IntKiBuf(Int_Xferred)) Int_Xferred = Int_Xferred + 1 END DO ! I + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ADBlFile not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ADBlFile)) DEALLOCATE(OutData%ADBlFile) + ALLOCATE(OutData%ADBlFile(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ADBlFile.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ADBlFile,1), UBOUND(OutData%ADBlFile,1) + DO I = 1, LEN(OutData%ADBlFile) + OutData%ADBlFile(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF OutData%AirDens = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%KinVisc = ReKiBuf(Re_Xferred) @@ -3308,6 +3511,24 @@ SUBROUTINE AD_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err OutData%TwrCd(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrTI not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%TwrTI)) DEALLOCATE(OutData%TwrTI) + ALLOCATE(OutData%TwrTI(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrTI.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%TwrTI,1), UBOUND(OutData%TwrTI,1) + OutData%TwrTI(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END IF OutData%SumPrint = TRANSFER(IntKiBuf(Int_Xferred), OutData%SumPrint) Int_Xferred = Int_Xferred + 1 @@ -7203,6 +7424,18 @@ SUBROUTINE AD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF END IF DstParamData%TwrCd = SrcParamData%TwrCd +ENDIF +IF (ALLOCATED(SrcParamData%TwrTI)) THEN + i1_l = LBOUND(SrcParamData%TwrTI,1) + i1_u = UBOUND(SrcParamData%TwrTI,1) + IF (.NOT. ALLOCATED(DstParamData%TwrTI)) THEN + ALLOCATE(DstParamData%TwrTI(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%TwrTI.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%TwrTI = SrcParamData%TwrTI ENDIF DstParamData%AirDens = SrcParamData%AirDens DstParamData%KinVisc = SrcParamData%KinVisc @@ -7345,6 +7578,9 @@ SUBROUTINE AD_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%TwrCd)) THEN DEALLOCATE(ParamData%TwrCd) ENDIF +IF (ALLOCATED(ParamData%TwrTI)) THEN + DEALLOCATE(ParamData%TwrTI) +ENDIF IF (ALLOCATED(ParamData%AFI)) THEN DO i1 = LBOUND(ParamData%AFI,1), UBOUND(ParamData%AFI,1) CALL AFI_DestroyParam( ParamData%AFI(i1), ErrStat, ErrMsg ) @@ -7435,6 +7671,11 @@ SUBROUTINE AD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si IF ( ALLOCATED(InData%TwrCd) ) THEN Int_BufSz = Int_BufSz + 2*1 ! TwrCd upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%TwrCd) ! TwrCd + END IF + Int_BufSz = Int_BufSz + 1 ! TwrTI allocated yes/no + IF ( ALLOCATED(InData%TwrTI) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! TwrTI upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrTI) ! TwrTI END IF Re_BufSz = Re_BufSz + 1 ! AirDens Re_BufSz = Re_BufSz + 1 ! KinVisc @@ -7627,7 +7868,7 @@ SUBROUTINE AD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%TwrPotent Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%TwrShadow, IntKiBuf(1)) + IntKiBuf(Int_Xferred) = InData%TwrShadow Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%TwrAero, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 @@ -7672,6 +7913,21 @@ SUBROUTINE AD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si ReKiBuf(Re_Xferred) = InData%TwrCd(i1) Re_Xferred = Re_Xferred + 1 END DO + END IF + IF ( .NOT. ALLOCATED(InData%TwrTI) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrTI,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrTI,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%TwrTI,1), UBOUND(InData%TwrTI,1) + ReKiBuf(Re_Xferred) = InData%TwrTI(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF ReKiBuf(Re_Xferred) = InData%AirDens Re_Xferred = Re_Xferred + 1 @@ -8021,7 +8277,7 @@ SUBROUTINE AD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Int_Xferred = Int_Xferred + 1 OutData%TwrPotent = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%TwrShadow = TRANSFER(IntKiBuf(Int_Xferred), OutData%TwrShadow) + OutData%TwrShadow = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%TwrAero = TRANSFER(IntKiBuf(Int_Xferred), OutData%TwrAero) Int_Xferred = Int_Xferred + 1 @@ -8072,6 +8328,24 @@ SUBROUTINE AD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg OutData%TwrCd(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrTI not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%TwrTI)) DEALLOCATE(OutData%TwrTI) + ALLOCATE(OutData%TwrTI(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrTI.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%TwrTI,1), UBOUND(OutData%TwrTI,1) + OutData%TwrTI(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END IF OutData%AirDens = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 diff --git a/modules/aerodyn/src/AirfoilInfo.f90 b/modules/aerodyn/src/AirfoilInfo.f90 index 8648733e2d..5787870b2f 100644 --- a/modules/aerodyn/src/AirfoilInfo.f90 +++ b/modules/aerodyn/src/AirfoilInfo.f90 @@ -592,7 +592,7 @@ SUBROUTINE ReadAFfile ( AFfile, NumCoefs, InCol_Alfa, InCol_Cl, InCol_Cd, InCol_ CALL ParseVar ( FileInfo, CurLine, 'C_nalpha', p%Table(iTable)%UA_BL%C_nalpha, ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - + !>>> add after this feature gets tested better: ! CALL ParseVar ( FileInfo, CurLine, 'C_lalpha', p%Table(iTable)%UA_BL%C_lalpha, ErrStat2, ErrMsg2, UnEc ) ! CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) diff --git a/modules/aerodyn/src/FVW.f90 b/modules/aerodyn/src/FVW.f90 index 3e1cd6912d..4a984e362f 100644 --- a/modules/aerodyn/src/FVW.f90 +++ b/modules/aerodyn/src/FVW.f90 @@ -467,7 +467,7 @@ end subroutine FVW_ToString !> This routine is called at the end of the simulation. subroutine FVW_End( u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) - type(FVW_InputType), intent(inout) :: u(:) !< System inputs + type(FVW_InputType),allocatable, intent(inout) :: u(:) !< System inputs type(FVW_ParameterType), intent(inout) :: p !< Parameters type(FVW_ContinuousStateType), intent(inout) :: x !< Continuous states type(FVW_DiscreteStateType), intent(inout) :: xd !< Discrete states @@ -486,9 +486,11 @@ subroutine FVW_End( u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) ! Place any last minute operations or calculations here: ! Close files here: ! Destroy the input data: - do i=1,size(u) - call FVW_DestroyInput( u(i), ErrStat, ErrMsg ) - enddo + if (allocated(u)) then + do i=1,size(u) + call FVW_DestroyInput( u(i), ErrStat, ErrMsg ) + enddo + endif ! Destroy the parameter data: call FVW_DestroyParam( p, ErrStat, ErrMsg ) diff --git a/modules/aerodyn/src/FVW_Wings.f90 b/modules/aerodyn/src/FVW_Wings.f90 index 431ab3403b..bad06fbce5 100644 --- a/modules/aerodyn/src/FVW_Wings.f90 +++ b/modules/aerodyn/src/FVW_Wings.f90 @@ -175,9 +175,13 @@ subroutine Wings_Panelling(Meshes, p, m, ErrStat, ErrMsg ) DP1 = P6-P8 DP2 = P10-P9 DP3 = P7-P5 + + ! NOTE: The denominator below has seg-faulted with Intel Fortran in Release mode, possibly due to nuances in copmiler optimizations. + ! This code was previously after the m%Norm calculations, but moving it up "fixes" the bug. + m%Tang(1:3,iSpan,iW) = (DP1)/TwoNorm(DP1) ! tangential unit vector, along chord + m%Norm(1:3,iSpan,iW) = cross_product(DP1,DP2) m%Norm(1:3,iSpan,iW) = m%Norm(1:3,iSpan,iW)/TwoNorm(m%Norm(1:3,iSpan,iW)) - m%Tang(1:3,iSpan,iW) = (DP1)/TwoNorm(DP1) ! tangential unit vector, along chord ! m%Tscoord(1:3,iSpan) = (DP3)/norm2(DP3) ! tangential unit vector, along span, follows ref line m%dl (1:3,iSpan,iW) = DP2 m%Orth(1:3,iSpan,iW) = cross_product(m%Norm(1:3,iSpan,iW),m%Tang(1:3,iSpan,iW)) ! orthogonal vector to N and T diff --git a/modules/beamdyn/src/BeamDyn_Subs.f90 b/modules/beamdyn/src/BeamDyn_Subs.f90 index 97a169dec1..4a47bbd5ba 100644 --- a/modules/beamdyn/src/BeamDyn_Subs.f90 +++ b/modules/beamdyn/src/BeamDyn_Subs.f90 @@ -973,7 +973,11 @@ SUBROUTINE BD_Interp_Pos_CRV(p, eta, POS, CRV, ErrStat, ErrMsg) INTEGER(IntKi) :: ErrStat2 ! Temporary Error status CHARACTER(ErrMsgLen) :: ErrMsg2 ! Temporary Error message + character(*), parameter :: RoutineName = 'BD_Interp_Pos_CRV' + ErrStat = ErrID_None + ErrMsg = "" + ! find element in which eta resides eta_right = 0._BDKi found = 0 @@ -993,24 +997,32 @@ SUBROUTINE BD_Interp_Pos_CRV(p, eta, POS, CRV, ErrStat, ErrMsg) eta_local(1) = 2._BDKi * (eta - eta_left)/p%member_eta(element) - 1._BDKi call AllocAry(gll, p%nodes_per_elem, "local GLL nodes",ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) call AllocAry(shp, p%nodes_per_elem, 1,"local shape function",ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) call AllocAry(shpder, p%nodes_per_elem, 1,"local shape deriv function",ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - call BD_GenerateGLL(p%nodes_per_elem,gll,ErrStat2,ErrMsg2) - call bd_diffmtc(p%nodes_per_elem, gll, eta_local, 1, shp, shpder) ! evaluate shp and shpder at single point - - pos = 0._BDki - crv = 0._BDki - do i = 1, p%nodes_per_elem - do j = 1, 3 - pos(j) = pos(j) + p%uuN0(j, i,element) *shp(i,1) - CRV(j) = CRV(j) + p%uuN0(j+3,i,element)*shp(i,1) - enddo - enddo + if (ErrStat < AbortErrLev) then + call BD_GenerateGLL(p%nodes_per_elem,gll,ErrStat2,ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call bd_diffmtc(p%nodes_per_elem, gll, eta_local, 1, shp, shpder) ! evaluate shp and shpder at single point + + pos = 0._BDki + crv = 0._BDki + do i = 1, p%nodes_per_elem + do j = 1, 3 + pos(j) = pos(j) + p%uuN0(j, i,element) *shp(i,1) + CRV(j) = CRV(j) + p%uuN0(j+3,i,element)*shp(i,1) + enddo + enddo - deallocate(gll) - deallocate(shp) - deallocate(shpder) + end if + + if (allocated(gll)) deallocate(gll) + if (allocated(shp)) deallocate(shp) + if (allocated(shpder)) deallocate(shpder) END SUBROUTINE BD_Interp_Pos_CRV !----------------------------------------------------------------------------------------------------------------------------------- diff --git a/modules/beamdyn/tests/test_BD_ComputeIniNodalCrv.F90 b/modules/beamdyn/tests/test_BD_ComputeIniNodalCrv.F90 new file mode 100644 index 0000000000..17f476db34 --- /dev/null +++ b/modules/beamdyn/tests/test_BD_ComputeIniNodalCrv.F90 @@ -0,0 +1,83 @@ +@test +subroutine test_BD_ComputeIniNodalCrv() + ! test branches + ! - simple rotation with known parameters: Pi on xaxis + ! - 0 rotation + ! - small rotation with baseline WM parameters calculated + + use pFUnit_mod + use BeamDyn_Subs + use NWTC_Num + use test_tools + + implicit none + + real(BDKi), dimension(3,3) :: r + real(BDKi), dimension(3) :: test_wmparams, baseline_wmparams + real(BDKi) :: angle, param, n(3) + character(1024) :: testname + real(BDKi) :: tolerance + integer(IntKi) :: ErrStat + character :: ErrMsg + + ! initialize NWTC_Num constants + call SetConstants() + + tolerance = 1e-14 + + ! -------------------------------------------------------------------------- + testname = "Tangent aligned with z-axis and 0 degree twist:" + n = (/ real(0.0, BDKi), real(0.0, BDKi), real(1.0, BDKi) /) ! tangent axis + angle = 0 + + ! Baseline Wiener-Milenkovic parameters + baseline_wmparams = (/ 0.0, 0.0, 0.0 /) + + call BD_ComputeIniNodalCrv(n, angle, test_wmparams, ErrStat, ErrMsg) + + @assertEqual(0.0_BDKi, ErrStat, tolerance, testname) + @assertEqual(baseline_wmparams, test_wmparams, tolerance, testname) + + ! -------------------------------------------------------------------------- + testname = "Tangent at 45 degree w.r.t. y-axis and 0 degree twist:" + n = (/ 1.0_BDKi/sqrt(2.0_BDKi), 0.0_BDKi, 1.0_BDKi/sqrt(2.0_BDKi) /) ! tangent axis + angle = 0.0_BDKi + + ! Baseline Wiener-Milenkovic parameters + param = 4*tan((Pi_D/4)/4) + baseline_wmparams = (/ real(0.0, BDKi), param, real(0.0, BDKi) /) + + call BD_ComputeIniNodalCrv(n, angle, test_wmparams, ErrStat, ErrMsg) + + @assertEqual(0.0_BDKi, ErrStat, tolerance, testname) + @assertEqual(baseline_wmparams, test_wmparams, tolerance, testname) + + ! -------------------------------------------------------------------------- + testname = "Tangent at -45 degree w.r.t. x-axis and 0 degree twist:" + n = (/ 0.0_BDKi, 1.0_BDKi/sqrt(2.0_BDKi), 1.0_BDKi/sqrt(2.0_BDKi) /) ! tangent axis + angle = 0.0_BDKi + + ! Baseline Wiener-Milenkovic parameters + param = 4*tan((-Pi_D/4)/4) + baseline_wmparams = (/ param, real(0.0, BDKi), real(0.0, BDKi) /) + + call BD_ComputeIniNodalCrv(n, angle, test_wmparams, ErrStat, ErrMsg) + + @assertEqual(0.0_BDKi, ErrStat, tolerance, testname) + @assertEqual(baseline_wmparams, test_wmparams, tolerance, testname) + + ! -------------------------------------------------------------------------- + testname = "Tangent along z-axis with 45 degree twist:" + n = (/ real(0.0, BDKi), real(0.0, BDKi), 1.0_BDKi /) ! tangent axis + angle = 45.0_BDKi + + ! Baseline Wiener-Milenkovic parameters + param = 4*tan((Pi_D/4)/4) + baseline_wmparams = (/ real(0.0, BDKi), real(0.0, BDKi), param /) + + call BD_ComputeIniNodalCrv(n, angle, test_wmparams, ErrStat, ErrMsg) + + @assertEqual(0.0_BDKi, ErrStat, tolerance, testname) + @assertEqual(baseline_wmparams, test_wmparams, tolerance, testname) + +end subroutine test_BD_ComputeIniNodalCrv diff --git a/modules/elastodyn/src/ElastoDyn.f90 b/modules/elastodyn/src/ElastoDyn.f90 index 2e0c2814e2..7bc2708c94 100644 --- a/modules/elastodyn/src/ElastoDyn.f90 +++ b/modules/elastodyn/src/ElastoDyn.f90 @@ -100,6 +100,7 @@ SUBROUTINE ED_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut INTEGER(IntKi) :: i ! loop counters LOGICAL, PARAMETER :: GetAdamsVals = .FALSE. ! Determines if we should read Adams values and create (update) an Adams model CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None + REAL(R8Ki) :: TransMat(3,3) ! Initial rotation matrix at Platform Refz ! Initialize variables for this routine @@ -240,7 +241,14 @@ SUBROUTINE ED_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut InitOut%BladeLength = p%TipRad - p%HubRad InitOut%TowerHeight = p%TwrFlexL InitOut%TowerBaseHeight = p%TowerBsHt + + ! Platform reference point wrt to global origin (0,0,0) InitOut%PlatformPos = x%QT(1:6) + CALL SmllRotTrans('initial platform rotation', x%QT(4), x%QT(5), x%QT(6), TransMat, '', ErrStat2, ErrMsg2) + InitOut%PlatformPos(1) = InitOut%PlatformPos(1) - TransMat(3,1)*p%PtfmRefzt + InitOut%PlatformPos(2) = InitOut%PlatformPos(2) - TransMat(3,2)*p%PtfmRefzt + InitOut%PlatformPos(3) = InitOut%PlatformPos(3) - TransMat(3,3)*p%PtfmRefzt + p%PtfmRefzt + InitOut%HubHt = p%HubHt InitOut%TwrBasePos = y%TowerLn2Mesh%Position(:,p%TwrNodes + 2) InitOut%HubRad = p%HubRad @@ -5255,10 +5263,18 @@ SUBROUTINE Coeff(p,InputFileData, ErrStat, ErrMsg) ! Calculate the tower natural frequencies: DO I = 1,2 ! Loop through all tower DOFs in one direction - p%FreqTFA(I,1) = Inv2Pi*SQRT( p%KTFA(I,I) /( MTFA(I,I) - p%TwrTpMass ) ) ! Natural tower I-fore-aft frequency w/o gravitational destiffening nor tower-top mass effects - p%FreqTFA(I,2) = Inv2Pi*SQRT( ( p%KTFA(I,I) + KTFAGrav(I,I) )/ MTFA(I,I) ) ! Natural tower I-fore-aft frequency w/ gravitational destiffening and tower-top mass effects - p%FreqTSS(I,1) = Inv2Pi*SQRT( p%KTSS(I,I) /( MTSS(I,I) - p%TwrTpMass ) ) ! Natural tower I-side-to-side frequency w/o gravitational destiffening nor tower-top mass effects - p%FreqTSS(I,2) = Inv2Pi*SQRT( ( p%KTSS(I,I) + KTSSGrav(I,I) )/ MTSS(I,I) ) ! Natural tower I-side-to-side frequency w/ gravitational destiffening and tower-top mass effects + if ( EqualRealNos(( MTFA(I,I) - p%TwrTpMass ), 0.0_ReKi) ) then + p%FreqTFA(I,1) = NaN ! Avoid creating a divide by zero signal, but set p%FreqTFA(I,1) = NaN + else + p%FreqTFA(I,1) = Inv2Pi*SQRT( p%KTFA(I,I)/( MTFA(I,I) - p%TwrTpMass ) ) ! Natural tower I-fore-aft frequency w/o gravitational destiffening nor tower-top mass effects + end if + if ( EqualRealNos(( MTSS(I,I) - p%TwrTpMass ), 0.0_ReKi) ) then + p%FreqTSS(I,1) = NaN ! Avoid creating a divide by zero signal, but set p%FreqTFS(I,1) = NaN + else + p%FreqTSS(I,1) = Inv2Pi*SQRT( p%KTSS(I,I)/( MTSS(I,I) - p%TwrTpMass ) ) ! Natural tower I-side-to-side frequency w/o gravitational destiffening nor tower-top mass effects + end if + p%FreqTFA(I,2) = Inv2Pi*SQRT( ( p%KTFA(I,I) + KTFAGrav(I,I) )/MTFA(I,I) ) ! Natural tower I-fore-aft frequency w/ gravitational destiffening and tower-top mass effects + p%FreqTSS(I,2) = Inv2Pi*SQRT( ( p%KTSS(I,I) + KTSSGrav(I,I) )/MTSS(I,I) ) ! Natural tower I-side-to-side frequency w/ gravitational destiffening and tower-top mass effects ENDDO ! I - All tower DOFs in one direction diff --git a/modules/extptfm/src/ExtPtfm_MCKF.f90 b/modules/extptfm/src/ExtPtfm_MCKF.f90 index e5c32f0337..0af5205be2 100644 --- a/modules/extptfm/src/ExtPtfm_MCKF.f90 +++ b/modules/extptfm/src/ExtPtfm_MCKF.f90 @@ -211,9 +211,11 @@ SUBROUTINE ExtPtfm_Init( InitInp, u, p, x, xd, z, OtherState, y, m, dt_gluecode, CALL AllocAry(InitOut%RotFrame_y, 6+p%NumOuts , 'RotFrame_y', ErrStat, ErrMsg); if(Failed()) return CALL AllocAry(InitOut%LinNames_x, 2*p%nCB , 'LinNames_x', ErrStat, ErrMsg); if(Failed()) return CALL AllocAry(InitOut%RotFrame_x, 2*p%nCB , 'RotFrame_x', ErrStat, ErrMsg); if(Failed()) return + CALL AllocAry(InitOut%DerivOrder_x, 2*p%nCB , 'DerivOrd_x', ErrStat, ErrMsg); if(Failed()) return CALL AllocAry(InitOut%LinNames_u, N_INPUTS , 'LinNames_u', ErrStat, ErrMsg); if(Failed()) return CALL AllocAry(InitOut%RotFrame_u, N_INPUTS , 'RotFrame_u', ErrStat, ErrMsg); if(Failed()) return CALL AllocAry(InitOut%IsLoad_u , N_INPUTS , 'IsLoad_u' , ErrStat, ErrMsg); if(Failed()) return + InitOut%DerivOrder_x(:)=2 ! LinNames_y do I=1,3; InitOut%LinNames_y(I) = 'Interface node '//XYZ(I)//' force, N' diff --git a/modules/extptfm/src/ExtPtfm_MCKF_Registry.txt b/modules/extptfm/src/ExtPtfm_MCKF_Registry.txt index df8b051a81..c75fee857d 100644 --- a/modules/extptfm/src/ExtPtfm_MCKF_Registry.txt +++ b/modules/extptfm/src/ExtPtfm_MCKF_Registry.txt @@ -54,6 +54,7 @@ typedef ^ ^ LOGICAL RotFrame_y { typedef ^ ^ LOGICAL RotFrame_x {:} - - "Flag that tells FAST/MBC3 if the continuous states used in linearization are in the rotating frame" - typedef ^ ^ LOGICAL RotFrame_u {:} - - "Flag that tells FAST/MBC3 if the inputs used in linearization are in the rotating frame" - typedef ^ ^ LOGICAL IsLoad_u {:} - - "Flag that tells FAST if the inputs used in linearization are loads (for preconditioning matrix)" - +typedef ^ ^ IntKi DerivOrder_x {:} - - "Integer that tells FAST/MBC3 the maximum derivative order of continuous states used in linearization" - # ..... States .................................................................................................................... diff --git a/modules/extptfm/src/ExtPtfm_MCKF_Types.f90 b/modules/extptfm/src/ExtPtfm_MCKF_Types.f90 index dcd7770cce..aac3e92fbc 100644 --- a/modules/extptfm/src/ExtPtfm_MCKF_Types.f90 +++ b/modules/extptfm/src/ExtPtfm_MCKF_Types.f90 @@ -73,6 +73,7 @@ MODULE ExtPtfm_MCKF_Types LOGICAL , DIMENSION(:), ALLOCATABLE :: RotFrame_x !< Flag that tells FAST/MBC3 if the continuous states used in linearization are in the rotating frame [-] LOGICAL , DIMENSION(:), ALLOCATABLE :: RotFrame_u !< Flag that tells FAST/MBC3 if the inputs used in linearization are in the rotating frame [-] LOGICAL , DIMENSION(:), ALLOCATABLE :: IsLoad_u !< Flag that tells FAST if the inputs used in linearization are loads (for preconditioning matrix) [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: DerivOrder_x !< Integer that tells FAST/MBC3 the maximum derivative order of continuous states used in linearization [-] END TYPE ExtPtfm_InitOutputType ! ======================= ! ========= ExtPtfm_ContinuousStateType ======= @@ -855,6 +856,18 @@ SUBROUTINE ExtPtfm_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCod END IF END IF DstInitOutputData%IsLoad_u = SrcInitOutputData%IsLoad_u +ENDIF +IF (ALLOCATED(SrcInitOutputData%DerivOrder_x)) THEN + i1_l = LBOUND(SrcInitOutputData%DerivOrder_x,1) + i1_u = UBOUND(SrcInitOutputData%DerivOrder_x,1) + IF (.NOT. ALLOCATED(DstInitOutputData%DerivOrder_x)) THEN + ALLOCATE(DstInitOutputData%DerivOrder_x(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%DerivOrder_x.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%DerivOrder_x = SrcInitOutputData%DerivOrder_x ENDIF END SUBROUTINE ExtPtfm_CopyInitOutput @@ -894,6 +907,9 @@ SUBROUTINE ExtPtfm_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(InitOutputData%IsLoad_u)) THEN DEALLOCATE(InitOutputData%IsLoad_u) +ENDIF +IF (ALLOCATED(InitOutputData%DerivOrder_x)) THEN + DEALLOCATE(InitOutputData%DerivOrder_x) ENDIF END SUBROUTINE ExtPtfm_DestroyInitOutput @@ -995,6 +1011,11 @@ SUBROUTINE ExtPtfm_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + 2*1 ! IsLoad_u upper/lower bounds for each dimension Int_BufSz = Int_BufSz + SIZE(InData%IsLoad_u) ! IsLoad_u END IF + Int_BufSz = Int_BufSz + 1 ! DerivOrder_x allocated yes/no + IF ( ALLOCATED(InData%DerivOrder_x) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! DerivOrder_x upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%DerivOrder_x) ! DerivOrder_x + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1195,6 +1216,21 @@ SUBROUTINE ExtPtfm_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_Xferred = Int_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%DerivOrder_x) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%DerivOrder_x,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DerivOrder_x,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%DerivOrder_x,1), UBOUND(InData%DerivOrder_x,1) + IntKiBuf(Int_Xferred) = InData%DerivOrder_x(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF END SUBROUTINE ExtPtfm_PackInitOutput SUBROUTINE ExtPtfm_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1436,6 +1472,24 @@ SUBROUTINE ExtPtfm_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Xferred = Int_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! DerivOrder_x not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%DerivOrder_x)) DEALLOCATE(OutData%DerivOrder_x) + ALLOCATE(OutData%DerivOrder_x(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%DerivOrder_x.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%DerivOrder_x,1), UBOUND(OutData%DerivOrder_x,1) + OutData%DerivOrder_x(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF END SUBROUTINE ExtPtfm_UnPackInitOutput SUBROUTINE ExtPtfm_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg ) diff --git a/modules/hydrodyn/CMakeLists.txt b/modules/hydrodyn/CMakeLists.txt index 5626c445fb..3c10213253 100644 --- a/modules/hydrodyn/CMakeLists.txt +++ b/modules/hydrodyn/CMakeLists.txt @@ -40,9 +40,7 @@ set(HYDRODYN_SOURCES src/UserWaves.f90 src/WAMIT.f90 src/WAMIT2.f90 - src/WAMIT2_Output.f90 src/WAMIT_Interp.f90 - src/WAMIT_Output.f90 src/Waves.f90 src/Waves2.f90 src/Waves2_Output.f90 diff --git a/modules/hydrodyn/src/Conv_Radiation.f90 b/modules/hydrodyn/src/Conv_Radiation.f90 index 54040d15a3..1aa6b961f9 100644 --- a/modules/hydrodyn/src/Conv_Radiation.f90 +++ b/modules/hydrodyn/src/Conv_Radiation.f90 @@ -55,23 +55,7 @@ MODULE Conv_Radiation CONTAINS -SUBROUTINE ShiftValuesLeft(XDHistory, NSteps) -! This routine shifts every entry in XDHistory such that XDHistory(K+1,I) is now stored in XDHistory(K,I) -! - REAL(ReKi), INTENT(INOUT) :: XDHistory (:,:) ! The time history of the 3 components of the translational velocity (in m/s) of the WAMIT reference and the 3 components of the rotational (angular) velocity (in rad/s) of the platform relative to the inertial frame - INTEGER(IntKi), INTENT(IN ) :: NSteps ! Number of elements in the array - - INTEGER(IntKi) :: I -! INTEGER(IntKi) :: J - INTEGER(IntKi) :: K - - DO K = 0,NSteps-2 - DO I = 1,6 ! Loop through all DOFs - XDHistory(K,I) = XDHistory(K+1,I) - END DO - END DO - -END SUBROUTINE ShiftValuesLeft + !---------------------------------------------------------------------------------------------------------------------------------- !> This routine is called at the start of the simulation to perform initialization steps. @@ -119,16 +103,18 @@ SUBROUTINE Conv_Rdtn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, TYPE(FFT_DataType) :: FFT_Data ! the instance of the FFT module we're using + ! Error handling + CHARACTER(1024) :: ErrMsg2 ! Temporary error message for calls + INTEGER(IntKi) :: ErrStat2 ! Temporary error status for calls ! Initialize ErrStat ErrStat = ErrID_None ErrMsg = "" -!TODO -!BJJ: This was uninitialized; not sure how it should be set >>> -!PRINT *, 'Greg, please initialize this variable:RdtnFrmA' -RdtnFrmAM = .FALSE. -!<<< + + ! For now, this is the only model we have implemented + RdtnFrmAM = .FALSE. + ! Initialize the NWTC Subroutine Library CALL NWTC_Init( ) @@ -139,7 +125,7 @@ SUBROUTINE Conv_Rdtn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, ! RdtnOmegaMax, Abort because RdtnDT must be reduced in order to have ! sufficient accuracy in the computation of the radiation impulse response ! functions: - + p%NBody = InitInp%NBody p%RdtnDT = InitInp%RdtnDT RdtnOmegaMax = Pi / InitInp%RdtnDT @@ -151,8 +137,8 @@ SUBROUTINE Conv_Rdtn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, RETURN END IF - - + call AllocAry( u%Velocity, 6*p%NBody, "u%Velocity" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Conv_Rdtn_Init' ) + call AllocAry( y%F_Rdtn , 6*p%NBody, "y%F_Rdtn" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Conv_Rdtn_Init' ) u%Velocity = 0.0 !this is an initial guess; @@ -190,14 +176,14 @@ SUBROUTINE Conv_Rdtn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, RETURN END IF - ALLOCATE ( p%RdtnKrnl (0:p%NStepRdtn-1,6,6) , STAT=ErrStat ) + ALLOCATE ( p%RdtnKrnl (0:p%NStepRdtn-1,6*p%NBody,6*p%NBody) , STAT=ErrStat ) IF ( ErrStat /= ErrID_None ) THEN ErrMsg = ' Error allocating memory for the RdtnKrnl array.' ErrStat = ErrID_Fatal RETURN END IF - ALLOCATE ( xd%XDHistory(0:p%NStepRdtn ,6 ) , STAT=ErrStat ) ! In the numerical convolution we must have NStepRdtn1 elements within the XDHistory array, which is one more than the NStepRdtn elements that are in the RdtnKrnl array + ALLOCATE ( xd%XDHistory(0:p%NStepRdtn ,6*p%NBody ) , STAT=ErrStat ) ! In the numerical convolution we must have NStepRdtn1 elements within the XDHistory array, which is one more than the NStepRdtn elements that are in the RdtnKrnl array IF ( ErrStat /= ErrID_None ) THEN ErrMsg = ' Error allocating memory for the XDHistory array.' ErrStat = ErrID_Fatal @@ -206,7 +192,7 @@ SUBROUTINE Conv_Rdtn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, ! Initialize all elements of the xd%XDHistory array with the intial values of u%Velocity DO K = 0,p%NStepRdtn-1 - DO J = 1,6 ! Loop through all DOFs + DO J = 1,6*p%NBody ! Loop through all DOFs xd%XDHistory(K,J) = u%Velocity(J) END DO END DO @@ -243,13 +229,13 @@ SUBROUTINE Conv_Rdtn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, ! Compute the upper-triangular portion (diagonal and above) of the sine ! transform of the wave radiation kernel: - Indx = 0 - DO J = 1,6 ! Loop through all rows of RdtnKrnl - DO K = J,6 ! Loop through all columns of RdtnKrnl above and including the diagonal - Indx = Indx + 1 + ! Indx = 0 + DO J = 1,6*p%NBody ! Loop through all rows of RdtnKrnl + DO K = 1,6*p%NBody ! Loop through all columns of RdtnKrnl above and including the diagonal + !Indx = Indx + 1 p%RdtnKrnl(I,J,K) = Krnl_Fact*Omega*( InterpStp( Omega, InitInp%HdroFreq(:), & - InitInp%HdroAddMs(: ,Indx), LastInd, InitInp%NInpFreq ) & - - InitInp%HdroAddMs(InitInp%NInpFreq,Indx) ) + InitInp%HdroAddMs(: ,J,K), LastInd, InitInp%NInpFreq ) & + - InitInp%HdroAddMs(InitInp%NInpFreq,J,K) ) END DO ! K - All columns of RdtnKrnl above and including the diagonal END DO ! J - All rows of RdtnKrnl @@ -269,16 +255,11 @@ SUBROUTINE Conv_Rdtn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, RETURN END IF - DO J = 1,6 ! Loop through all rows of RdtnKrnl - DO K = J,6 ! Loop through all columns of RdtnKrnl above and including the diagonal + DO J = 1,6*p%NBody ! Loop through all rows of RdtnKrnl + DO K = 1,6*p%NBody ! Loop through all columns of RdtnKrnl above and including the diagonal CALL ApplySINT( p%RdtnKrnl(:,J,K), FFT_Data, ErrStat ) IF ( ErrStat /= ErrID_None ) RETURN END DO ! K - All columns of RdtnKrnl above and including the diagonal - DO K = J+1,6 ! Loop through all rows of RdtnKrnl below the diagonal - DO I = 0,p%NStepRdtn-1 ! Loop through all frequency components (including zero) of the sine transform - p%RdtnKrnl(I,K,J) = p%RdtnKrnl(I,J,K) - END DO ! I - All frequency components (including zero) of the sine transform - END DO ! K - All rows of RdtnKrnl below the diagonal END DO ! J - All rows of RdtnKrnl CALL ExitSINT(FFT_Data, ErrStat) @@ -320,11 +301,11 @@ SUBROUTINE Conv_Rdtn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, ! Compute the upper-triangular portion (diagonal and above) of the cosine ! transform of the wave radiation kernel: - Indx = 0 - DO J = 1,6 ! Loop through all rows of RdtnKrnl - DO K = J,6 ! Loop through all columns of RdtnKrnl above and including the diagonal - Indx = Indx + 1 - p%RdtnKrnl(I,J,K) = Krnl_Fact*InterpStp ( Omega, InitInp%HdroFreq(:), InitInp%HdroDmpng(:,Indx), LastInd, InitInp%NInpFreq ) + !Indx = 0 + DO J = 1,6*p%NBody ! Loop through all rows of RdtnKrnl + DO K = 1,6*p%NBody ! Loop through all columns of RdtnKrnl above and including the diagonal + !Indx = Indx + 1 + p%RdtnKrnl(I,J,K) = Krnl_Fact*InterpStp ( Omega, InitInp%HdroFreq(:), InitInp%HdroDmpng(:,J,K), LastInd, InitInp%NInpFreq ) END DO ! K - All columns of RdtnKrnl above and including the diagonal END DO ! J - All rows of RdtnKrnl @@ -343,8 +324,8 @@ SUBROUTINE Conv_Rdtn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, RETURN END IF - DO J = 1,6 ! Loop through all rows of RdtnKrnl - DO K = J,6 ! Loop through all columns of RdtnKrnl above and including the diagonal + DO J = 1,6*p%NBody ! Loop through all rows of RdtnKrnl + DO K = 1,6*p%NBody ! Loop through all columns of RdtnKrnl above and including the diagonal CALL ApplyCOST( p%RdtnKrnl(:,J,K), FFT_Data, ErrStat ) IF ( ErrStat /= ErrID_None ) THEN ErrMsg = 'Error applying Cosine Transform' @@ -352,11 +333,6 @@ SUBROUTINE Conv_Rdtn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, RETURN END IF END DO ! K - All columns of RdtnKrnl above and including the diagonal - DO K = J+1,6 ! Loop through all rows of RdtnKrnl below the diagonal - DO I = 0,p%NStepRdtn-1 ! Loop through all radiation time steps - p%RdtnKrnl(I,K,J) = p%RdtnKrnl(I,J,K) - END DO ! I - All radiation time steps - END DO ! K - All rows of RdtnKrnl below the diagonal END DO ! J - All rows of RdtnKrnl CALL ExitCOST(FFT_Data, ErrStat) @@ -388,10 +364,8 @@ SUBROUTINE Conv_Rdtn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, !END IF - IF ( ALLOCATED( RdtnTime ) ) DEALLOCATE( RdtnTime ) + IF ( ALLOCATED( RdtnTime ) ) DEALLOCATE( RdtnTime ) - - ! If you want to choose your own rate instead of using what the glue code suggests, tell the glue code the rate at which ! this module must be called here: @@ -494,7 +468,8 @@ SUBROUTINE Conv_Rdtn_UpdateStates( t, n, Inputs, InputTimes, p, x, xd, z, OtherS TYPE(Conv_Rdtn_InputType) :: u !< Instantaneous inputs INTEGER(IntKi) :: ErrStat2 !< Error status of the operation (secondary error) CHARACTER(ErrMsgLen) :: ErrMsg2 !< Error message if ErrStat2 /= ErrID_None - + character(*), parameter :: RoutineName = 'Conv_Rdtn_UpdateStates' + ! Initialize variables @@ -507,8 +482,12 @@ SUBROUTINE Conv_Rdtn_UpdateStates( t, n, Inputs, InputTimes, p, x, xd, z, OtherS ! Get the inputs at time t, based on the array of values sent by the glue code: + call Conv_Rdtn_CopyInput( Inputs(1), u, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + - CALL Conv_Rdtn_Input_ExtrapInterp( Inputs, InputTimes, u, t, ErrStat, ErrMsg ) + CALL Conv_Rdtn_Input_ExtrapInterp( Inputs, InputTimes, u, t, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) RETURN @@ -516,7 +495,8 @@ SUBROUTINE Conv_Rdtn_UpdateStates( t, n, Inputs, InputTimes, p, x, xd, z, OtherS ! Note that xd [discrete state] is changed in Conv_Rdtn_UpdateDiscState() so xd will now contain values at t+Interval ! We'll first make a copy that contains xd at time t, which will be used in computing the constraint states - CALL Conv_Rdtn_UpdateDiscState( t, n, u, p, x, xd, z, OtherState, m, ErrStat, ErrMsg ) + CALL Conv_Rdtn_UpdateDiscState( t, n, u, p, x, xd, z, OtherState, m, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Integrate (update) continuous states (x) here: @@ -550,7 +530,7 @@ SUBROUTINE Conv_Rdtn_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None ! REAL(ReKi) :: F_Rdtn (6) - REAL(ReKi) :: F_RdtnDT (6) ! The portion of the total load contribution from wave radiation damping associated with the convolution integral proportional to ( RdtnDT - RdtnRmndr ) (N, N-m) + REAL(ReKi) :: F_RdtnDT (6*p%NBody) ! The portion of the total load contribution from wave radiation damping associated with the convolution integral proportional to ( RdtnDT - RdtnRmndr ) (N, N-m) INTEGER :: I ! Generic index INTEGER :: J ! Generic index @@ -568,12 +548,12 @@ SUBROUTINE Conv_Rdtn_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat MaxInd = MIN(p%NStepRdtn-1,OtherState%IndRdtn) ! Note: xd%IndRdtn index is from the previous time-step since this state was for the previous time-step - DO I = 1,6 ! Loop through all wave radiation damping forces and moments + DO I = 1,6*p%NBody ! Loop through all wave radiation damping forces and moments F_RdtnDT (I) = 0.0 ! F_RdtnRmndr(I) = 0.0 - DO J = 1,6 ! Loop through all platform DOFs + DO J = 1,6*p%NBody ! Loop through all platform DOFs DO K = 0, MaxInd ! Loop through all NStepRdtn time steps in the radiation Kernel (less than NStepRdtn time steps are used when ZTime < RdtnTmax) F_RdtnDT(I) = F_RdtnDT(I) - p%RdtnKrnl(MaxInd-K,I,J)*xd%XDHistory(K,J) @@ -655,9 +635,8 @@ SUBROUTINE Conv_Rdtn_UpdateDiscState( Time, n, u, p, x, xd, z, OtherState, m, Er ErrStat = ErrID_None ErrMsg = "" - - - + + ! Find the index xd%IndRdtn, where RdtnTime(IndRdtn) is the largest value in ! RdtnTime(:) that is less than or equal to Time and find the amount of ! time remaining from this calculation: @@ -689,64 +668,21 @@ SUBROUTINE Conv_Rdtn_UpdateDiscState( Time, n, u, p, x, xd, z, OtherState, m, Er !BJJ: this needs a better check so that it is ALWAYS done (MATLAB/Simulink could possibly avoid this step by starting at Time>0, OR there may be some numerical issues where this is NOT EXACTLY zero) IF ( OtherState%IndRdtn < (p%NStepRdtn) ) THEN - DO J = 1,6 ! Loop through all platform DOFs + DO J = 1,6*p%NBody ! Loop through all platform DOFs xd%XDHistory(OtherState%IndRdtn,J) = u%Velocity(J) ! XDHistory was allocated as a zero-based array! END DO ! J - All platform DOFs ELSE - !CALL ShiftValuesLeft( xd%XDHistory, p%NStepRdtn ) ! This is NOT to be used GJH + ! Shift the stored history by one index DO K = 0,p%NStepRdtn-2 - DO J = 1,6 ! Loop through all DOFs + DO J = 1,6*p%NBody ! Loop through all DOFs xd%XDHistory(K,J) = xd%XDHistory(K+1,J) END DO END DO - DO J = 1,6 ! Loop through all platform DOFs + DO J = 1,6*p%NBody ! Loop through all platform DOFs xd%XDHistory(p%NStepRdtn-1,J) = u%Velocity(J) ! Set the last array element to the current velocity END DO ! J - All platform DOFs END IF - - ! IF ( Time == 0.0_DbKi ) THEN ! (1) .TRUE. if we are on the initialization pass where Time = 0.0 (and IndRdtn = 0) - ! - ! DO J = 1,6 ! Loop through all platform DOFs - ! xd%XDHistory(xd%IndRdtn,J) = u%Velocity(J) - ! END DO ! J - All platform DOFs - ! - ! xd%LastIndRdtn = xd%IndRdtn ! Save the value of IndRdtn for the next call to this routine (in this case IndRdtn = 0) - ! - ! ELSEIF ( xd%IndRdtn > xd%LastIndRdtn ) THEN ! (2) .TRUE. if we have increased in time by at least RdtnDT - ! - ! DO J = 1,6 ! Loop through all platform DOFs - ! - ! IncrmntUD = ( p%RdtnDT/( Time - ( xd%LastIndRdtn*p%RdtnDT ) ) ) * & - ! ( u%Velocity(J) - xd%XDHistory(MOD(xd%LastIndRdtn ,p%NStepRdtn1),J) ) - ! - ! DO K = xd%LastIndRdtn +1,xd%IndRdtn ! Loop through all radiation time steps where the time history of UD has yet to be stored - ! xd%XDHistory(MOD(K,p%NStepRdtn1),J) = xd%XDHistory(MOD(xd%LastIndRdtn ,p%NStepRdtn1),J) & - ! + ( K - xd%LastIndRdtn )*IncrmntUD - ! END DO ! K - All radiation time steps where the time history of UD has yet to be stored - ! - ! END DO ! J - All platform DOFs - ! - ! xd%LastIndRdtn2 = xd%LastIndRdtn ! Save the value of LastIndRdtn for the next call to this routine - ! xd%LastIndRdtn = xd%IndRdtn ! Save the value of IndRdtn for the next call to this routine - ! xd%LastTime = Time ! Save the value of Time associated with LastIndRdtn for the next call to this routine - ! - !!BJJ: this needs a better check in case there may be some numerical issues where this is NOT EXACTLY the same... - ! ELSEIF ( Time == xd%LastTime ) THEN ! (3). .TRUE. if the time has not changed since the last time we have increased in time by at least RdtnDt (i.e., on a call to the corrector) - ! - ! DO J = 1,6 ! Loop through all platform DOFs - ! - ! IncrmntUD = ( p%RdtnDT/( Time - ( xd%LastIndRdtn2*p%RdtnDT ) ) ) * & - ! ( u%Velocity(J) - xd%XDHistory(MOD(xd%LastIndRdtn2,p%NStepRdtn1),J) ) - ! - ! DO K = xd%LastIndRdtn2+1,xd%IndRdtn ! Loop through all radiation time steps where the time history of UD should be updated - ! xd%XDHistory(MOD(K,p%NStepRdtn1),J) = xd%XDHistory(MOD(xd%LastIndRdtn2,p%NStepRdtn1),J) & - ! + ( K - xd%LastIndRdtn2 )*IncrmntUD - ! END DO ! K - All radiation time steps where the time history of UD should be updated - ! - ! END DO ! J - All platform DOFs - ! - ! END IF END SUBROUTINE Conv_Rdtn_UpdateDiscState !---------------------------------------------------------------------------------------------------------------------------------- diff --git a/modules/hydrodyn/src/Conv_Radiation.txt b/modules/hydrodyn/src/Conv_Radiation.txt index 82a4f09dc4..e421042b54 100644 --- a/modules/hydrodyn/src/Conv_Radiation.txt +++ b/modules/hydrodyn/src/Conv_Radiation.txt @@ -20,11 +20,12 @@ include Registry_NWTC_Library.txt # typedef Conv_Radiation/Conv_Rdtn InitInputType DbKi RdtnDT - - - "" - typedef ^ ^ CHARACTER(80) RdtnDTChr +typedef ^ ^ INTEGER NBody - - - "[>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6]" - typedef ^ ^ ReKi HighFreq - - - "" - typedef ^ ^ CHARACTER(1024) WAMITFile - - - "" - -typedef ^ ^ SiKi HdroAddMs {:}{:} - - "" - +typedef ^ ^ SiKi HdroAddMs {:}{:}{:} - - "" - typedef ^ ^ SiKi HdroFreq {:} - - "" - -typedef ^ ^ SiKi HdroDmpng {:}{:} - - "" - +typedef ^ ^ SiKi HdroDmpng {:}{:}{:} - - "" - typedef ^ ^ INTEGER NInpFreq - - - "" - typedef ^ ^ DbKi RdtnTMax - - - "" - typedef ^ ^ INTEGER UnSum - - - "" - @@ -67,6 +68,7 @@ typedef ^ MiscVarType INTEGER # typedef ^ ParameterType DbKi DT - - - "Time step for continuous state integration & discrete state update" seconds typedef ^ ^ DbKi RdtnDT - - - "" - +typedef ^ ^ INTEGER NBody - - - "[>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6]" - typedef ^ ^ SiKi RdtnKrnl {:}{:}{:} - - "" - typedef ^ ^ INTEGER NStepRdtn - - - "" - typedef ^ ^ INTEGER NStepRdtn1 - - - "" - @@ -77,11 +79,11 @@ typedef ^ ^ INTEGER # #typedef^ InputType MeshType MeshedInput - - - "Meshed input data" - # Define inputs that are not on this mesh here: -typedef ^ InputType ReKi Velocity {6} - - "" - +typedef ^ InputType ReKi Velocity {:} - - "" - # # # ..... Outputs ................................................................................................................... # Define outputs that are contained on the mesh here: #typedef^ OutputType MeshType MeshedOutput - - - "Meshed output data" - # Define outputs that are not on this mesh here: -typedef ^ OutputType ReKi F_Rdtn {6} - - "" - +typedef ^ OutputType ReKi F_Rdtn {:} - - "" - diff --git a/modules/hydrodyn/src/Conv_Radiation_Types.f90 b/modules/hydrodyn/src/Conv_Radiation_Types.f90 index cbbf1b3868..d9188b01d3 100644 --- a/modules/hydrodyn/src/Conv_Radiation_Types.f90 +++ b/modules/hydrodyn/src/Conv_Radiation_Types.f90 @@ -37,11 +37,12 @@ MODULE Conv_Radiation_Types TYPE, PUBLIC :: Conv_Rdtn_InitInputType REAL(DbKi) :: RdtnDT !< [-] CHARACTER(80) :: RdtnDTChr + INTEGER(IntKi) :: NBody !< [>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6] [-] REAL(ReKi) :: HighFreq !< [-] CHARACTER(1024) :: WAMITFile !< [-] - REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: HdroAddMs !< [-] + REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: HdroAddMs !< [-] REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: HdroFreq !< [-] - REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: HdroDmpng !< [-] + REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: HdroDmpng !< [-] INTEGER(IntKi) :: NInpFreq !< [-] REAL(DbKi) :: RdtnTMax !< [-] INTEGER(IntKi) :: UnSum !< [-] @@ -82,6 +83,7 @@ MODULE Conv_Radiation_Types TYPE, PUBLIC :: Conv_Rdtn_ParameterType REAL(DbKi) :: DT !< Time step for continuous state integration & discrete state update [seconds] REAL(DbKi) :: RdtnDT !< [-] + INTEGER(IntKi) :: NBody !< [>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6] [-] REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: RdtnKrnl !< [-] INTEGER(IntKi) :: NStepRdtn !< [-] INTEGER(IntKi) :: NStepRdtn1 !< [-] @@ -89,12 +91,12 @@ MODULE Conv_Radiation_Types ! ======================= ! ========= Conv_Rdtn_InputType ======= TYPE, PUBLIC :: Conv_Rdtn_InputType - REAL(ReKi) , DIMENSION(1:6) :: Velocity !< [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Velocity !< [-] END TYPE Conv_Rdtn_InputType ! ======================= ! ========= Conv_Rdtn_OutputType ======= TYPE, PUBLIC :: Conv_Rdtn_OutputType - REAL(ReKi) , DIMENSION(1:6) :: F_Rdtn !< [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: F_Rdtn !< [-] END TYPE Conv_Rdtn_OutputType ! ======================= CONTAINS @@ -117,6 +119,7 @@ SUBROUTINE Conv_Rdtn_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode ErrMsg = "" DstInitInputData%RdtnDT = SrcInitInputData%RdtnDT DstInitInputData%RdtnDTChr = SrcInitInputData%RdtnDTChr + DstInitInputData%NBody = SrcInitInputData%NBody DstInitInputData%HighFreq = SrcInitInputData%HighFreq DstInitInputData%WAMITFile = SrcInitInputData%WAMITFile IF (ALLOCATED(SrcInitInputData%HdroAddMs)) THEN @@ -124,8 +127,10 @@ SUBROUTINE Conv_Rdtn_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode i1_u = UBOUND(SrcInitInputData%HdroAddMs,1) i2_l = LBOUND(SrcInitInputData%HdroAddMs,2) i2_u = UBOUND(SrcInitInputData%HdroAddMs,2) + i3_l = LBOUND(SrcInitInputData%HdroAddMs,3) + i3_u = UBOUND(SrcInitInputData%HdroAddMs,3) IF (.NOT. ALLOCATED(DstInitInputData%HdroAddMs)) THEN - ALLOCATE(DstInitInputData%HdroAddMs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + ALLOCATE(DstInitInputData%HdroAddMs(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%HdroAddMs.', ErrStat, ErrMsg,RoutineName) RETURN @@ -150,8 +155,10 @@ SUBROUTINE Conv_Rdtn_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode i1_u = UBOUND(SrcInitInputData%HdroDmpng,1) i2_l = LBOUND(SrcInitInputData%HdroDmpng,2) i2_u = UBOUND(SrcInitInputData%HdroDmpng,2) + i3_l = LBOUND(SrcInitInputData%HdroDmpng,3) + i3_u = UBOUND(SrcInitInputData%HdroDmpng,3) IF (.NOT. ALLOCATED(DstInitInputData%HdroDmpng)) THEN - ALLOCATE(DstInitInputData%HdroDmpng(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + ALLOCATE(DstInitInputData%HdroDmpng(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%HdroDmpng.', ErrStat, ErrMsg,RoutineName) RETURN @@ -221,11 +228,12 @@ SUBROUTINE Conv_Rdtn_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = 0 Db_BufSz = Db_BufSz + 1 ! RdtnDT Int_BufSz = Int_BufSz + 1*LEN(InData%RdtnDTChr) ! RdtnDTChr + Int_BufSz = Int_BufSz + 1 ! NBody Re_BufSz = Re_BufSz + 1 ! HighFreq Int_BufSz = Int_BufSz + 1*LEN(InData%WAMITFile) ! WAMITFile Int_BufSz = Int_BufSz + 1 ! HdroAddMs allocated yes/no IF ( ALLOCATED(InData%HdroAddMs) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! HdroAddMs upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + 2*3 ! HdroAddMs upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%HdroAddMs) ! HdroAddMs END IF Int_BufSz = Int_BufSz + 1 ! HdroFreq allocated yes/no @@ -235,7 +243,7 @@ SUBROUTINE Conv_Rdtn_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF Int_BufSz = Int_BufSz + 1 ! HdroDmpng allocated yes/no IF ( ALLOCATED(InData%HdroDmpng) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! HdroDmpng upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + 2*3 ! HdroDmpng upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%HdroDmpng) ! HdroDmpng END IF Int_BufSz = Int_BufSz + 1 ! NInpFreq @@ -274,6 +282,8 @@ SUBROUTINE Conv_Rdtn_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, IntKiBuf(Int_Xferred) = ICHAR(InData%RdtnDTChr(I:I), IntKi) Int_Xferred = Int_Xferred + 1 END DO ! I + IntKiBuf(Int_Xferred) = InData%NBody + Int_Xferred = Int_Xferred + 1 ReKiBuf(Re_Xferred) = InData%HighFreq Re_Xferred = Re_Xferred + 1 DO I = 1, LEN(InData%WAMITFile) @@ -291,12 +301,17 @@ SUBROUTINE Conv_Rdtn_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_Xferred = Int_Xferred + 2 IntKiBuf( Int_Xferred ) = LBOUND(InData%HdroAddMs,2) IntKiBuf( Int_Xferred + 1) = UBOUND(InData%HdroAddMs,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%HdroAddMs,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%HdroAddMs,3) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%HdroAddMs,2), UBOUND(InData%HdroAddMs,2) - DO i1 = LBOUND(InData%HdroAddMs,1), UBOUND(InData%HdroAddMs,1) - ReKiBuf(Re_Xferred) = InData%HdroAddMs(i1,i2) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(InData%HdroAddMs,3), UBOUND(InData%HdroAddMs,3) + DO i2 = LBOUND(InData%HdroAddMs,2), UBOUND(InData%HdroAddMs,2) + DO i1 = LBOUND(InData%HdroAddMs,1), UBOUND(InData%HdroAddMs,1) + ReKiBuf(Re_Xferred) = InData%HdroAddMs(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END IF @@ -326,12 +341,17 @@ SUBROUTINE Conv_Rdtn_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_Xferred = Int_Xferred + 2 IntKiBuf( Int_Xferred ) = LBOUND(InData%HdroDmpng,2) IntKiBuf( Int_Xferred + 1) = UBOUND(InData%HdroDmpng,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%HdroDmpng,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%HdroDmpng,3) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%HdroDmpng,2), UBOUND(InData%HdroDmpng,2) - DO i1 = LBOUND(InData%HdroDmpng,1), UBOUND(InData%HdroDmpng,1) - ReKiBuf(Re_Xferred) = InData%HdroDmpng(i1,i2) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(InData%HdroDmpng,3), UBOUND(InData%HdroDmpng,3) + DO i2 = LBOUND(InData%HdroDmpng,2), UBOUND(InData%HdroDmpng,2) + DO i1 = LBOUND(InData%HdroDmpng,1), UBOUND(InData%HdroDmpng,1) + ReKiBuf(Re_Xferred) = InData%HdroDmpng(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END IF @@ -378,6 +398,8 @@ SUBROUTINE Conv_Rdtn_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt OutData%RdtnDTChr(I:I) = CHAR(IntKiBuf(Int_Xferred)) Int_Xferred = Int_Xferred + 1 END DO ! I + OutData%NBody = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%HighFreq = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 DO I = 1, LEN(OutData%WAMITFile) @@ -394,16 +416,21 @@ SUBROUTINE Conv_Rdtn_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 IF (ALLOCATED(OutData%HdroAddMs)) DEALLOCATE(OutData%HdroAddMs) - ALLOCATE(OutData%HdroAddMs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + ALLOCATE(OutData%HdroAddMs(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%HdroAddMs.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%HdroAddMs,2), UBOUND(OutData%HdroAddMs,2) - DO i1 = LBOUND(OutData%HdroAddMs,1), UBOUND(OutData%HdroAddMs,1) - OutData%HdroAddMs(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(OutData%HdroAddMs,3), UBOUND(OutData%HdroAddMs,3) + DO i2 = LBOUND(OutData%HdroAddMs,2), UBOUND(OutData%HdroAddMs,2) + DO i1 = LBOUND(OutData%HdroAddMs,1), UBOUND(OutData%HdroAddMs,1) + OutData%HdroAddMs(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END IF @@ -435,16 +462,21 @@ SUBROUTINE Conv_Rdtn_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 IF (ALLOCATED(OutData%HdroDmpng)) DEALLOCATE(OutData%HdroDmpng) - ALLOCATE(OutData%HdroDmpng(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + ALLOCATE(OutData%HdroDmpng(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%HdroDmpng.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%HdroDmpng,2), UBOUND(OutData%HdroDmpng,2) - DO i1 = LBOUND(OutData%HdroDmpng,1), UBOUND(OutData%HdroDmpng,1) - OutData%HdroDmpng(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(OutData%HdroDmpng,3), UBOUND(OutData%HdroDmpng,3) + DO i2 = LBOUND(OutData%HdroDmpng,2), UBOUND(OutData%HdroDmpng,2) + DO i1 = LBOUND(OutData%HdroDmpng,1), UBOUND(OutData%HdroDmpng,1) + OutData%HdroDmpng(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END IF @@ -1294,6 +1326,7 @@ SUBROUTINE Conv_Rdtn_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, E ErrMsg = "" DstParamData%DT = SrcParamData%DT DstParamData%RdtnDT = SrcParamData%RdtnDT + DstParamData%NBody = SrcParamData%NBody IF (ALLOCATED(SrcParamData%RdtnKrnl)) THEN i1_l = LBOUND(SrcParamData%RdtnKrnl,1) i1_u = UBOUND(SrcParamData%RdtnKrnl,1) @@ -1365,6 +1398,7 @@ SUBROUTINE Conv_Rdtn_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Int_BufSz = 0 Db_BufSz = Db_BufSz + 1 ! DT Db_BufSz = Db_BufSz + 1 ! RdtnDT + Int_BufSz = Int_BufSz + 1 ! NBody Int_BufSz = Int_BufSz + 1 ! RdtnKrnl allocated yes/no IF ( ALLOCATED(InData%RdtnKrnl) ) THEN Int_BufSz = Int_BufSz + 2*3 ! RdtnKrnl upper/lower bounds for each dimension @@ -1403,6 +1437,8 @@ SUBROUTINE Conv_Rdtn_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Db_Xferred = Db_Xferred + 1 DbKiBuf(Db_Xferred) = InData%RdtnDT Db_Xferred = Db_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NBody + Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%RdtnKrnl) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -1467,6 +1503,8 @@ SUBROUTINE Conv_Rdtn_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Db_Xferred = Db_Xferred + 1 OutData%RdtnDT = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 + OutData%NBody = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! RdtnKrnl not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -1516,7 +1554,18 @@ SUBROUTINE Conv_Rdtn_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, E ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(SrcInputData%Velocity)) THEN + i1_l = LBOUND(SrcInputData%Velocity,1) + i1_u = UBOUND(SrcInputData%Velocity,1) + IF (.NOT. ALLOCATED(DstInputData%Velocity)) THEN + ALLOCATE(DstInputData%Velocity(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%Velocity.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInputData%Velocity = SrcInputData%Velocity +ENDIF END SUBROUTINE Conv_Rdtn_CopyInput SUBROUTINE Conv_Rdtn_DestroyInput( InputData, ErrStat, ErrMsg ) @@ -1528,6 +1577,9 @@ SUBROUTINE Conv_Rdtn_DestroyInput( InputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(InputData%Velocity)) THEN + DEALLOCATE(InputData%Velocity) +ENDIF END SUBROUTINE Conv_Rdtn_DestroyInput SUBROUTINE Conv_Rdtn_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1565,7 +1617,11 @@ SUBROUTINE Conv_Rdtn_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! Velocity allocated yes/no + IF ( ALLOCATED(InData%Velocity) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Velocity upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Velocity) ! Velocity + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1593,10 +1649,21 @@ SUBROUTINE Conv_Rdtn_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Db_Xferred = 1 Int_Xferred = 1 - DO i1 = LBOUND(InData%Velocity,1), UBOUND(InData%Velocity,1) - ReKiBuf(Re_Xferred) = InData%Velocity(i1) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( .NOT. ALLOCATED(InData%Velocity) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Velocity,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Velocity,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Velocity,1), UBOUND(InData%Velocity,1) + ReKiBuf(Re_Xferred) = InData%Velocity(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE Conv_Rdtn_PackInput SUBROUTINE Conv_Rdtn_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1626,12 +1693,24 @@ SUBROUTINE Conv_Rdtn_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - i1_l = LBOUND(OutData%Velocity,1) - i1_u = UBOUND(OutData%Velocity,1) - DO i1 = LBOUND(OutData%Velocity,1), UBOUND(OutData%Velocity,1) - OutData%Velocity(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Velocity not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Velocity)) DEALLOCATE(OutData%Velocity) + ALLOCATE(OutData%Velocity(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Velocity.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Velocity,1), UBOUND(OutData%Velocity,1) + OutData%Velocity(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE Conv_Rdtn_UnPackInput SUBROUTINE Conv_Rdtn_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -1649,7 +1728,18 @@ SUBROUTINE Conv_Rdtn_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(SrcOutputData%F_Rdtn)) THEN + i1_l = LBOUND(SrcOutputData%F_Rdtn,1) + i1_u = UBOUND(SrcOutputData%F_Rdtn,1) + IF (.NOT. ALLOCATED(DstOutputData%F_Rdtn)) THEN + ALLOCATE(DstOutputData%F_Rdtn(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%F_Rdtn.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstOutputData%F_Rdtn = SrcOutputData%F_Rdtn +ENDIF END SUBROUTINE Conv_Rdtn_CopyOutput SUBROUTINE Conv_Rdtn_DestroyOutput( OutputData, ErrStat, ErrMsg ) @@ -1661,6 +1751,9 @@ SUBROUTINE Conv_Rdtn_DestroyOutput( OutputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(OutputData%F_Rdtn)) THEN + DEALLOCATE(OutputData%F_Rdtn) +ENDIF END SUBROUTINE Conv_Rdtn_DestroyOutput SUBROUTINE Conv_Rdtn_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1698,7 +1791,11 @@ SUBROUTINE Conv_Rdtn_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! F_Rdtn allocated yes/no + IF ( ALLOCATED(InData%F_Rdtn) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! F_Rdtn upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%F_Rdtn) ! F_Rdtn + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1726,10 +1823,21 @@ SUBROUTINE Conv_Rdtn_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Db_Xferred = 1 Int_Xferred = 1 - DO i1 = LBOUND(InData%F_Rdtn,1), UBOUND(InData%F_Rdtn,1) - ReKiBuf(Re_Xferred) = InData%F_Rdtn(i1) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( .NOT. ALLOCATED(InData%F_Rdtn) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_Rdtn,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_Rdtn,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%F_Rdtn,1), UBOUND(InData%F_Rdtn,1) + ReKiBuf(Re_Xferred) = InData%F_Rdtn(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE Conv_Rdtn_PackOutput SUBROUTINE Conv_Rdtn_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1759,12 +1867,24 @@ SUBROUTINE Conv_Rdtn_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - i1_l = LBOUND(OutData%F_Rdtn,1) - i1_u = UBOUND(OutData%F_Rdtn,1) - DO i1 = LBOUND(OutData%F_Rdtn,1), UBOUND(OutData%F_Rdtn,1) - OutData%F_Rdtn(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_Rdtn not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_Rdtn)) DEALLOCATE(OutData%F_Rdtn) + ALLOCATE(OutData%F_Rdtn(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_Rdtn.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%F_Rdtn,1), UBOUND(OutData%F_Rdtn,1) + OutData%F_Rdtn(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE Conv_Rdtn_UnPackOutput @@ -1862,10 +1982,12 @@ SUBROUTINE Conv_Rdtn_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, E END IF ScaleFactor = t_out / t(2) +IF (ALLOCATED(u_out%Velocity) .AND. ALLOCATED(u1%Velocity)) THEN DO i1 = LBOUND(u_out%Velocity,1),UBOUND(u_out%Velocity,1) b = -(u1%Velocity(i1) - u2%Velocity(i1)) u_out%Velocity(i1) = u1%Velocity(i1) + b * ScaleFactor END DO +END IF ! check if allocated END SUBROUTINE Conv_Rdtn_Input_ExtrapInterp1 @@ -1923,11 +2045,13 @@ SUBROUTINE Conv_Rdtn_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrSta END IF ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) +IF (ALLOCATED(u_out%Velocity) .AND. ALLOCATED(u1%Velocity)) THEN DO i1 = LBOUND(u_out%Velocity,1),UBOUND(u_out%Velocity,1) b = (t(3)**2*(u1%Velocity(i1) - u2%Velocity(i1)) + t(2)**2*(-u1%Velocity(i1) + u3%Velocity(i1)))* scaleFactor c = ( (t(2)-t(3))*u1%Velocity(i1) + t(3)*u2%Velocity(i1) - t(2)*u3%Velocity(i1) ) * scaleFactor u_out%Velocity(i1) = u1%Velocity(i1) + b + c * t_out END DO +END IF ! check if allocated END SUBROUTINE Conv_Rdtn_Input_ExtrapInterp2 @@ -2025,10 +2149,12 @@ SUBROUTINE Conv_Rdtn_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, END IF ScaleFactor = t_out / t(2) +IF (ALLOCATED(y_out%F_Rdtn) .AND. ALLOCATED(y1%F_Rdtn)) THEN DO i1 = LBOUND(y_out%F_Rdtn,1),UBOUND(y_out%F_Rdtn,1) b = -(y1%F_Rdtn(i1) - y2%F_Rdtn(i1)) y_out%F_Rdtn(i1) = y1%F_Rdtn(i1) + b * ScaleFactor END DO +END IF ! check if allocated END SUBROUTINE Conv_Rdtn_Output_ExtrapInterp1 @@ -2086,11 +2212,13 @@ SUBROUTINE Conv_Rdtn_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrSt END IF ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) +IF (ALLOCATED(y_out%F_Rdtn) .AND. ALLOCATED(y1%F_Rdtn)) THEN DO i1 = LBOUND(y_out%F_Rdtn,1),UBOUND(y_out%F_Rdtn,1) b = (t(3)**2*(y1%F_Rdtn(i1) - y2%F_Rdtn(i1)) + t(2)**2*(-y1%F_Rdtn(i1) + y3%F_Rdtn(i1)))* scaleFactor c = ( (t(2)-t(3))*y1%F_Rdtn(i1) + t(3)*y2%F_Rdtn(i1) - t(2)*y3%F_Rdtn(i1) ) * scaleFactor y_out%F_Rdtn(i1) = y1%F_Rdtn(i1) + b + c * t_out END DO +END IF ! check if allocated END SUBROUTINE Conv_Rdtn_Output_ExtrapInterp2 END MODULE Conv_Radiation_Types diff --git a/modules/hydrodyn/src/HydroDyn.f90 b/modules/hydrodyn/src/HydroDyn.f90 index 9f1b60fb8e..ca4cf13dd2 100644 --- a/modules/hydrodyn/src/HydroDyn.f90 +++ b/modules/hydrodyn/src/HydroDyn.f90 @@ -27,6 +27,7 @@ MODULE HydroDyn USE HydroDyn_Types USE NWTC_Library + use Morison USE WAMIT USE WAMIT2 USE HydroDyn_Input @@ -86,7 +87,7 @@ SUBROUTINE WvStretch_Init(WaveStMod, WtrDpth, NStepWave, NNodes, & INTEGER, INTENT(IN ) :: WaveStMod REAL(SiKi), INTENT(IN ) :: WtrDpth INTEGER, INTENT(IN ) :: NStepWave - INTEGER, INTENT(IN ) :: NNodes !< TODO: WHY are there both NNodes and NWaveElev ??? GJH 2/1/2016 + INTEGER, INTENT(IN ) :: NNodes INTEGER, INTENT(IN ) :: NWaveElev REAL(SiKi), INTENT(IN ) :: WaveElev(0:,:) REAL(SiKi), INTENT(IN ) :: WaveKinzi(:) @@ -224,7 +225,7 @@ END SUBROUTINE WvStretch_Init SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut, ErrStat, ErrMsg ) !.................................................................................................................................. - TYPE(HydroDyn_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization routine. TODO: This does not follow the template due to the interface of HydroDyn_CopyInitInput() + TYPE(HydroDyn_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization routine. TYPE(HydroDyn_InputType), INTENT( OUT) :: u !< An initial guess for the input; input mesh must be defined TYPE(HydroDyn_ParameterType), INTENT( OUT) :: p !< Parameters TYPE(HydroDyn_ContinuousStateType), INTENT( OUT) :: x !< Initial continuous states @@ -255,7 +256,7 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I ! LOGICAL :: hasWAMITOuts ! Are there any WAMIT-related outputs ! LOGICAL :: hasMorisonOuts ! Are there any Morison-related outputs ! INTEGER :: numHydroOuts ! total number of WAMIT and Morison outputs - INTEGER :: I, J ! Generic counters + INTEGER :: I, J, k, iBody ! Generic counters REAL(SiKi) :: WaveNmbr ! Wavenumber of the current frequency component (1/meter) ! These are dummy variables to satisfy the framework, but are not used @@ -296,6 +297,9 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I Real(ReKi) :: dftreal Real(ReKi) :: dftimag + ! WAMIT Mesh + real(R8Ki) :: theta(3), orientation(3,3) + ! Wave Stretching Data REAL(SiKi), ALLOCATABLE :: tmpWaveKinzi(: ) INTEGER :: tmpNWaveElev @@ -352,7 +356,7 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I - IF ( InitInp%UseInputFile ) THEN + IF ( InitLocal%UseInputFile ) THEN ! Parse all HydroDyn-related input files and populate the *_InitInputType derived types @@ -660,9 +664,6 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I CALL MOVE_ALLOC(Waves_InitOut%WaveElevC0, InitLocal%Waves2%WaveElevC0) CALL MOVE_ALLOC(Waves_InitOut%WaveDirArr, InitLocal%Waves2%WaveDirArr) - !bjj: note that this doesn't get called if .not. (InitLocal%Waves2%WvDiffQTFF .OR. InitLocal%Waves2%WvSumQTFF), so p%waves2%* never get set - ! however, they get queried later in the code!!!! I've set these parameters in an "else" statement, below - !========================================================================== ! Initialize Wave Stretching data for 2nd Order Waves !========================================================================== @@ -770,6 +771,7 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I +!FIXME: why is this called again? I'm either not remembering something, or I don't undestand the wave stretching above. -- ADP CALL Waves2_Init(InitLocal%Waves2, m%u_Waves2, p%Waves2, x%Waves2, xd%Waves2, z%Waves2, OtherState%Waves2, & y%Waves2, m%Waves2, Interval, InitOut%Waves2, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -824,6 +826,7 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I p%WaveElev(I,J) = p%Waves2%WaveElev2(I,J) + p%WaveElev(I,J) ENDDO ENDDO + CALL MOVE_ALLOC(p%Waves2%WaveElev2,p%WaveElev2) ENDIF ENDIF @@ -836,7 +839,7 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I p%Waves2%WvSumQTFF = .FALSE. p%Waves2%NumOuts = 0 - ENDIF + ENDIF ! InitLocal%Waves2%WvDiffQTFF .OR. InitLocal%Waves2%WvSumQTFF @@ -844,107 +847,277 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I ! Is there a WAMIT body? IF ( InitLocal%PotMod == 1 ) THEN + p%nWAMITObj = InitLocal%nWAMITObj ! All the data for the various WAMIT bodies are stored in a single WAMIT file + p%vecMultiplier = InitLocal%vecMultiplier ! Multiply all vectors and matrices row/column lengths by NBody + InitLocal%WAMIT%NBodyMod = InitLocal%NBodyMod + InitLocal%WAMIT%Gravity = InitLocal%Gravity + InitLocal%WAMIT%WtrDpth = InitLocal%Morison%WtrDpth ! The data in InitLocal%Morison%WtrDpth was directly placed there when we parsed the HydroDyn input file + p%NBody = InitLocal%NBody + p%NBodyMod = InitLocal%NBodyMod + + call AllocAry( m%F_PtfmAdd, 6*InitLocal%NBody, "m%F_PtfmAdd", ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( m%F_Waves , 6*InitLocal%NBody, "m%F_Waves" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Determine how many WAMIT modules we need based on NBody and NBodyMod + if (p%NBodyMod == 1) then + InitLocal%WAMIT%NBody = InitLocal%NBody ! The WAMIT object will contain all NBody WAMIT bodies + + ! Allocate WAMIT InitInp arrays based on NBodyMod and copy the inputfile data into the WAMIT init data (entire arrays' worth for NBodyMod=1 + call AllocAry( InitLocal%WAMIT%PtfmVol0 , InitLocal%NBody, "PtfmVol0" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT%PtfmRefxt , InitLocal%NBody, "PtfmRefxt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT%PtfmRefyt , InitLocal%NBody, "PtfmRefyt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT%PtfmRefzt , InitLocal%NBody, "PtfmRefzt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT%PtfmRefztRot, InitLocal%NBody, "PtfmRefztRot", ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT%PtfmCOBxt , InitLocal%NBody, "PtfmCOBxt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT%PtfmCOByt , InitLocal%NBody, "PtfmCOByt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + allocate( p%WAMIT( 1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array p%WAMIT.', ErrStat, ErrMsg, RoutineName ) + allocate( x%WAMIT( 1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array x%WAMIT.', ErrStat, ErrMsg, RoutineName ) + allocate( xd%WAMIT( 1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array xd%WAMIT.', ErrStat, ErrMsg, RoutineName ) + allocate( OtherState%WAMIT(1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array OtherState%WAMIT.', ErrStat, ErrMsg, RoutineName ) + allocate( y%WAMIT( 1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array y%WAMIT.', ErrStat, ErrMsg, RoutineName ) + allocate( m%WAMIT( 1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array m%WAMIT.', ErrStat, ErrMsg, RoutineName ) + allocate( m%u_WAMIT( 1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array m%u_WAMIT.', ErrStat, ErrMsg, RoutineName ) + allocate( InitOut%WAMIT( 1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array InitOut%WAMIT.', ErrStat, ErrMsg, RoutineName ) + + InitLocal%WAMIT%PtfmVol0 = InitLocal%PtfmVol0 + InitLocal%WAMIT%WAMITULEN = InitLocal%WAMITULEN(1) + InitLocal%WAMIT%PtfmRefxt = InitLocal%PtfmRefxt + InitLocal%WAMIT%PtfmRefyt = InitLocal%PtfmRefyt + InitLocal%WAMIT%PtfmRefzt = InitLocal%PtfmRefzt + InitLocal%WAMIT%PtfmRefztRot = InitLocal%PtfmRefztRot + InitLocal%WAMIT%PtfmCOBxt = InitLocal%PtfmCOBxt + InitLocal%WAMIT%PtfmCOByt = InitLocal%PtfmCOByt + else + InitLocal%WAMIT%NBody = 1 ! Each WAMIT object will only contain one of the NBody WAMIT bodies + + ! Allocate WAMIT InitInp arrays based on NBodyMod and copy the inputfile data into the 1st WAMIT body init data for NBodyMod > 1 + call AllocAry( InitLocal%WAMIT%PtfmVol0 , 1, "PtfmVol0" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT%PtfmRefxt , 1, "PtfmRefxt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT%PtfmRefyt , 1, "PtfmRefyt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT%PtfmRefzt , 1, "PtfmRefzt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT%PtfmRefztRot, 1, "PtfmRefztRot", ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT%PtfmCOBxt , 1, "PtfmCOBxt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT%PtfmCOByt , 1, "PtfmCOByt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + allocate( p%WAMIT( InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array p%WAMIT.', ErrStat, ErrMsg, RoutineName ) + allocate( x%WAMIT( InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array x%WAMIT.', ErrStat, ErrMsg, RoutineName ) + allocate( xd%WAMIT( InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array xd%WAMIT.', ErrStat, ErrMsg, RoutineName ) + allocate( OtherState%WAMIT(InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array OtherState%WAMIT.', ErrStat, ErrMsg, RoutineName ) + allocate( y%WAMIT( InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array y%WAMIT.', ErrStat, ErrMsg, RoutineName ) + allocate( m%WAMIT( InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array m%WAMIT.', ErrStat, ErrMsg, RoutineName ) + allocate( m%u_WAMIT( InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array m%u_WAMIT.', ErrStat, ErrMsg, RoutineName ) + allocate( InitOut%WAMIT( InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array InitOut%WAMIT.', ErrStat, ErrMsg, RoutineName ) + InitLocal%WAMIT%PtfmVol0 (1) = InitLocal%PtfmVol0 (1) + InitLocal%WAMIT%WAMITULEN = InitLocal%WAMITULEN (1) + InitLocal%WAMIT%PtfmRefxt (1) = InitLocal%PtfmRefxt (1) + InitLocal%WAMIT%PtfmRefyt (1) = InitLocal%PtfmRefyt (1) + InitLocal%WAMIT%PtfmRefzt (1) = InitLocal%PtfmRefzt (1) + InitLocal%WAMIT%PtfmRefztRot(1) = InitLocal%PtfmRefztRot(1) + InitLocal%WAMIT%PtfmCOBxt (1) = InitLocal%PtfmCOBxt (1) + InitLocal%WAMIT%PtfmCOByt (1) = InitLocal%PtfmCOByt (1) + + end if - ! Copy Waves initialization output into the initialization input type for the WAMIT module + if ( ErrStat >= AbortErrLev ) then + call CleanUp() + return + end if + + ! Copy Waves initialization output into the initialization input type for the WAMIT module InitLocal%WAMIT%RhoXg = Waves_InitOut%RhoXg InitLocal%WAMIT%NStepWave = Waves_InitOut%NStepWave InitLocal%WAMIT%NStepWave2 = Waves_InitOut%NStepWave2 InitLocal%WAMIT%WaveDirMin = Waves_InitOut%WaveDirMin InitLocal%WAMIT%WaveDirMax = Waves_InitOut%WaveDirMax - InitLocal%WAMIT%WaveDOmega = Waves_InitOut%WaveDOmega - - + InitLocal%WAMIT%WaveDOmega = Waves_InitOut%WaveDOmega + ! Init inputs for the SS_Excitation model (set this just in case it will be used) InitLocal%WAMIT%WaveDir = Waves_InitOut%WaveDir - CALL MOVE_ALLOC(Waves_InitOut%WaveElev0, InitLocal%WAMIT%WaveElev0) - - ! Temporarily move arrays to init input for WAMIT (save some space) + CALL MOVE_ALLOC(Waves_InitOut%WaveElev0, InitLocal%WAMIT%WaveElev0) + + ! Temporarily move arrays to init input for WAMIT (save some space) CALL MOVE_ALLOC(p%WaveTime, InitLocal%WAMIT%WaveTime) CALL MOVE_ALLOC(Waves_InitOut%WaveElevC0, InitLocal%WAMIT%WaveElevC0) CALL MOVE_ALLOC(Waves_InitOut%WaveDirArr, InitLocal%WAMIT%WaveDirArr) - !----------------------------------------- - ! Initialize the WAMIT Calculations - !----------------------------------------- - - CALL WAMIT_Init(InitLocal%WAMIT, m%u_WAMIT, p%WAMIT, x%WAMIT, xd%WAMIT, z%WAMIT, OtherState%WAMIT, & - y%WAMIT, m%WAMIT, Interval, InitOut%WAMIT, ErrStat2, ErrMsg2 ) + CALL WAMIT_Init(InitLocal%WAMIT, m%u_WAMIT(1), p%WAMIT(1), x%WAMIT(1), xd%WAMIT(1), z%WAMIT, OtherState%WAMIT(1), & + y%WAMIT(1), m%WAMIT(1), Interval, InitOut%WAMIT(1), ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN + CALL CleanUp() + RETURN END IF - - - - ! Generate Summary file information for WAMIT module - ! Compute the load contribution from hydrostatics: - IF ( InitLocal%UnSum > 0 ) THEN - WRITE( InitLocal%UnSum, '(A11)') 'WAMIT Model' - WRITE( InitLocal%UnSum, '(A11)') '-----------' - WRITE( InitLocal%UnSum, '(A42,2X,ES15.6)') 'Displaced volume (m^3) :', p%WAMIT%PtfmVol0 - WRITE( InitLocal%UnSum, '(A42,2X,ES15.6)') 'X-offset of the center of buoyancy (m) :', p%WAMIT%PtfmCOBxt - WRITE( InitLocal%UnSum, '(A42,2X,ES15.6)') 'Y-offset of the center of buoyancy (m) :', p%WAMIT%PtfmCOByt - WRITE( InitLocal%UnSum, '(/)' ) - WRITE( InitLocal%UnSum, '(A81)' ) 'Buoyancy loads from members modelled with WAMIT, summed about ( 0.0, 0.0, 0.0 )' - WRITE( InitLocal%UnSum, '(18x,6(2X,A20))' ) ' BuoyFxi ', ' BuoyFyi ', ' BuoyFzi ', ' BuoyMxi ', ' BuoyMyi ', ' BuoyMzi ' - WRITE( InitLocal%UnSum, '(18x,6(2X,A20))' ) ' (N) ', ' (N) ', ' (N) ', ' (N-m) ', ' (N-m) ', ' (N-m) ' - WRITE( InitLocal%UnSum, '(A18,6(2X,ES20.6))') ' External: ',0.0,0.0,p%WAMIT%RhoXg*p%WAMIT%PtfmVol0,p%WAMIT%RhoXg*p%WAMIT%PtfmVol0*p%WAMIT%PtfmCOByt, -p%WAMIT%RhoXg*p%WAMIT%PtfmVol0*p%WAMIT%PtfmCOBxt, 0.0 ! and the moment about Y due to the COB being offset from the WAMIT reference point - + + ! For NBodyMod > 1 and NBody > 1, set the body info and init the WAMIT body + do i = 2, p%nWAMITObj + !----------------------------------------- + ! Initialize the WAMIT Calculations + !----------------------------------------- + InitLocal%WAMIT%WAMITFile = InitLocal%PotFile (i) + InitLocal%WAMIT%PtfmVol0 (1) = InitLocal%PtfmVol0 (i) + InitLocal%WAMIT%WAMITULEN = InitLocal%WAMITULEN (i) + InitLocal%WAMIT%PtfmRefxt (1) = InitLocal%PtfmRefxt (i) + InitLocal%WAMIT%PtfmRefyt (1) = InitLocal%PtfmRefyt (i) + InitLocal%WAMIT%PtfmRefzt (1) = InitLocal%PtfmRefzt (i) + InitLocal%WAMIT%PtfmRefztRot(1) = InitLocal%PtfmRefztRot(i) + InitLocal%WAMIT%PtfmCOBxt (1) = InitLocal%PtfmCOBxt (i) + InitLocal%WAMIT%PtfmCOByt (1) = InitLocal%PtfmCOByt (i) + + CALL WAMIT_Init(InitLocal%WAMIT, m%u_WAMIT(i), p%WAMIT(i), x%WAMIT(i), xd%WAMIT(i), z%WAMIT, OtherState%WAMIT(i), & + y%WAMIT(i), m%WAMIT(i), Interval, InitOut%WAMIT(i), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + CALL CleanUp() + RETURN + END IF + end do + + ! Generate Summary file information for WAMIT module + ! Compute the load contribution from hydrostatics: + IF ( InitLocal%UnSum > 0 ) THEN + do iBody = 1, InitLocal%NBody + WRITE( InitLocal%UnSum, '(A18,I5)') 'WAMIT Model - Body',iBody + WRITE( InitLocal%UnSum, '(A18)') '------------------' + WRITE( InitLocal%UnSum, '(A42,2X,ES15.6)') 'Displaced volume (m^3) :', InitLocal%PtfmVol0(iBody) + WRITE( InitLocal%UnSum, '(A42,2X,ES15.6)') 'X-offset of the center of buoyancy (m) :', InitLocal%PtfmCOBxt(iBody) + WRITE( InitLocal%UnSum, '(A42,2X,ES15.6)') 'Y-offset of the center of buoyancy (m) :', InitLocal%PtfmCOByt(iBody) + WRITE( InitLocal%UnSum, '(/)' ) + WRITE( InitLocal%UnSum, '(A81)' ) 'Buoyancy loads from members modelled with WAMIT, summed about ( 0.0, 0.0, 0.0 )' + WRITE( InitLocal%UnSum, '(18x,6(2X,A20))' ) ' BuoyFxi ', ' BuoyFyi ', ' BuoyFzi ', ' BuoyMxi ', ' BuoyMyi ', ' BuoyMzi ' + WRITE( InitLocal%UnSum, '(18x,6(2X,A20))' ) ' (N) ', ' (N) ', ' (N) ', ' (N-m) ', ' (N-m) ', ' (N-m) ' + WRITE( InitLocal%UnSum, '(A18,6(2X,ES20.6))') ' External: ',0.0,0.0,InitLocal%WAMIT%RhoXg*InitLocal%PtfmVol0(iBody),InitLocal%WAMIT%RhoXg*InitLocal%PtfmVol0(iBody)*InitLocal%PtfmCOByt(iBody), -InitLocal%WAMIT%RhoXg*InitLocal%PtfmVol0(iBody)*InitLocal%PtfmCOBxt(iBody), 0.0 ! and the moment about Y due to the COB being offset from the WAMIT reference point + end do END IF - ! Verify that WAMIT_Init() did not request a different Interval! + ! Verify that WAMIT_Init() did not request a different Interval! IF ( p%DT /= Interval ) THEN - CALL SetErrStat(ErrID_Fatal,'WAMIT Module attempted to change timestep interval, but this is not allowed. WAMIT Module must use the HydroDyn Interval.',ErrStat,ErrMsg,RoutineName) - CALL CleanUp() - RETURN + CALL SetErrStat(ErrID_Fatal,'WAMIT Module attempted to change timestep interval, but this is not allowed. WAMIT Module must use the HydroDyn Interval.',ErrStat,ErrMsg,RoutineName) + CALL CleanUp() + RETURN END IF - + + ! move arrays back CALL MOVE_ALLOC(InitLocal%WAMIT%WaveTime, p%WaveTime ) CALL MOVE_ALLOC(InitLocal%WAMIT%WaveElevC0, Waves_InitOut%WaveElevC0) CALL MOVE_ALLOC(InitLocal%WAMIT%WaveDirArr, Waves_InitOut%WaveDirArr) - + !----------------------------------------- ! Initialize the WAMIT2 Calculations !----------------------------------------- - + ! Only call the WAMIT2_Init if one of the flags is set for a calculation IF ( InitLocal%WAMIT2%MnDriftF .OR. InitLocal%WAMIT2%NewmanAppF .OR. InitLocal%WAMIT2%DiffQTFF .OR. InitLocal%WAMIT2%SumQTFF ) THEN - - + + ! Flag required for indicating when to try using arrays that are allocated + p%WAMIT2used = .TRUE. + + ! Temporarily move arrays to init input for WAMIT2 (save some space) + CALL MOVE_ALLOC(p%WaveTime, InitLocal%WAMIT2%WaveTime) + CALL MOVE_ALLOC(Waves_InitOut%WaveElevC0, InitLocal%WAMIT2%WaveElevC0) + CALL MOVE_ALLOC(Waves_InitOut%WaveDirArr, InitLocal%WAMIT2%WaveDirArr) + + ! Copy Waves initialization output into the initialization input type for the WAMIT module InitLocal%WAMIT2%RhoXg = Waves_InitOut%RhoXg InitLocal%WAMIT2%NStepWave = Waves_InitOut%NStepWave InitLocal%WAMIT2%NStepWave2 = Waves_InitOut%NStepWave2 InitLocal%WAMIT2%WaveDirMin = Waves_InitOut%WaveDirMin InitLocal%WAMIT2%WaveDirMax = Waves_InitOut%WaveDirMax InitLocal%WAMIT2%WaveDOmega = Waves_InitOut%WaveDOmega - - ! Temporarily move arrays to init input for WAMIT2 (save some space) - CALL MOVE_ALLOC(p%WaveTime, InitLocal%WAMIT2%WaveTime) - CALL MOVE_ALLOC(Waves_InitOut%WaveElevC0, InitLocal%WAMIT2%WaveElevC0) - CALL MOVE_ALLOC(Waves_InitOut%WaveDirArr, InitLocal%WAMIT2%WaveDirArr) - - - CALL WAMIT2_Init(InitLocal%WAMIT2, m%u_WAMIT2, p%WAMIT2, x%WAMIT2, xd%WAMIT2, z%WAMIT2, OtherState%WAMIT2, & - y%WAMIT2, m%WAMIT2, Interval, InitOut%WAMIT2, ErrStat2, ErrMsg2 ) + InitLocal%WAMIT2%Gravity = InitLocal%Gravity + InitLocal%WAMIT2%WtrDpth = InitLocal%Morison%WtrDpth ! The data in InitLocal%Morison%WtrDpth was directly placed there when we parsed the HydroDyn input file + + ! Set values for all NBodyMods + InitLocal%WAMIT2%NBodyMod = InitLocal%NBodyMod ! There are restrictions in WAMIT2 on which files may be used for MnDriftF or NewmanAppF for BodyMod > 1 + InitLocal%WAMIT2%WAMITULEN = InitLocal%WAMITULEN(1) + + ! Determine how many WAMIT2 modules we need based on NBody and NBodyMod + if (p%NBodyMod == 1) then + InitLocal%WAMIT2%NBody = InitLocal%NBody ! The WAMIT2 object will contain all NBody WAMIT2 bodies + + ! Allocate WAMIT2 InitInp arrays based on NBodyMod and copy the inputfile data into the WAMIT2 init data (entire arrays' worth for NBodyMod=1 + call AllocAry( InitLocal%WAMIT2%PtfmRefxt , InitLocal%NBody, "PtfmRefxt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT2%PtfmRefyt , InitLocal%NBody, "PtfmRefyt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT2%PtfmRefzt , InitLocal%NBody, "PtfmRefzt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT2%PtfmRefztRot, InitLocal%NBody, "PtfmRefztRot", ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + allocate( p%WAMIT2( 1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array p%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + allocate( x%WAMIT2( 1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array x%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + allocate( xd%WAMIT2( 1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array xd%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + allocate( OtherState%WAMIT2(1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array OtherState%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + allocate( y%WAMIT2( 1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array y%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + allocate( m%WAMIT2( 1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array m%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + allocate( m%u_WAMIT2( 1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array m%u_WAMIT2.', ErrStat, ErrMsg, RoutineName ) + allocate( InitOut%WAMIT2( 1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array InitOut%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + InitLocal%WAMIT2%PtfmRefxt = InitLocal%PtfmRefxt + InitLocal%WAMIT2%PtfmRefyt = InitLocal%PtfmRefyt + InitLocal%WAMIT2%PtfmRefzt = InitLocal%PtfmRefzt + InitLocal%WAMIT2%PtfmRefztRot = InitLocal%PtfmRefztRot + + else + InitLocal%WAMIT2%NBody = 1_IntKi ! The WAMIT2 object will contain all NBody WAMIT2 bodies + + ! Allocate WAMIT2 InitInp arrays based on NBodyMod and copy the inputfile data into the 1st WAMIT body init data for NBodyMod > 1 + call AllocAry( InitLocal%WAMIT2%PtfmRefxt , 1, "PtfmRefxt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT2%PtfmRefyt , 1, "PtfmRefyt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT2%PtfmRefzt , 1, "PtfmRefzt" , ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( InitLocal%WAMIT2%PtfmRefztRot, 1, "PtfmRefztRot", ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + allocate( p%WAMIT2( InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array p%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + allocate( x%WAMIT2( InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array x%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + allocate( xd%WAMIT2( InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array xd%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + allocate( OtherState%WAMIT2(InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array OtherState%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + allocate( y%WAMIT2( InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array y%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + allocate( m%WAMIT2( InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array m%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + allocate( m%u_WAMIT2( InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array m%u_WAMIT2.', ErrStat, ErrMsg, RoutineName ) + allocate( InitOut%WAMIT2( InitLocal%NBody), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array InitOut%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + InitLocal%WAMIT2%PtfmRefxt (1) = InitLocal%PtfmRefxt (1) + InitLocal%WAMIT2%PtfmRefyt (1) = InitLocal%PtfmRefyt (1) + InitLocal%WAMIT2%PtfmRefzt (1) = InitLocal%PtfmRefzt (1) + InitLocal%WAMIT2%PtfmRefztRot(1) = InitLocal%PtfmRefztRot(1) + + endif + + if ( ErrStat >= AbortErrLev ) then + call CleanUp() + return + end if + + CALL WAMIT2_Init(InitLocal%WAMIT2, m%u_WAMIT2(1), p%WAMIT2(1), x%WAMIT2(1), xd%WAMIT2(1), z%WAMIT2, OtherState%WAMIT2(1), & + y%WAMIT2(1), m%WAMIT2(1), Interval, InitOut%WAMIT2(1), ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN END IF - + + ! For NBodyMod > 1 and NBody > 1, set the body info and init the WAMIT2 body + do i = 2, p%nWAMITObj + InitLocal%WAMIT2%WAMITFile = InitLocal%PotFile (i) + InitLocal%WAMIT2%WAMITULEN = InitLocal%WAMITULEN (i) + InitLocal%WAMIT2%PtfmRefxt (1) = InitLocal%PtfmRefxt (i) + InitLocal%WAMIT2%PtfmRefyt (1) = InitLocal%PtfmRefyt (i) + InitLocal%WAMIT2%PtfmRefzt (1) = InitLocal%PtfmRefzt (i) + InitLocal%WAMIT2%PtfmRefztRot(1) = InitLocal%PtfmRefztRot(i) + + CALL WAMIT2_Init(InitLocal%WAMIT2, m%u_WAMIT2(i), p%WAMIT2(i), x%WAMIT2(i), xd%WAMIT2(i), z%WAMIT2, OtherState%WAMIT2(i), & + y%WAMIT2(i), m%WAMIT2(i), Interval, InitOut%WAMIT2(i), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + CALL CleanUp() + RETURN + END IF + end do + + ! move arrays back - CALL MOVE_ALLOC(InitLocal%WAMIT2%WaveTime, p%WaveTime ) - CALL MOVE_ALLOC(InitLocal%WAMIT2%WaveElevC0, Waves_InitOut%WaveElevC0) - CALL MOVE_ALLOC(InitLocal%WAMIT2%WaveDirArr, Waves_InitOut%WaveDirArr) - - + CALL MOVE_ALLOC(InitLocal%WAMIT2%WaveTime, p%WaveTime ) + CALL MOVE_ALLOC(InitLocal%WAMIT2%WaveElevC0, Waves_InitOut%WaveElevC0) + CALL MOVE_ALLOC(InitLocal%WAMIT2%WaveDirArr, Waves_InitOut%WaveDirArr) + + ! Verify that WAMIT2_Init() did not request a different Interval! IF ( p%DT /= Interval ) THEN @@ -953,11 +1126,16 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I CALL CleanUp() RETURN END IF - + ELSE - - p%WAMIT2%NumOuts = 0 !This doesn't get initialized if we don't call WAMIT2_Init - + ! Flag used in output handling to indicate when to ignore WAMIT2 outputs. + p%WAMIT2used = .FALSE. + allocate( p%WAMIT2(1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array p%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + allocate( m%WAMIT2(1), stat = ErrStat2 ); if (ErrStat2 /=0) call SetErrStat( ErrID_Fatal, 'Failed to allocate array m%WAMIT2.', ErrStat, ErrMsg, RoutineName ) + p%WAMIT2%MnDriftF = .FALSE. + p%WAMIT2%NewmanAppF = .FALSE. + p%WAMIT2%DiffQTFF = .FALSE. + p%WAMIT2%SumQTFF = .FALSE. ENDIF #ifdef USE_FIT @@ -1142,7 +1320,7 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I ! TODO: 1/29/2016 GJH ! This is where we need to perform Wave Stretching, now that the wave kinematics have been combined. ! We will call a new subroutine to perform this work. - ! As an input, this code need the kinematics at the (X,Y,0) location which in a Z-line above/below all the nodes where kinematics are computed. + ! As an input, this code needs the kinematics at the (X,Y,0) location which in a Z-line above/below all the nodes where kinematics are computed. ! This code will alter the kinematics for stretching AND alter the nodeInWater array based on the combined wave elevation information IF (InitLocal%Waves%WaveStMod > 0 ) THEN call WvStretch_Init( InitLocal%Waves%WaveStMod, InitLocal%Waves%WtrDpth, InitLocal%Morison%NStepWave, InitLocal%Morison%NNodes, & @@ -1196,43 +1374,25 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I CALL MOVE_ALLOC( InitLocal%Morison%WaveTime, p%WaveTime ) - IF ( u%Morison%DistribMesh%Committed ) THEN + IF ( u%Morison%Mesh%Committed ) THEN ! we need the translation displacement mesh for loads transfer: - CALL MeshCopy ( SrcMesh = u%Morison%DistribMesh & - , DestMesh = m%MrsnDistribMesh_position & + CALL MeshCopy ( SrcMesh = u%Morison%Mesh & + , DestMesh = m%MrsnMesh_position & , CtrlCode = MESH_NEWCOPY & , IOS = COMPONENT_INPUT & , TranslationDisp = .TRUE. & , ErrStat = ErrStat2 & , ErrMess = ErrMsg2 ) ! automatically sets DestMesh%RemapFlag = .TRUE. - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'HydroDyn_Init:m%MrsnDistribMesh_position') + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'HydroDyn_Init:m%MrsnMesh_position') IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN END IF - m%MrsnDistribMesh_position%TranslationDisp = 0.0 ! bjj: this is actually initialized in the ModMesh module, but I'll do it here anyway. + m%MrsnMesh_position%TranslationDisp = 0.0 ! bjj: this is actually initialized in the ModMesh module, but I'll do it here anyway. END IF - IF ( u%Morison%LumpedMesh%Committed ) THEN - ! we need the translation displacement mesh for loads transfer: - CALL MeshCopy ( SrcMesh = u%Morison%LumpedMesh & - , DestMesh = m%MrsnLumpedMesh_position & - , CtrlCode = MESH_NEWCOPY & - , IOS = COMPONENT_INPUT & - , TranslationDisp = .TRUE. & - , ErrStat = ErrStat2 & - , ErrMess = ErrMsg2 ) ! automatically sets DestMesh%RemapFlag = .TRUE. - - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'HydroDyn_Init:m%MrsnLumpedMesh_position') - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - m%MrsnLumpedMesh_position%TranslationDisp = 0.0 ! bjj: this is actually initialized in the ModMesh module, but I'll do it here anyway. - - END IF ! Verify that Morison_Init() did not request a different Interval! IF ( p%DT /= Interval ) THEN @@ -1267,19 +1427,74 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I IF ( InitLocal%PotMod == 1 .AND. InitLocal%WAMIT%RdtnMod == 1) THEN - ! Write the header for this section - WRITE( InitLocal%UnSum, '(//)' ) - WRITE( InitLocal%UnSum, '(A)' ) 'Radiation memory effect kernel' - WRITE( InitLocal%UnSum, '(//)' ) - WRITE( InitLocal%UnSum, '(1X,A10,2X,A10,21(2X,A16))' ) ' n ' , ' t ', ' K11 ', ' K12 ', ' K13 ', ' K14 ', ' K15 ', ' K16 ', ' K22 ', ' K23 ', ' K24 ', ' K25 ', ' K26 ', ' K33 ', ' K34 ', ' K35 ', 'K36 ', ' K44 ', ' K45 ', ' K46 ', ' K55 ', ' K56 ', ' K66 ' - WRITE( InitLocal%UnSum, '(1X,A10,2X,A10,21(2X,A16))' ) ' (-) ' , ' (s) ', ' (kg/s^2) ', ' (kg/s^2) ', ' (kg/s^2) ', ' (kgm/s^2) ', ' (kgm/s^2) ', ' (kgm/s^2) ', ' (kg/s^2) ', ' (kg/s^2) ', ' (kgm/s^2) ', ' (kgm/s^2) ', ' (kgm/s^2) ', ' (kg/s^2) ', ' (kgm/s^2) ', ' (kgm/s^2) ', ' (kgm/s^2) ', '(kgm^2/s^2)', '(kgm^2/s^2)', '(kgm^2/s^2)', '(kgm^2/s^2)', '(kgm^2/s^2)', '(kgm^2/s^2)' + ! Write the header for this section: Note: When NBodyMod = 1 the kernel is now 6*NBody by 6*Nbody in size, + ! and we have NBody 6 by 6 kernels for NBodyMod=2 or 3 + if (p%NBodyMod == 1) then + ! NBodyMod=1 kernel printout which is 6*NBody x 6*NBody long + WRITE( InitLocal%UnSum, '(//)' ) + WRITE( InitLocal%UnSum, '(A)' ) 'Radiation memory effect kernel' + WRITE( InitLocal%UnSum, '(//)' ) + + WRITE( InitLocal%UnSum, '(1X,A10,2X,A10)',ADVANCE='no' ) ' n ' , ' t ' + do i = 1,6*p%NBody + do j = 1,6*p%NBody + WRITE( InitLocal%UnSum, '(2X,A16)',ADVANCE='no' ) 'K'//trim(num2lstr(i))//trim(num2lstr(j)) + end do + end do + write(InitLocal%UnSum,'()') ! end of line character + + + WRITE( InitLocal%UnSum, '(1X,A10,2X,A10)',ADVANCE='no' ) ' (-) ' , ' (s) ' + do i = 1,6*p%NBody + do j = 1,6*p%NBody + if ( mod(i-1,6)+1 < 4 ) then + if ( mod(j-1,6)+1 < 4 ) then + WRITE( InitLocal%UnSum, '(2X,A16)',ADVANCE='no' ) ' (kg/s^2) ' + else + WRITE( InitLocal%UnSum, '(2X,A16)',ADVANCE='no' ) ' (kgm/s^2) ' + end if + else + if ( mod(j-1,6)+1 < 4 ) then + WRITE( InitLocal%UnSum, '(2X,A16)',ADVANCE='no' ) ' (kgm/s^2) ' + else + WRITE( InitLocal%UnSum, '(2X,A16)',ADVANCE='no' ) '(kgm^2/s^2)' + end if + end if + end do + end do + write(InitLocal%UnSum,'()') ! end of line character + + do k= 0,p%WAMIT(1)%Conv_Rdtn%NStepRdtn-1 + WRITE( InitLocal%UnSum, '(1X,I10,2X,E12.5)',ADVANCE='no' ) K, K*p%WAMIT(1)%Conv_Rdtn%RdtnDT + do i = 1,6*p%NBody + do j = 1,6*p%NBody + WRITE( InitLocal%UnSum, '(2X,ES16.5)',ADVANCE='no' ) p%WAMIT(1)%Conv_Rdtn%RdtnKrnl(k,i,j) + end do + end do + write(InitLocal%UnSum,'()') ! end of line character + end do + + else + do j = 1,p%nWAMITObj + WRITE( InitLocal%UnSum, '(//)' ) + WRITE( InitLocal%UnSum, '(A)' ) 'Radiation memory effect kernel' + WRITE( InitLocal%UnSum, '(//)' ) + WRITE( InitLocal%UnSum, '(1X,A10,2X,A10,21(2X,A16))' ) ' n ' , ' t ', ' K11 ', ' K12 ', ' K13 ', ' K14 ', ' K15 ', ' K16 ', ' K22 ', ' K23 ', ' K24 ', ' K25 ', ' K26 ', ' K33 ', ' K34 ', ' K35 ', 'K36 ', ' K44 ', ' K45 ', ' K46 ', ' K55 ', ' K56 ', ' K66 ' + WRITE( InitLocal%UnSum, '(1X,A10,2X,A10,21(2X,A16))' ) ' (-) ' , ' (s) ', ' (kg/s^2) ', ' (kg/s^2) ', ' (kg/s^2) ', ' (kgm/s^2) ', ' (kgm/s^2) ', ' (kgm/s^2) ', ' (kg/s^2) ', ' (kg/s^2) ', ' (kgm/s^2) ', ' (kgm/s^2) ', ' (kgm/s^2) ', ' (kg/s^2) ', ' (kgm/s^2) ', ' (kgm/s^2) ', ' (kgm/s^2) ', '(kgm^2/s^2)', '(kgm^2/s^2)', '(kgm^2/s^2)', '(kgm^2/s^2)', '(kgm^2/s^2)', '(kgm^2/s^2)' ! Write the data - DO I = 0,p%WAMIT%Conv_Rdtn%NStepRdtn-1 - - WRITE( InitLocal%UnSum, '(1X,I10,2X,E12.5,21(2X,ES16.5))' ) I, I*p%WAMIT%Conv_Rdtn%RdtnDT, p%WAMIT%Conv_Rdtn%RdtnKrnl(I,1,1), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,1,2), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,1,3), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,1,4), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,1,5), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,1,6), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,2,2), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,2,3), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,2,4), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,2,5), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,2,6), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,3,3), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,3,4), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,3,5), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,3,6), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,4,4), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,4,5), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,4,6), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,5,5), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,5,6), p%WAMIT%Conv_Rdtn%RdtnKrnl(I,6,6) - - END DO + DO I = 0,p%WAMIT(j)%Conv_Rdtn%NStepRdtn-1 + WRITE( InitLocal%UnSum, '(1X,I10,2X,E12.5,21(2X,ES16.5))' ) I, I*p%WAMIT(j)%Conv_Rdtn%RdtnDT, & + p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,1,1), p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,1,2), p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,1,3), & + p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,1,4), p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,1,5), p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,1,6), & + p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,2,2), p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,2,3), p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,2,4), & + p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,2,5), p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,2,6), p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,3,3), & + p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,3,4), p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,3,5), p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,3,6), & + p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,4,4), p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,4,5), p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,4,6), & + p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,5,5), p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,5,6), p%WAMIT(j)%Conv_Rdtn%RdtnKrnl(I,6,6) + END DO + end do + end if END IF END IF @@ -1305,12 +1520,8 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I END IF END IF - ! Define system output initializations (set up mesh) here: - - - ! Create the input and output meshes associated with lumped load at the WAMIT reference point (WRP) - - CALL MeshCreate( BlankMesh = u%Mesh & + ! Create the input mesh associated with kinematics of the platform reference point + CALL MeshCreate( BlankMesh = u%PRPMesh & ,IOS = COMPONENT_INPUT & ,Nnodes = 1 & ,ErrStat = ErrStat2 & @@ -1320,106 +1531,138 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I ,TranslationVel = .TRUE. & ,RotationVel = .TRUE. & ,TranslationAcc = .TRUE. & - ,RotationAcc = .TRUE.) - ! Create the node on the mesh - + ,RotationAcc = .TRUE. ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - - CALL MeshPositionNode (u%Mesh & + + CALL MeshPositionNode (u%PRPMesh & , 1 & , (/0.0_ReKi, 0.0_ReKi, 0.0_ReKi/) & , ErrStat2 & , ErrMsg2 ) - - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - - - ! Create the mesh element - CALL MeshConstructElement ( u%Mesh & - , ELEMENT_POINT & - , ErrStat2 & - , ErrMsg2 & - , 1 & - ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + CALL MeshConstructElement ( u%PRPMesh & + , ELEMENT_POINT & + , ErrStat2 & + , ErrMsg2 & + , 1 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - - - CALL MeshCommit ( u%Mesh & - , ErrStat2 & - , ErrMsg2 ) + CALL MeshCommit ( u%PRPMesh & + , ErrStat2 & + , ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF + + IF ( ErrStat >= AbortErrLev ) THEN + CALL CleanUp() + RETURN + END IF + u%PRPMesh%RemapFlag = .TRUE. + + + ! Create the input mesh associated with kinematics of the various WAMIT bodies + IF (p%PotMod >= 1) THEN + CALL MeshCreate( BlankMesh = u%WAMITMesh & + ,IOS = COMPONENT_INPUT & + ,Nnodes = p%NBody & + ,ErrStat = ErrStat2 & + ,ErrMess = ErrMsg2 & + ,TranslationDisp = .TRUE. & + ,Orientation = .TRUE. & + ,TranslationVel = .TRUE. & + ,RotationVel = .TRUE. & + ,TranslationAcc = .TRUE. & + ,RotationAcc = .TRUE. ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + do iBody = 1, p%NBody + theta = (/ 0.0_R8Ki, 0.0_R8Ki, InitLocal%PtfmRefztRot(iBody)/) + orientation = EulerConstruct(theta) + + CALL MeshPositionNode (u%WAMITMesh & + , iBody & + , (/InitLocal%PtfmRefxt(iBody), InitLocal%PtfmRefyt(iBody), InitLocal%PtfmRefzt(iBody)/) & + , ErrStat2 & + , ErrMsg2 & + , orientation ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + CALL MeshConstructElement ( u%WAMITMesh & + , ELEMENT_POINT & + , ErrStat2 & + , ErrMsg2 & + , iBody ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + end do + + CALL MeshCommit ( u%WAMITMesh & + , ErrStat2 & + , ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - CALL MeshCopy ( SrcMesh = u%Mesh & - ,DestMesh = y%Mesh & - ,CtrlCode = MESH_SIBLING & - ,IOS = COMPONENT_OUTPUT & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 & - ,Force = .TRUE. & - ,Moment = .TRUE. ) - - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'HydroDyn_Init:y%Mesh') - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - u%Mesh%RemapFlag = .TRUE. - y%Mesh%RemapFlag = .TRUE. - - CALL MeshCopy ( SrcMesh = y%Mesh & - ,DestMesh = y%AllHdroOrigin & - ,CtrlCode = MESH_NEWCOPY & - ,IOS = COMPONENT_OUTPUT & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 & - ,Force = .TRUE. & - ,Moment = .TRUE. ) - - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'HydroDyn_Init:y%AllHdroOrigin') IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN - END IF - y%AllHdroOrigin%RemapFlag = .TRUE. - - ! we need the translation displacement mesh for loads transfer: - CALL MeshCopy ( SrcMesh = u%Mesh & - , DestMesh = m%AllHdroOrigin_position & - , CtrlCode = MESH_NEWCOPY & - , IOS = COMPONENT_INPUT & - , TranslationDisp = .TRUE. & - , ErrStat = ErrStat2 & - , ErrMess = ErrMsg2 ) ! automatically sets DestMesh%RemapFlag = .TRUE. - - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + END IF + + + ! Output mesh for loads at each WAMIT body + CALL MeshCopy ( SrcMesh = u%WAMITMesh & + ,DestMesh = y%WAMITMesh & + ,CtrlCode = MESH_SIBLING & + ,IOS = COMPONENT_OUTPUT & + ,ErrStat = ErrStat2 & + ,ErrMess = ErrMsg2 & + ,Force = .TRUE. & + ,Moment = .TRUE. ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'HydroDyn_Init:y%WAMITMesh') IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN END IF - m%AllHdroOrigin_position%TranslationDisp = 0.0 ! bjj: this is actually initialized in the ModMesh module, but I'll do it here anyway. - - - ! Create the Output file if requested + u%WAMITMesh%RemapFlag = .TRUE. + y%WAMITMesh%RemapFlag = .TRUE. + ENDIF ! PotMod > 1 + + + ! Create helper mesh to map all Hydrodynamics loads to the platform reference point to (0,0,0) + CALL MeshCreate ( BlankMesh = m%AllHdroOrigin & + ,IOS = COMPONENT_OUTPUT & + ,Nnodes = 1 & + ,ErrStat = ErrStat2 & + ,ErrMess = ErrMsg2 & + ,Force = .TRUE. & + ,Moment = .TRUE. ) + + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'HydroDyn_Init:m%AllHdroOrigin') + + CALL MeshPositionNode (m%AllHdroOrigin & + , 1 & + , (/0.0_ReKi, 0.0_ReKi, 0.0_ReKi/) & + , ErrStat2 & + , ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + CALL MeshConstructElement ( m%AllHdroOrigin & + , ELEMENT_POINT & + , ErrStat2 & + , ErrMsg2 & + , 1 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + CALL MeshCommit ( m%AllHdroOrigin & + , ErrStat2 & + , ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + CALL CleanUp() + RETURN + END IF + m%AllHdroOrigin%RemapFlag = .TRUE. + + ! Create the Output file if requested p%OutSwtch = InitLocal%OutSwtch p%Delim = '' !p%Morison%Delim = p%Delim ! Need to set this from within Morison to follow framework @@ -1428,39 +1671,24 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I p%OutSFmt = InitLocal%OutSFmt p%NumOuts = InitLocal%NumOuts - CALL HDOUT_Init( HydroDyn_ProgDesc, InitLocal, y, p, m, InitOut, ErrStat2, ErrMsg2 ) - - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + CALL HDOUT_Init( HydroDyn_ProgDesc, InitLocal, y, p, m, InitOut, ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp() RETURN END IF + + if ( y%WAMITMesh%Committed ) then + call MeshMapCreate( y%WAMITMesh, m%AllHdroOrigin, m%HD_MeshMap%W_P_2_PRP_P, ErrStat2, ErrMsg2 );CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + end if - ! Create some mesh mapping data - CALL MeshCopy ( SrcMesh = y%Mesh & - ,DestMesh = m%y_mapped & - ,CtrlCode = MESH_NEWCOPY & - ,IOS = COMPONENT_OUTPUT & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 & - ,Force = .TRUE. & - ,Moment = .TRUE. ) - - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - m%y_mapped%RemapFlag = .TRUE. - - CALL MeshMapCreate( y%Mesh, m%y_mapped, m%HD_MeshMap%HD_P_2_WRP_P, ErrStat2, ErrMsg2 );CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - IF ( y%Morison%LumpedMesh%Committed ) THEN - CALL MeshMapCreate( y%Morison%LumpedMesh, m%y_mapped, m%HD_MeshMap%M_P_2_WRP_P, ErrStat2, ErrMsg2 );CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - ENDIF - IF ( y%Morison%DistribMesh%Committed ) THEN - CALL MeshMapCreate( y%Morison%DistribMesh, m%y_mapped, m%HD_MeshMap%M_L_2_WRP_P, ErrStat2, ErrMsg2 );CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + IF ( y%Morison%Mesh%Committed ) THEN + CALL MeshMapCreate( y%Morison%Mesh, m%AllHdroOrigin, m%HD_MeshMap%M_P_2_PRP_P, ErrStat2, ErrMsg2 );CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) ENDIF - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF + IF ( ErrStat >= AbortErrLev ) THEN + CALL CleanUp() + RETURN + END IF ! Define initialization-routine output here: InitOut%Ver = HydroDyn_ProgDesc @@ -1468,10 +1696,9 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I InitOut%WtrDens = InitLocal%Morison%WtrDens InitOut%WtrDpth = InitLocal%Morison%WtrDpth InitOut%MSL2SWL = InitLocal%Morison%MSL2SWL - - p%WtrDpth = InitOut%WtrDpth + p%WtrDpth = InitOut%WtrDpth - IF ( InitInp%hasIce ) THEN + IF ( InitLocal%hasIce ) THEN IF ((InitLocal%Waves%WaveMod /= 0) .OR. (InitLocal%Current%CurrMod /= 0) ) THEN CALL SetErrStat(ErrID_Fatal,'Waves and Current must be turned off in HydroDyn when ice loading is computed. Set WaveMod=0 and CurrMod=0.',ErrStat,ErrMsg,RoutineName) END IF @@ -1618,8 +1845,8 @@ SUBROUTINE HydroDyn_UpdateStates( t, n, Inputs, InputTimes, p, x, xd, z, OtherSt CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None ! Local variables - INTEGER :: I ! Generic loop counter - TYPE(HydroDyn_ContinuousStateType) :: dxdt ! Continuous state derivatives at t + INTEGER :: I, iWAMIT, iBody ! Generic loop counters +! TYPE(HydroDyn_ContinuousStateType) :: dxdt ! Continuous state derivatives at t TYPE(HydroDyn_DiscreteStateType) :: xd_t ! Discrete states at t (copy) TYPE(HydroDyn_ConstraintStateType) :: z_Residual ! Residual of the constraint state functions (Z) TYPE(HydroDyn_InputType) :: u ! Instantaneous inputs @@ -1656,44 +1883,66 @@ SUBROUTINE HydroDyn_UpdateStates( t, n, Inputs, InputTimes, p, x, xd, z, OtherSt ! Allocate array of WAMIT inputs - ! TODO: We should avoid allocating this at each time step if we can! !FIXME: Error handling appears to be broken here IF ( p%PotMod == 1 ) THEN + ALLOCATE( Inputs_WAMIT(nTime), STAT = ErrStat2 ) IF (ErrStat2 /=0) THEN CALL SetErrStat( ErrID_Fatal, 'Failed to allocate array Inputs_WAMIT.', ErrStat, ErrMsg, RoutineName ) RETURN END IF + if ( p%NBodyMod == 1 .or. p%NBody == 1 ) then + ! For this NBodyMod or NBody=1, there is only one WAMIT object, so copy the necessary inputs and then call WAMIT_UpdateStates + do I=1,nTime + ! Copy the inputs from the HD mesh into the WAMIT mesh + call MeshCopy( Inputs(I)%WAMITMesh, Inputs_WAMIT(I)%Mesh, MESH_NEWCOPY, ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + end do - ! Loop over number of inputs and copy them into an array of WAMIT inputs + if (ErrStat < AbortErrLev) then ! if there was an error copying the input meshes, we'll skip this step and then cleanup the temporary input meshes + ! Update the WAMIT module states - DO I=1,nTime - - ! Copy the inputs from the HD mesh into the WAMIT mesh - CALL MeshCopy( Inputs(I)%Mesh, Inputs_WAMIT(I)%Mesh, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call WAMIT_UpdateStates( t, n, Inputs_WAMIT, InputTimes, p%WAMIT(1), x%WAMIT(1), xd%WAMIT(1), z%WAMIT, OtherState%WAMIT(1), m%WAMIT(1), ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + end if - END DO - + else - IF (ErrStat < AbortErrLev) THEN ! if there was an error copying the input meshes, we'll skip this step and then cleanup the temporary input meshes - ! Update the WAMIT module states - - CALL WAMIT_UpdateStates( t, n, Inputs_WAMIT, InputTimes, p%WAMIT, x%WAMIT, xd%WAMIT, z%WAMIT, OtherState%WAMIT, m%WAMIT, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - END IF - + ! We have multiple WAMIT objects + + ! Loop over number of inputs and copy them into an array of WAMIT inputs + do iWAMIT = 1, p%nWAMITObj + + do I=1,nTime + ! We need to create to valid mesh data structures in our Inputs_WAMIT(I)%Mesh using the miscvar version as a template, but the actually data will be generated below + call MeshCopy( m%u_WAMIT(iWAMIT)%Mesh, Inputs_WAMIT(I)%Mesh, MESH_NEWCOPY, ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! We need to copy the iWAMIT-th node data from the Inputs(I)%WAMITMesh onto the 1st node of the Inputs_WAMIT(I)%Mesh + Inputs_WAMIT(I)%Mesh%TranslationDisp(:,1) = Inputs(I)%WAMITMesh%TranslationDisp(:,iWAMIT) + Inputs_WAMIT(I)%Mesh%Orientation (:,:,1)= Inputs(I)%WAMITMesh%Orientation (:,:,iWAMIT) + Inputs_WAMIT(I)%Mesh%TranslationVel (:,1) = Inputs(I)%WAMITMesh%TranslationVel (:,iWAMIT) + Inputs_WAMIT(I)%Mesh%RotationVel (:,1) = Inputs(I)%WAMITMesh%RotationVel (:,iWAMIT) + Inputs_WAMIT(I)%Mesh%TranslationAcc (:,1) = Inputs(I)%WAMITMesh%TranslationAcc (:,iWAMIT) + Inputs_WAMIT(I)%Mesh%RotationAcc (:,1) = Inputs(I)%WAMITMesh%RotationAcc (:,iWAMIT) + end do + + ! UpdateStates for the iWAMIT-th body + call WAMIT_UpdateStates( t, n, Inputs_WAMIT, InputTimes, p%WAMIT(iWAMIT), x%WAMIT(iWAMIT), xd%WAMIT(iWAMIT), z%WAMIT, OtherState%WAMIT(iWAMIT), m%WAMIT(iWAMIT), ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (ErrStat > AbortErrLev) exit + + end do + + end if + ! deallocate temporary inputs - DO I=1,nTime - CALL WAMIT_DestroyInput( Inputs_WAMIT(I), ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - END DO + do I=1,nTime + call WAMIT_DestroyInput( Inputs_WAMIT(I), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + end do - DEALLOCATE(Inputs_WAMIT) + deallocate(Inputs_WAMIT) #ifdef USE_FIT ELSE IF ( p%PotMod == 2 ) THEN ! FIT @@ -1712,13 +1961,13 @@ SUBROUTINE HydroDyn_UpdateStates( t, n, Inputs, InputTimes, p, x, xd, z, OtherSt ! Copy the inputs from the HD mesh into the FIT input variables ! Determine the rotational angles from the direction-cosine matrix - rotdisp = GetSmllRotAngs ( Inputs(I)%Mesh%Orientation(:,:,1), ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) + rotdisp = GetSmllRotAngs ( Inputs(I)%WAMITMesh%Orientation(:,:,1), ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_UpdateStates' ) Inputs_FIT(I)%roll = rotdisp(1) Inputs_FIT(I)%pitch = rotdisp(2) Inputs_FIT(I)%yaw = rotdisp(3) - Inputs_FIT(I)%si_t(:) = Inputs(I)%Mesh%TranslationDisp(:,1) - Inputs_FIT(I)%vel_t(:) = Inputs(I)%Mesh%TranslationVel (:,1) + Inputs_FIT(I)%si_t(:) = Inputs(I)%WAMITMesh%TranslationDisp(:,1) + Inputs_FIT(I)%vel_t(:) = Inputs(I)%WAMITMesh%TranslationVel (:,1) END DO @@ -1749,7 +1998,7 @@ END SUBROUTINE HydroDyn_UpdateStates SUBROUTINE HydroDyn_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds - TYPE(HydroDyn_InputType), INTENT(INOUT) :: u !< Inputs at Time (note that this is intent out because we're copying the u%mesh into m%u_wamit%mesh) + TYPE(HydroDyn_InputType), INTENT(INOUT) :: u !< Inputs at Time (note that this is intent out because we're copying the u%WAMITMesh into m%u_wamit%mesh) TYPE(HydroDyn_ParameterType), INTENT(IN ) :: p !< Parameters TYPE(HydroDyn_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time TYPE(HydroDyn_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at Time @@ -1773,16 +2022,19 @@ SUBROUTINE HydroDyn_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, #endif REAL(ReKi) :: WaveElev (p%NWaveElev) ! Instantaneous total elevation of incident waves at each of the NWaveElev points where the incident wave elevations can be output (meters) REAL(ReKi) :: WaveElev1(p%NWaveElev) ! Instantaneous first order elevation of incident waves at each of the NWaveElev points where the incident wave elevations can be output (meters) + REAL(ReKi) :: WaveElev2(p%NWaveElev) ! Instantaneous first order elevation of incident waves at each of the NWaveElev points where the incident wave elevations can be output (meters) - REAL(ReKi) :: q(6), qdot(6), qdotsq(6), qdotdot(6) + REAL(ReKi) :: q(6*p%NBody), qdot(6*p%NBody), qdotsq(6*p%NBody), qdotdot(6*p%NBody) REAL(ReKi) :: rotdisp(3) ! small angle rotational displacements REAL(ReKi) :: AllOuts(MaxHDOutputs) - + integer(IntKi) :: iBody, indxStart, indxEnd, iWAMIT ! Counters ! Initialize ErrStat ErrStat = ErrID_None - ErrMsg = "" + ErrMsg = "" + WaveElev1 = 0.0_ReKi + WaveElev2 = 0.0_ReKi ! In case we don't use 2nd order waves ! Compute outputs here: @@ -1792,7 +2044,6 @@ SUBROUTINE HydroDyn_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, ! Additional stiffness, damping forces. These need to be placed on a point mesh which is located at the WAMIT reference point (WRP). ! This mesh will need to get mapped by the glue code for use by either ElastoDyn or SubDyn. !------------------------------------------------------------------- -!bjj: if these are false in the input file, the parameter verions of these variables don't get set: ! Deal with any output from the Waves2 module.... IF (p%Waves2%WvDiffQTFF .OR. p%Waves2%WvSumQTFF ) THEN @@ -1804,105 +2055,178 @@ SUBROUTINE HydroDyn_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) END IF -!FIXME: Error handling appears to be broken here. - ! Determine the rotational angles from the direction-cosine matrix - rotdisp = GetSmllRotAngs ( u%Mesh%Orientation(:,:,1), ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) - - q = reshape((/REAL(u%Mesh%TranslationDisp(:,1),ReKi),rotdisp(:)/),(/6/)) - qdot = reshape((/u%Mesh%TranslationVel(:,1),u%Mesh%RotationVel(:,1)/),(/6/)) - qdotsq = abs(qdot)*qdot - qdotdot = reshape((/u%Mesh%TranslationAcc(:,1),u%Mesh%RotationAcc(:,1)/),(/6/)) - - - ! Compute the load contirbution from user-supplied added stiffness and damping + if ( p%PotMod == 1 ) then + do iBody = 1, p%NBody + ! Determine the rotational angles from the direction-cosine matrix + rotdisp = GetSmllRotAngs ( u%WAMITMesh%Orientation(:,:,iBody), ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) + indxStart = (iBody-1)*6+1 + indxEnd = indxStart+5 + q (indxStart:indxEnd) = reshape((/real(u%WAMITMesh%TranslationDisp(:,iBody),ReKi),rotdisp(:)/),(/6/)) + qdot (indxStart:indxEnd) = reshape((/u%WAMITMesh%TranslationVel(:,iBody),u%WAMITMesh%RotationVel(:,iBody)/),(/6/)) + qdotsq (indxStart:indxEnd) = abs(qdot(indxStart:indxEnd))*qdot(indxStart:indxEnd) + qdotdot(indxStart:indxEnd) = reshape((/u%WAMITMesh%TranslationAcc(:,iBody),u%WAMITMesh%RotationAcc(:,iBody)/),(/6/)) + end do + !FIXME: Error handling appears to be broken here. + if ( p%NBodyMod == 1 ) then + + ! Compute the load contirbution from user-supplied added stiffness and damping + m%F_PtfmAdd = p%AddF0(:,1) - matmul(p%AddCLin(:,:,1), q) - matmul(p%AddBLin(:,:,1), qdot) - matmul(p%AddBQuad(:,:,1), qdotsq) + do iBody = 1, p%NBody + indxStart = (iBody-1)*6+1 + indxEnd = indxStart+5 + ! Attach to the output point mesh + y%WAMITMesh%Force (:,iBody) = m%F_PtfmAdd(indxStart:indxStart+2) + y%WAMITMesh%Moment(:,iBody) = m%F_PtfmAdd(indxStart+3:indxEnd) + end do - m%F_PtfmAdd = p%AddF0 - matmul(p%AddCLin, q) - matmul(p%AddBLin, qdot) - matmul(p%AddBQuad, qdotsq) - - ! Attach to the output point mesh - y%Mesh%Force (:,1) = m%F_PtfmAdd(1:3) - y%Mesh%Moment(:,1) = m%F_PtfmAdd(4:6) + else + do iBody = 1, p%NBody + indxStart = (iBody-1)*6+1 + indxEnd = indxStart+5 + + m%F_PtfmAdd(indxStart:indxEnd) = p%AddF0(:,1) - matmul(p%AddCLin(:,:,iBody), q(indxStart:indxEnd)) - matmul(p%AddBLin(:,:,iBody), qdot(indxStart:indxEnd)) - matmul(p%AddBQuad(:,:,iBody), qdotsq(indxStart:indxEnd)) - IF ( p%PotMod == 1 ) THEN - IF ( m%u_WAMIT%Mesh%Committed ) THEN ! Make sure we are using WAMIT / there is a valid mesh - - ! Copy the inputs from the HD mesh into the WAMIT mesh - CALL MeshCopy( u%Mesh, m%u_WAMIT%Mesh, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL WAMIT_CalcOutput( Time, m%u_WAMIT, p%WAMIT, x%WAMIT, xd%WAMIT, & - z%WAMIT, OtherState%WAMIT, y%WAMIT, m%WAMIT, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) - - ! Add WAMIT forces to the HydroDyn output mesh - y%Mesh%Force (:,1) = y%Mesh%Force (:,1) + y%WAMIT%Mesh%Force (:,1) - y%Mesh%Moment(:,1) = y%Mesh%Moment(:,1) + y%WAMIT%Mesh%Moment(:,1) + ! Attach to the output point mesh + y%WAMITMesh%Force (:,iBody) = m%F_PtfmAdd(indxStart:indxStart+2) + y%WAMITMesh%Moment(:,iBody) = m%F_PtfmAdd(indxStart+3:indxEnd) + end do + end if + + m%F_Waves = 0.0_ReKi + + if (allocated(m%u_WAMIT)) then ! Check that we allocated u_WAMIT, otherwise there is an error checking the mesh + if ( m%u_WAMIT(1)%Mesh%Committed ) then ! Make sure we are using WAMIT / there is a valid mesh + + if ( p%NBodyMod == 1 .or. p%NBody == 1 ) then + ! Copy the inputs from the HD mesh into the WAMIT mesh + call MeshCopy( u%WAMITMesh, m%u_WAMIT(1)%Mesh, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) + if ( ErrStat >= AbortErrLev ) return + + call WAMIT_CalcOutput( Time, p%WaveTime, m%u_WAMIT(1), p%WAMIT(1), x%WAMIT(1), xd%WAMIT(1), & + z%WAMIT, OtherState%WAMIT(1), y%WAMIT(1), m%WAMIT(1), ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) + do iBody=1,p%NBody + y%WAMITMesh%Force (:,iBody) = y%WAMITMesh%Force (:,iBody) + y%WAMIT(1)%Mesh%Force (:,iBody) + y%WAMITMesh%Moment(:,iBody) = y%WAMITMesh%Moment(:,iBody) + y%WAMIT(1)%Mesh%Moment(:,iBody) + + end do + ! Copy the F_Waves1 information to the HydroDyn level so we can combine it with the 2nd order + m%F_Waves = m%F_Waves + m%WAMIT(1)%F_Waves1 + else + do iBody=1,p%NBody + + ! We need to copy the iWAMIT-th node data from the Inputs(I)%WAMITMesh onto the 1st node of the Inputs_WAMIT(I)%Mesh + m%u_WAMIT(iBody)%Mesh%TranslationDisp(:,1) = u%WAMITMesh%TranslationDisp(:,iBody) + m%u_WAMIT(iBody)%Mesh%Orientation (:,:,1)= u%WAMITMesh%Orientation (:,:,iBody) + m%u_WAMIT(iBody)%Mesh%TranslationVel (:,1) = u%WAMITMesh%TranslationVel (:,iBody) + m%u_WAMIT(iBody)%Mesh%RotationVel (:,1) = u%WAMITMesh%RotationVel (:,iBody) + m%u_WAMIT(iBody)%Mesh%TranslationAcc (:,1) = u%WAMITMesh%TranslationAcc (:,iBody) + m%u_WAMIT(iBody)%Mesh%RotationAcc (:,1) = u%WAMITMesh%RotationAcc (:,iBody) + + call WAMIT_CalcOutput( Time, p%WaveTime, m%u_WAMIT(iBody), p%WAMIT(iBody), x%WAMIT(iBody), xd%WAMIT(iBody), & + z%WAMIT, OtherState%WAMIT(iBody), y%WAMIT(iBody), m%WAMIT(iBody), ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) + y%WAMITMesh%Force (:,iBody) = y%WAMITMesh%Force (:,iBody) + y%WAMIT(iBody)%Mesh%Force (:,1) + y%WAMITMesh%Moment(:,iBody) = y%WAMITMesh%Moment(:,iBody) + y%WAMIT(iBody)%Mesh%Moment(:,1) + + ! Copy the F_Waves1 information to the HydroDyn level so we can combine it with the 2nd order + indxStart = (iBody-1)*6+1 + indxEnd = indxStart+5 + m%F_Waves(indxStart:indxEnd) = m%F_Waves(indxStart:indxEnd) + m%WAMIT(iBody)%F_Waves1 + end do + end if + end if ! m%u_WAMIT(1)%Mesh%Committed + end if ! m%u_WAMIT is allocated + + + + ! Second order + if (p%WAMIT2used) then + + if ( p%NBodyMod == 1 .or. p%NBody == 1 ) then + ! Copy the inputs from the HD mesh into the WAMIT mesh + call MeshCopy( u%WAMITMesh, m%u_WAMIT2(1)%Mesh, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) + if ( ErrStat >= AbortErrLev ) return + call WAMIT2_CalcOutput( Time, p%WaveTime, m%u_WAMIT2(1), p%WAMIT2(1), x%WAMIT2(1), xd%WAMIT2(1), & + z%WAMIT2, OtherState%WAMIT2(1), y%WAMIT2(1), m%WAMIT2(1), ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) + do iBody=1,p%NBody + y%WAMITMesh%Force (:,iBody) = y%WAMITMesh%Force (:,iBody) + y%WAMIT2(1)%Mesh%Force (:,iBody) + y%WAMITMesh%Moment(:,iBody) = y%WAMITMesh%Moment(:,iBody) + y%WAMIT2(1)%Mesh%Moment(:,iBody) + end do + ! Add F_Waves2 to m%F_Waves + m%F_Waves = m%F_Waves + m%WAMIT2(1)%F_Waves2 + else + do iBody=1,p%NBody + + ! We need to copy the iWAMIT2-th node data from the Inputs(I)%WAMIT2Mesh onto the 1st node of the Inputs_WAMIT2(I)%Mesh + m%u_WAMIT2(iBody)%Mesh%TranslationDisp(:,1) = u%WAMITMesh%TranslationDisp(:,iBody) + m%u_WAMIT2(iBody)%Mesh%Orientation (:,:,1)= u%WAMITMesh%Orientation (:,:,iBody) + m%u_WAMIT2(iBody)%Mesh%TranslationVel (:,1) = u%WAMITMesh%TranslationVel (:,iBody) + m%u_WAMIT2(iBody)%Mesh%RotationVel (:,1) = u%WAMITMesh%RotationVel (:,iBody) + m%u_WAMIT2(iBody)%Mesh%TranslationAcc (:,1) = u%WAMITMesh%TranslationAcc (:,iBody) + m%u_WAMIT2(iBody)%Mesh%RotationAcc (:,1) = u%WAMITMesh%RotationAcc (:,iBody) + + call WAMIT2_CalcOutput( Time, p%WaveTime, m%u_WAMIT2(iBody), p%WAMIT2(iBody), x%WAMIT2(iBody), xd%WAMIT2(iBody), & + z%WAMIT2, OtherState%WAMIT2(iBody), y%WAMIT2(iBody), m%WAMIT2(iBody), ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) + y%WAMITMesh%Force (:,iBody) = y%WAMITMesh%Force (:,iBody) + y%WAMIT2(iBody)%Mesh%Force (:,1) + y%WAMITMesh%Moment(:,iBody) = y%WAMITMesh%Moment(:,iBody) + y%WAMIT2(iBody)%Mesh%Moment(:,1) + + ! Copy the F_Waves1 information to the HydroDyn level so we can combine it with the 2nd order + indxStart = (iBody-1)*6+1 + indxEnd = indxStart+5 + m%F_Waves(indxStart:indxEnd) = m%F_Waves(indxStart:indxEnd) + m%WAMIT2(iBody)%F_Waves2 + end do + end if + end if ! p%WAMIT2used - ! Copy the F_Waves1 information to the HydroDyn level so we can combine it with the 2nd order - m%F_Waves = m%WAMIT%F_Waves1 - - - END IF - #ifdef USE_FIT ELSE IF ( p%PotMod ==2 ) THEN !FIT Inputs_FIT%roll = rotdisp(1) Inputs_FIT%pitch = rotdisp(2) Inputs_FIT%yaw = rotdisp(3) - Inputs_FIT%si_t(:) = u%Mesh%TranslationDisp(:,1) - Inputs_FIT%vel_t(:) = u%Mesh%TranslationVel (:,1) + Inputs_FIT%si_t(:) = u%WAMITMesh%TranslationDisp(:,1) + Inputs_FIT%vel_t(:) = u%WAMITMesh%TranslationVel (:,1) CALL FIT_CalcOutput( Time, Inputs_FIT, p%FIT, FIT_x, xd%FIT, FIT_z, OtherState%FIT, y%FIT, ErrStat2, ErrMsg2 ) ! Add FIT forces to the HydroDyn output mesh - y%Mesh%Force (:,1) = y%Mesh%Force (:,1) + y%FIT%F(:) - y%Mesh%Moment(:,1) = y%Mesh%Moment(:,1) + y%FIT%M(:) + y%WAMITMesh%Force (:,1) = y%WAMITMesh%Force (:,1) + y%FIT%F(:) + y%WAMITMesh%Moment(:,1) = y%WAMITMesh%Moment(:,1) + y%FIT%M(:) #endif END IF - IF ( m%u_WAMIT2%Mesh%Committed ) THEN ! Make sure we are using WAMIT2 / there is a valid mesh - - ! Copy the inputs from the HD mesh into the WAMIT2 mesh - CALL MeshCopy( u%Mesh, m%u_WAMIT2%Mesh, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) - IF ( ErrStat >= AbortErrLev ) RETURN - - CALL WAMIT2_CalcOutput( Time, m%u_WAMIT2, p%WAMIT2, x%WAMIT2, xd%WAMIT2, & - z%WAMIT2, OtherState%WAMIT2, y%WAMIT2, m%WAMIT2, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) - - ! Add WAMIT2 forces to the HydroDyn output mesh - y%Mesh%Force (:,1) = y%Mesh%Force (:,1) + y%WAMIT2%Mesh%Force (:,1) - y%Mesh%Moment(:,1) = y%Mesh%Moment(:,1) + y%WAMIT2%Mesh%Moment(:,1) - - ! Add the second order WAMIT forces to the first order WAMIT forces for the total (this is just to make the mesh match this misc var) - m%F_Waves = m%F_Waves + m%WAMIT2%F_Waves2 - - END IF - - - - IF ( u%Morison%LumpedMesh%Committed ) THEN ! Make sure we are using Morison / there is a valid mesh + IF ( u%Morison%Mesh%Committed ) THEN ! Make sure we are using Morison / there is a valid mesh CALL Morison_CalcOutput( Time, u%Morison, p%Morison, x%Morison, xd%Morison, & z%Morison, OtherState%Morison, y%Morison, m%Morison, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) END IF - ! Integrate all the mesh loads onto the WAMIT reference Point (WRP) at (0,0,0) - m%F_Hydro = CalcLoadsAtWRP( y, u, m%y_mapped, m%AllHdroOrigin_position, m%MrsnLumpedMesh_position, m%MrsnDistribMesh_position, m%HD_MeshMap, ErrStat2, ErrMsg2 ) + ! Integrate all the mesh loads onto the platfrom reference Point (PRP) at (0,0,0) + m%F_Hydro = CalcLoadsAtWRP( y, u, m%AllHdroOrigin, u%PRPMesh, m%MrsnMesh_position, m%HD_MeshMap, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) ! Compute the wave elevations at the requested output locations for this time. Note that p%WaveElev has the second order added to it already. - DO I=1,p%NWaveElev + ! Second order wave elevation, if calculated (This array is split out for speed because of the if) + if (allocated(p%WaveElev2)) then + DO I=1,p%NWaveElev + WaveElev2(I) = InterpWrappedStpReal ( REAL(Time, SiKi), p%WaveTime(:), p%WaveElev2(:,I), & + m%LastIndWave, p%NStepWave + 1 ) + END DO + endif + + DO I=1,p%NWaveElev WaveElev1(I) = InterpWrappedStpReal ( REAL(Time, SiKi), p%WaveTime(:), p%WaveElev1(:,I), & m%LastIndWave, p%NStepWave + 1 ) WaveElev(I) = InterpWrappedStpReal ( REAL(Time, SiKi), p%WaveTime(:), p%WaveElev(:,I), & @@ -1923,7 +2247,7 @@ SUBROUTINE HydroDyn_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, ! Map calculated results into the AllOuts Array - CALL HDOut_MapOutputs( Time, y, p%NWaveElev, WaveElev, WaveElev1, m%F_PtfmAdd, m%F_Waves, m%F_Hydro, q, qdot, qdotdot, AllOuts, ErrStat2, ErrMsg2 ) + CALL HDOut_MapOutputs( Time, p, y, m%WAMIT, m%WAMIT2, p%NWaveElev, WaveElev, WaveElev1, WaveElev2, m%F_PtfmAdd, m%F_Waves, m%F_Hydro, u%PRPMesh, q, qdot, qdotdot, AllOuts, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDyn_CalcOutput' ) DO I = 1,p%NumOuts @@ -1936,13 +2260,6 @@ SUBROUTINE HydroDyn_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, J = p%NumOuts + 1 - IF (ALLOCATED( p%WAMIT%OutParam ) .AND. p%WAMIT%NumOuts > 0) THEN - DO I=1, p%WAMIT%NumOuts - y%WriteOutput(J) = y%WAMIT%WriteOutput(I) - J = J + 1 - END DO - END IF - IF (ALLOCATED( p%Waves2%OutParam ) .AND. p%Waves2%NumOuts > 0) THEN DO I=1, p%Waves2%NumOuts y%WriteOutput(J) = y%Waves2%WriteOutput(I) @@ -1950,13 +2267,6 @@ SUBROUTINE HydroDyn_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, END DO END IF - IF (ALLOCATED( p%WAMIT2%OutParam ) .AND. p%WAMIT2%NumOuts > 0) THEN - DO I=1, p%WAMIT2%NumOuts - y%WriteOutput(J) = y%WAMIT2%WriteOutput(I) - J = J + 1 - END DO - END IF - IF (ALLOCATED( p%Morison%OutParam ) .AND. p%Morison%NumOuts > 0) THEN DO I=1, p%Morison%NumOuts y%WriteOutput(J) = y%Morison%WriteOutput(I) @@ -1986,7 +2296,7 @@ SUBROUTINE HydroDyn_CalcContStateDeriv( Time, u, p, x, xd, z, OtherState, m, dxd TYPE(HydroDyn_ContinuousStateType), INTENT( OUT) :: dxdt !< Continuous state derivatives at Time INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - + integer(IntKi) :: iWAMIT ! loop counter CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_CalcContStateDeriv' ! Initialize ErrStat @@ -1996,58 +2306,43 @@ SUBROUTINE HydroDyn_CalcContStateDeriv( Time, u, p, x, xd, z, OtherState, m, dxd ! Compute the first time derivatives of the continuous states here: - - IF ( m%u_WAMIT%Mesh%Committed ) THEN ! Make sure we are using WAMIT / there is a valid mesh - + if ( .not. m%u_WAMIT(1)%Mesh%Committed ) return ! Make sure we are using WAMIT / there is a valid mesh + + call HydroDyn_CopyContState( x, dxdt, MESH_NEWCOPY, ErrStat, ErrMsg) + if ( ErrStat >= AbortErrLev ) return + + if ( p%NBodyMod == 1 .or. p%NBody == 1 ) then ! Copy the inputs from the HD mesh into the WAMIT mesh - CALL MeshCopy( u%Mesh, m%u_WAMIT%Mesh, MESH_UPDATECOPY, ErrStat, ErrMsg ) - IF ( ErrStat >= AbortErrLev ) RETURN + call MeshCopy( u%WAMITMesh, m%u_WAMIT(1)%Mesh, MESH_UPDATECOPY, ErrStat, ErrMsg ) + if ( ErrStat >= AbortErrLev ) return - CALL WAMIT_CalcContStateDeriv( Time, m%u_WAMIT, p%WAMIT, x%WAMIT, xd%WAMIT, z%WAMIT, OtherState%WAMIT, m%WAMIT, dxdt%WAMIT, ErrStat, ErrMsg ) - - END IF + call WAMIT_CalcContStateDeriv( Time, m%u_WAMIT(1), p%WAMIT(1), x%WAMIT(1), xd%WAMIT(1), z%WAMIT, OtherState%WAMIT(1), m%WAMIT(1), dxdt%WAMIT(1), ErrStat, ErrMsg ) + else + + ! We have multiple WAMIT objects + + ! Loop over number of inputs and copy them into an array of WAMIT inputs + do iWAMIT = 1, p%nWAMITObj + + ! We need to copy the iWAMIT-th node data from the Inputs(I)%WAMITMesh onto the 1st node of the Inputs_WAMIT(I)%Mesh + m%u_WAMIT(iWAMIT)%Mesh%TranslationDisp(:,1) = u%WAMITMesh%TranslationDisp(:,iWAMIT) + m%u_WAMIT(iWAMIT)%Mesh%Orientation (:,:,1)= u%WAMITMesh%Orientation (:,:,iWAMIT) + m%u_WAMIT(iWAMIT)%Mesh%TranslationVel (:,1) = u%WAMITMesh%TranslationVel (:,iWAMIT) + m%u_WAMIT(iWAMIT)%Mesh%RotationVel (:,1) = u%WAMITMesh%RotationVel (:,iWAMIT) + m%u_WAMIT(iWAMIT)%Mesh%TranslationAcc (:,1) = u%WAMITMesh%TranslationAcc (:,iWAMIT) + m%u_WAMIT(iWAMIT)%Mesh%RotationAcc (:,1) = u%WAMITMesh%RotationAcc (:,iWAMIT) + + ! UpdateStates for the iWAMIT-th body + call WAMIT_CalcContStateDeriv( Time, m%u_WAMIT(iWAMIT), p%WAMIT(iWAMIT), x%WAMIT(iWAMIT), xd%WAMIT(iWAMIT), z%WAMIT, OtherState%WAMIT(iWAMIT), m%WAMIT(iWAMIT), dxdt%WAMIT(iWAMIT), ErrStat, ErrMsg ) + if (ErrStat > AbortErrLev) exit + + end do + + end if END SUBROUTINE HydroDyn_CalcContStateDeriv -!---------------------------------------------------------------------------------------------------------------------------------- -! Tight coupling routine for updating discrete states. Note that the WAMIT_UpdateDiscState violates the framework by having OtherStates -! be intent in/out. If/when this is fixed we can uncomment this routine. -!SUBROUTINE HydroDyn_UpdateDiscState( Time, n, u, p, x, xd, z, OtherState, m, ErrStat, ErrMsg ) -! -! REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds -! INTEGER(IntKi), INTENT(IN ) :: n !< Current step of the simulation: t = n*Interval -! TYPE(HydroDyn_InputType), INTENT(IN ) :: u !< Inputs at Time -! TYPE(HydroDyn_ParameterType), INTENT(IN ) :: p !< Parameters -! TYPE(HydroDyn_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time -! TYPE(HydroDyn_DiscreteStateType), INTENT(INOUT) :: xd !< Input: Discrete states at Time; -! !! Output: Discrete states at Time + Interval -! TYPE(HydroDyn_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at Time -! TYPE(HydroDyn_OtherStateType), INTENT(IN ) :: OtherState !< Other/optimization states -! TYPE(HydroDyn_MiscVarType), INTENT(INOUT) :: m !< Initial misc/optimization variables -! INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation -! CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None -! -! -! ! Initialize ErrStat -! -! ErrStat = ErrID_None -! ErrMsg = "" -! -! -! ! Update discrete states -! -! IF ( m%u_WAMIT%Mesh%Committed ) THEN ! Make sure we are using WAMIT / there is a valid mesh -! -! ! Copy the inputs from the HD mesh into the WAMIT mesh -! CALL MeshCopy( u%Mesh, m%u_WAMIT%Mesh, MESH_UPDATECOPY, ErrStat, ErrMsg ) -! IF ( ErrStat >= AbortErrLev ) RETURN -! -! CALL WAMIT_UpdateDiscState( Time, n, m%u_WAMIT, p%WAMIT, x%WAMIT, xd%WAMIT, z%WAMIT, OtherState%WAMIT, m%WAMIT, ErrStat, ErrMsg ) -! IF ( ErrStat >= AbortErrLev ) RETURN -! END IF -! -!END SUBROUTINE HydroDyn_UpdateDiscState !---------------------------------------------------------------------------------------------------------------------------------- @@ -2073,110 +2368,59 @@ SUBROUTINE HydroDyn_CalcConstrStateResidual( Time, u, p, x, xd, z, OtherState, m ErrStat = ErrID_None ErrMsg = "" - + ! Nothing to do here since none of the sub-modules have contraint states + z_residual = z + ! Solve for the constraint states here: - - IF ( m%u_WAMIT%Mesh%Committed ) THEN ! Make sure we are using WAMIT / there is a valid mesh - - ! Copy the inputs from the HD mesh into the WAMIT mesh - CALL MeshCopy( u%Mesh, m%u_WAMIT%Mesh, MESH_UPDATECOPY, ErrStat, ErrMsg ) - IF ( ErrStat >= AbortErrLev ) RETURN - - call WAMIT_CalcConstrStateResidual( Time, m%u_WAMIT, p%WAMIT, x%WAMIT, xd%WAMIT, z%WAMIT, OtherState%WAMIT, m%WAMIT, z_residual%WAMIT, ErrStat, ErrMsg ) - - END IF END SUBROUTINE HydroDyn_CalcConstrStateResidual !---------------------------------------------------------------------------------------------------------------------------------- -FUNCTION CalcLoadsAtWRP( y, u, y_mapped, AllHdroOrigin_position, MrsnLumpedMesh_Postion, MrsnDistribMesh_Position, MeshMapData, ErrStat, ErrMsg ) - - TYPE(HydroDyn_OutputType), INTENT(INOUT) :: y ! Hydrodyn outputs - TYPE(HydroDyn_InputType), INTENT(IN ) :: u ! Hydrodyn inputs - TYPE(MeshType), INTENT(INOUT) :: y_mapped ! This is the mesh which data is mapped onto. We pass it in to avoid allocating it at each call - TYPE(MeshType), INTENT(IN ) :: AllHdroOrigin_position ! This is the mesh which data is mapped onto. We pass it in to avoid allocating it at each call - TYPE(MeshType), INTENT(IN ) :: MrsnLumpedMesh_Postion ! This is the mesh which data is mapped onto. We pass it in to avoid allocating it at each call - TYPE(MeshType), INTENT(IN ) :: MrsnDistribMesh_Position ! This is the mesh which data is mapped onto. We pass it in to avoid allocating it at each call - TYPE(HD_ModuleMapType), INTENT(INOUT) :: MeshMapData ! Map data structures - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - REAL(ReKi) :: CalcLoadsAtWRP(6) +function CalcLoadsAtWRP( y, u, AllHdroOrigin, PRP_Position, MrsnMesh_Position, MeshMapData, ErrStat, ErrMsg ) + + type(HydroDyn_OutputType), intent(inout) :: y ! Hydrodyn outputs + type(HydroDyn_InputType), intent(in ) :: u ! Hydrodyn inputs + type(MeshType), intent(inout) :: AllHdroOrigin ! This is the mesh which data is mapped onto. We pass it in to avoid allocating it at each call + type(MeshType), intent(inout) :: PRP_Position ! These are the kinematics associated the PRP at (0,0,0). We pass it in to avoid allocating it at each call + type(MeshType), intent(in ) :: MrsnMesh_Position ! These are the kinematics associated with the Morison loads mesh. We pass it in to avoid allocating it at each call + type(HD_ModuleMapType), intent(inout) :: MeshMapData ! Mesh mapping data structures + integer(IntKi), intent( out) :: ErrStat ! Error status of the operation + character(*), intent( out) :: ErrMsg ! Error message if ErrStat /= ErrID_None + real(ReKi) :: CalcLoadsAtWRP(6) ! local variables - INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation - CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None + integer(IntKi) :: ErrStat2 ! temporary Error status of the operation + character(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None - y%AllHdroOrigin%Force = 0.0 - y%AllHdroOrigin%Moment= 0.0 + CalcLoadsAtWRP = 0.0_ReKi - IF ( y%Mesh%Committed ) THEN + if ( y%WAMITMesh%Committed ) then ! Just transfer the loads because the meshes are at the same location (0,0,0) - - y%AllHdroOrigin%Force = y%Mesh%Force - y%AllHdroOrigin%Moment = y%Mesh%Moment - - END IF - - IF ( y%Morison%LumpedMesh%Committed ) THEN - - ! This is viscous drag associate with the WAMIT body and/or filled/flooded forces of the WAMIT body - - CALL Transfer_Point_to_Point( y%Morison%LumpedMesh, y_mapped, MeshMapData%M_P_2_WRP_P, ErrStat2, ErrMsg2, MrsnLumpedMesh_Postion, AllHdroOrigin_position ) - CALL CheckError( ErrStat2, ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN + call Transfer_Point_to_Point( y%WAMITMesh, AllHdroOrigin, MeshMapData%W_P_2_PRP_P, ErrStat2, ErrMsg2, u%WAMITMesh, PRP_Position ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'CalcLoadsAtWRP') + if (ErrStat >= AbortErrLev) return - y%AllHdroOrigin%Force = y%AllHdroOrigin%Force + y_mapped%Force - y%AllHdroOrigin%Moment = y%AllHdroOrigin%Moment + y_mapped%Moment + CalcLoadsAtWRP(1:3) = CalcLoadsAtWRP(1:3) + AllHdroOrigin%Force(:,1) + CalcLoadsAtWRP(4:6) = CalcLoadsAtWRP(4:6) + AllHdroOrigin%Moment(:,1) - END IF + end if + - IF ( y%Morison%DistribMesh%Committed ) THEN + if ( y%Morison%Mesh%Committed ) then - CALL Transfer_Line2_to_Point( y%Morison%DistribMesh, y_mapped, MeshMapData%M_L_2_WRP_P, ErrStat2, ErrMsg2, MrsnDistribMesh_Position, AllHdroOrigin_position ) - CALL CheckError( ErrStat2, ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN + call Transfer_Point_to_Point( y%Morison%Mesh, AllHdroOrigin, MeshMapData%M_P_2_PRP_P, ErrStat2, ErrMsg2, u%Morison%Mesh, PRP_Position ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'CalcLoadsAtWRP') + if (ErrStat >= AbortErrLev) return - y%AllHdroOrigin%Force = y%AllHdroOrigin%Force + y_mapped%Force - y%AllHdroOrigin%Moment = y%AllHdroOrigin%Moment + y_mapped%Moment + CalcLoadsAtWRP(1:3) = CalcLoadsAtWRP(1:3) + AllHdroOrigin%Force(:,1) + CalcLoadsAtWRP(4:6) = CalcLoadsAtWRP(4:6) + AllHdroOrigin%Moment(:,1) - END IF + end if - CalcLoadsAtWRP(1:3) = y%AllHdroOrigin%Force(:,1) - CalcLoadsAtWRP(4:6) = y%AllHdroOrigin%Moment(:,1) - -CONTAINS - !............................................................................................................................... - SUBROUTINE CheckError(ErrID,Msg) - ! This subroutine sets the error message and level and cleans up if the error is >= AbortErrLev - !............................................................................................................................... - - ! Passed arguments - INTEGER(IntKi), INTENT(IN) :: ErrID ! The error identifier (ErrStat) - CHARACTER(*), INTENT(IN) :: Msg ! The error message (ErrMsg) - - INTEGER(IntKi) :: ErrStat3 ! The error identifier (ErrStat) - CHARACTER(ErrMsgLen) :: ErrMsg3 ! The error message (ErrMsg) - - !............................................................................................................................ - ! Set error status/message; - !............................................................................................................................ - - IF ( ErrID /= ErrID_None ) THEN - - IF ( LEN_TRIM(ErrMsg) > 0 ) ErrMsg = TRIM(ErrMsg)//NewLine - ErrMsg = TRIM(ErrMsg)//' CalcLoadsAtWRP:'//TRIM(Msg) - ErrStat = MAX(ErrStat, ErrID) - - !......................................................................................................................... - ! Clean up if we're going to return on error: close files, deallocate local arrays - !......................................................................................................................... - END IF - - END SUBROUTINE CheckError -END FUNCTION CalcLoadsAtWRP +end function CalcLoadsAtWRP !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ! ###### The following four routines are Jacobian routines for linearization capabilities ####### @@ -2218,7 +2462,7 @@ SUBROUTINE HD_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrM TYPE(HydroDyn_ContinuousStateType) :: x_m TYPE(HydroDyn_InputType) :: u_perturb REAL(R8Ki) :: delta ! delta change in input or state - INTEGER(IntKi) :: i, j, NN, offsetI, offsetJ + INTEGER(IntKi) :: i, j, k, startingI, startingJ, bOffset, offsetI, offsetJ, n_du_plus1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 @@ -2230,8 +2474,7 @@ SUBROUTINE HD_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrM ErrStat = ErrID_None ErrMsg = '' - ! LIN_TODO: We need to deal with the case where either RdtnMod=0, and/or ExtcnMod=0 and hence %SS_Rdtn data or %SS_Exctn data is not valid - NN = p%WAMIT%SS_Rdtn%N + p%WAMIT%SS_Exctn%N + n_du_plus1 = size(p%Jac_u_indx,1)+1 ! make a copy of the inputs to perturb call HydroDyn_CopyInput( u, u_perturb, MESH_NEWCOPY, ErrStat2, ErrMsg2) @@ -2249,7 +2492,7 @@ SUBROUTINE HD_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrM ! allocate dYdu if necessary if (.not. allocated(dYdu)) then - call AllocAry(dYdu, p%Jac_ny, size(p%Jac_u_indx,1)+1, 'dYdu', ErrStat2, ErrMsg2) + call AllocAry(dYdu, p%Jac_ny, n_du_plus1, 'dYdu', ErrStat2, ErrMsg2) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat>=AbortErrLev) then call cleanup() @@ -2295,7 +2538,7 @@ SUBROUTINE HD_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrM end do ! p%WaveElev0 column - dYdu(:,size(p%Jac_u_indx,1)+1) = 0 + dYdu(:,n_du_plus1) = 0 if (ErrStat>=AbortErrLev) then @@ -2311,11 +2554,16 @@ SUBROUTINE HD_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrM IF ( PRESENT( dXdu ) ) THEN + ! For the case where either RdtnMod=0 and ExtcnMod=0 and hence %SS_Rdtn data or %SS_Exctn data is not valid then we do not have states, so simply return + ! The key here is to never allocate the dXdu and related state Jacobian arrays because then the glue-code will behave properly + + if ( p%totalStates == 0 ) return + ! Calculate the partial derivative of the continuous state functions (X) with respect to the inputs (u) here: ! allocate dXdu if necessary if (.not. allocated(dXdu)) then - call AllocAry(dXdu, NN, size(p%Jac_u_indx,1)+1, 'dXdu', ErrStat2, ErrMsg2) + call AllocAry(dXdu, p%totalStates, n_du_plus1, 'dXdu', ErrStat2, ErrMsg2) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat>=AbortErrLev) then call cleanup() @@ -2326,22 +2574,90 @@ SUBROUTINE HD_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrM offsetI = 0 dXdu = 0.0_R8Ki - - do i = 1,p%WAMIT%SS_Exctn%N - dXdu(offsetI+i,size(p%Jac_u_indx,1)+1) = p%WAMIT%SS_Exctn%B(i) + do j = 1,p%nWAMITObj + do i = 1,p%WAMIT(j)%SS_Exctn%numStates + dXdu(offsetI+i,n_du_plus1) = p%WAMIT(j)%SS_Exctn%B(i) ! B is numStates by 1 + end do + offsetI = offsetI + p%WAMIT(j)%SS_Exctn%numStates end do - - offsetI = NN - p%WAMIT%SS_Rdtn%N - offsetJ = size(p%Jac_u_indx,1)+1 - 13 - do j = 1, 6 - do i = 1,p%WAMIT%SS_Rdtn%N - dXdu(offsetI+i,offsetJ+j) = p%WAMIT%SS_Rdtn%B(i,j) + startingI = p%totalStates - p%totalRdtnStates + startingJ = n_du_plus1 - 1 - 18 - 4*3*p%NBody ! subtract 1 for WaveElev0, then 6*3 for PRPMesh and then 4*3*NBody to place us at the beginning of the velocity inputs + ! B is numStates by 6*NBody where NBody =1 if NBodyMod=2 or 3, but could be >1 for NBodyMod=1 + if ( p%NBodyMod == 1 ) then + ! Example for NBodyMod=1 and NBody = 2, + ! dXdu(:,startingIndx + 1) = p%WAMIT(1)%SS_Rdtn%B(:,1) + ! dXdu(:,startingIndx + 2) = p%WAMIT(1)%SS_Rdtn%B(:,2) + ! dXdu(:,startingIndx + 3) = p%WAMIT(1)%SS_Rdtn%B(:,3) + ! dXdu(:,startingIndx + 4) = p%WAMIT(1)%SS_Rdtn%B(:,7) + ! dXdu(:,startingIndx + 5) = p%WAMIT(1)%SS_Rdtn%B(:,8) + ! dXdu(:,startingIndx + 6) = p%WAMIT(1)%SS_Rdtn%B(:,9) + ! dXdu(:,startingIndx + 7) = p%WAMIT(1)%SS_Rdtn%B(:,4) ! start of rotationalVel + ! dXdu(:,startingIndx + 8) = p%WAMIT(1)%SS_Rdtn%B(:,5) + ! dXdu(:,startingIndx + 9) = p%WAMIT(1)%SS_Rdtn%B(:,6) + ! dXdu(:,startingIndx +10) = p%WAMIT(1)%SS_Rdtn%B(:,10) + ! dXdu(:,startingIndx +11) = p%WAMIT(1)%SS_Rdtn%B(:,11) + ! dXdu(:,startingIndx +12) = p%WAMIT(1)%SS_Rdtn%B(:,12) + + do i = 1,p%WAMIT(1)%SS_Rdtn%numStates + k=0 + ! First set all translationalVel components + do j = 1, p%WAMIT(1)%NBody + bOffset = (j-1)*6 + dXdu(startingI+i,startingJ+k+1) = p%WAMIT(1)%SS_Rdtn%B(i,bOffset+1) + dXdu(startingI+i,startingJ+k+2) = p%WAMIT(1)%SS_Rdtn%B(i,bOffset+2) + dXdu(startingI+i,startingJ+k+3) = p%WAMIT(1)%SS_Rdtn%B(i,bOffset+3) + k = k + 3 + end do + ! Now set all rotationalVel components + do j = 1, p%WAMIT(1)%NBody + bOffset = (j-1)*6 + dXdu(startingI+i,startingJ+k+1) = p%WAMIT(1)%SS_Rdtn%B(i,bOffset+4) + dXdu(startingI+i,startingJ+k+2) = p%WAMIT(1)%SS_Rdtn%B(i,bOffset+5) + dXdu(startingI+i,startingJ+k+3) = p%WAMIT(1)%SS_Rdtn%B(i,bOffset+6) + k = k + 3 + end do + end do + else + ! Example NBodyMod=2or3 and NBody = 2, + ! dXdu(:,startingIndx + 1) = p%WAMIT(1)%SS_Rdtn%B(:,1) + ! dXdu(:,startingIndx + 2) = p%WAMIT(1)%SS_Rdtn%B(:,2) + ! dXdu(:,startingIndx + 3) = p%WAMIT(1)%SS_Rdtn%B(:,3) + ! dXdu(:,startingIndx + 4) = p%WAMIT(2)%SS_Rdtn%B(:,1) + ! dXdu(:,startingIndx + 5) = p%WAMIT(2)%SS_Rdtn%B(:,2) + ! dXdu(:,startingIndx + 6) = p%WAMIT(2)%SS_Rdtn%B(:,3) + ! dXdu(:,startingIndx + 7) = p%WAMIT(1)%SS_Rdtn%B(:,4) ! start of rotationalVel + ! dXdu(:,startingIndx + 8) = p%WAMIT(1)%SS_Rdtn%B(:,5) + ! dXdu(:,startingIndx + 9) = p%WAMIT(1)%SS_Rdtn%B(:,6) + ! dXdu(:,startingIndx +10) = p%WAMIT(2)%SS_Rdtn%B(:,4) + ! dXdu(:,startingIndx +11) = p%WAMIT(2)%SS_Rdtn%B(:,5) + ! dXdu(:,startingIndx +12) = p%WAMIT(2)%SS_Rdtn%B(:,6) + + + k=0 + offsetI=0 + ! First set all translationalVel components + do j = 1, p%nWAMITObj + do i = 1,p%WAMIT(j)%SS_Rdtn%numStates + dXdu(startingI+offsetI+i,startingJ+k+1) = p%WAMIT(j)%SS_Rdtn%B(i,1) + dXdu(startingI+offsetI+i,startingJ+k+2) = p%WAMIT(j)%SS_Rdtn%B(i,2) + dXdu(startingI+offsetI+i,startingJ+k+3) = p%WAMIT(j)%SS_Rdtn%B(i,3) + end do + k = k + 3 + offsetI = offsetI + p%WAMIT(j)%SS_Rdtn%numStates end do - end do - - - + ! Now set all rotationalVel components + offsetI=0 + do j = 1, p%nWAMITObj + do i = 1,p%WAMIT(j)%SS_Rdtn%numStates + dXdu(startingI+offsetI+i,startingJ+k+1) = p%WAMIT(1)%SS_Rdtn%B(i,4) + dXdu(startingI+offsetI+i,startingJ+k+2) = p%WAMIT(1)%SS_Rdtn%B(i,5) + dXdu(startingI+offsetI+i,startingJ+k+3) = p%WAMIT(1)%SS_Rdtn%B(i,6) + end do + k = k + 3 + offsetI = offsetI + p%WAMIT(j)%SS_Rdtn%numStates + end do + end if END IF @@ -2403,7 +2719,7 @@ SUBROUTINE HD_JacobianPContState( t, u, p, x, xd, z, OtherState, y, m, ErrStat, TYPE(HydroDyn_ContinuousStateType) :: x_m TYPE(HydroDyn_ContinuousStateType) :: x_perturb REAL(R8Ki) :: delta ! delta change in input or state - INTEGER(IntKi) :: i, j, NN + INTEGER(IntKi) :: i, j, k, sOffset INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 @@ -2415,9 +2731,10 @@ SUBROUTINE HD_JacobianPContState( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrStat = ErrID_None ErrMsg = '' + if ( p%totalStates == 0 ) return ! Calculate the partial derivative of the output functions (Y) with respect to the continuous states (x) here: - NN = p%WAMIT%SS_Exctn%N+p%WAMIT%SS_Rdtn%N + ! make a copy of the continuous states to perturb call HydroDyn_CopyContState( x, x_perturb, MESH_NEWCOPY, ErrStat2, ErrMsg2) @@ -2432,7 +2749,7 @@ SUBROUTINE HD_JacobianPContState( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ! allocate dYdx if necessary if (.not. allocated(dYdx)) then - call AllocAry(dYdx, p%Jac_ny, NN, 'dYdx', ErrStat2, ErrMsg2) + call AllocAry(dYdx, p%Jac_ny, p%totalStates, 'dYdx', ErrStat2, ErrMsg2) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat>=AbortErrLev) then call cleanup() @@ -2451,7 +2768,7 @@ SUBROUTINE HD_JacobianPContState( t, u, p, x, xd, z, OtherState, y, m, ErrStat, end if - do i=1,NN + do i=1,p%totalStates ! get x_op + delta x call HydroDyn_CopyContState( x, x_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ) @@ -2493,7 +2810,7 @@ SUBROUTINE HD_JacobianPContState( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ! allocate dXdu if necessary if (.not. allocated(dXdx)) then - call AllocAry(dXdx, NN, NN, 'dXdx', ErrStat2, ErrMsg2) + call AllocAry(dXdx, p%totalStates, p%totalStates, 'dXdx', ErrStat2, ErrMsg2) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat>=AbortErrLev) then call cleanup() @@ -2503,18 +2820,26 @@ SUBROUTINE HD_JacobianPContState( t, u, p, x, xd, z, OtherState, y, m, ErrStat, dXdx = 0.0_R8Ki ! Analytical Jacobians from State-space models - if ( p%WAMIT%SS_Exctn%N > 0 ) then - do j=1,p%WAMIT%SS_Exctn%N - do i=1,p%WAMIT%SS_Exctn%N ! Loop through all active (enabled) DOFs - dXdx(i, j) = p%WAMIT%SS_Exctn%A(i,j) + if ( p%totalExctnStates > 0 ) then + sOffset = 0 + do k=1,p%nWAMITObj + do j=1,p%WAMIT(k)%SS_Exctn%numStates + do i=1,p%WAMIT(k)%SS_Exctn%numStates ! Loop through all active (enabled) DOFs + dXdx(i+sOffset, j+sOffset) = p%WAMIT(k)%SS_Exctn%A(i,j) + end do end do + sOffset = sOffset + p%WAMIT(k)%SS_Exctn%numStates end do end if - if ( p%WAMIT%SS_Rdtn%N > 0 ) then - do j=1,p%WAMIT%SS_Rdtn%N - do i=1,p%WAMIT%SS_Rdtn%N ! Loop through all active (enabled) DOFs - dXdx(i+p%WAMIT%SS_Exctn%N, j+p%WAMIT%SS_Exctn%N) = p%WAMIT%SS_Rdtn%A(i,j) + if ( p%totalRdtnStates > 0 ) then + sOffset = 0 + do k=1,p%nWAMITObj + do j=1,p%WAMIT(k)%SS_Rdtn%numStates + do i=1,p%WAMIT(k)%SS_Rdtn%numStates ! Loop through all active (enabled) DOFs + dXdx(i+p%totalExctnStates+sOffset, j+p%totalExctnStates+sOffset) = p%WAMIT(k)%SS_Rdtn%A(i,j) + end do end do + sOffset = sOffset + p%WAMIT(k)%SS_Rdtn%numStates end do end if @@ -2712,13 +3037,13 @@ SUBROUTINE HD_Init_Jacobian_y( p, y, InitOut, ErrStat, ErrMsg) ! determine how many outputs there are in the Jacobians p%Jac_ny = 0 - if ( y%Morison%DistribMesh%Committed ) then - p%Jac_ny = p%Jac_ny + y%Morison%DistribMesh%NNodes * 6 ! 3 Force, Moment, at each node on the distributed loads mesh - p%Jac_ny = p%Jac_ny + y%Morison%LumpedMesh%NNodes * 6 ! 3 Force, Moment, at each node on the lumped loads mesh + if ( y%Morison%Mesh%Committed ) then + p%Jac_ny = p%Jac_ny + y%Morison%Mesh%NNodes * 6 ! 3 Force, Moment, at each node on the morison mesh end if - - p%Jac_ny = p%Jac_ny + y%Mesh%NNodes * 6 ! 3 Force, Moment, at the WAMIT reference Point - p%Jac_ny = p%Jac_ny + y%AllHdroOrigin%NNodes * 6 ! 3 Force, Moment, of all HD loads integrated to the origin (0,0,0) + if ( y%WAMITMesh%Committed ) then + p%Jac_ny = p%Jac_ny + y%WAMITMesh%NNodes * 6 ! 3 Force, Moment, at the WAMIT reference Point(s) + end if + p%Jac_ny = p%Jac_ny + p%NumTotalOuts ! WriteOutput values @@ -2726,7 +3051,8 @@ SUBROUTINE HD_Init_Jacobian_y( p, y, InitOut, ErrStat, ErrMsg) ! set linearization output names: !................. CALL AllocAry(InitOut%LinNames_y, p%Jac_ny, 'LinNames_y', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - ! LIN-TODO: Do we need RotFrame_y for this module? + ! We do not need RotFrame_y for this module and the glue code with handle the fact that we did not allocate the array and hence set all values to false at the glue-code level + ! Same with RotFrame_x !CALL AllocAry(InitOut%RotFrame_y, p%Jac_ny, 'RotFrame_y', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return @@ -2734,19 +3060,15 @@ SUBROUTINE HD_Init_Jacobian_y( p, y, InitOut, ErrStat, ErrMsg) index_next = 1 - if ( y%Morison%DistribMesh%Committed ) then - index_last = index_next - call PackLoadMesh_Names(y%Morison%DistribMesh, 'DistribLoads', InitOut%LinNames_y, index_next) + if ( y%Morison%Mesh%Committed ) then index_last = index_next - call PackLoadMesh_Names(y%Morison%LumpedMesh, 'LumpedLoads', InitOut%LinNames_y, index_next) + call PackLoadMesh_Names(y%Morison%Mesh, 'MorisonLoads', InitOut%LinNames_y, index_next) end if - - index_last = index_next - call PackLoadMesh_Names(y%Mesh, 'PlatformRefPtLoads', InitOut%LinNames_y, index_next) - - index_last = index_next - call PackLoadMesh_Names(y%AllHdroOrigin, 'AllHdroOrigin', InitOut%LinNames_y, index_next) + if ( y%WAMITMesh%Committed ) then + index_last = index_next + call PackLoadMesh_Names(y%WAMITMesh, 'WAMITLoads', InitOut%LinNames_y, index_next) + end if index_last = index_next @@ -2773,54 +3095,76 @@ SUBROUTINE HD_Init_Jacobian_x( p, InitOut, ErrStat, ErrMsg) CHARACTER(*), PARAMETER :: RoutineName = 'HD_Init_Jacobian_x' ! local variables: - INTEGER(IntKi) :: i, j, k, NN, spdof, indx + INTEGER(IntKi) :: i, j, k, l, spdof, indx CHARACTER(10) :: modLabels(2), dofLabels(6) ErrStat = ErrID_None ErrMsg = "" indx = 1 - NN = p%WAMIT%SS_Rdtn%N + p%WAMIT%SS_Exctn%N - if ( NN == 0 ) return + + ! Need to determine how many wamit body objects there are + p%totalExctnStates = 0 + p%totalRdtnStates = 0 + do j = 1, p%nWAMITObj + p%totalExctnStates = p%totalExctnStates + p%WAMIT(j)%SS_Exctn%numStates !numStates defaults to zero in the case where ExctnMod = 0 instead of 2 + p%totalRdtnStates = p%totalRdtnStates + p%WAMIT(j)%SS_Rdtn%numStates !numStates defaults to zero in the case where RdtnMod = 0 instead of 2 + end do + p%totalStates = p%totalExctnStates + p%totalRdtnStates + + if ( p%totalStates == 0 ) return ! No states, so return and do not allocate the following arrays. This lets the glue-code know that the module does not have states + ! allocate space for the row/column names and for perturbation sizes - call allocAry(p%dx, NN, 'p%dx', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - call AllocAry(InitOut%LinNames_x, NN, 'LinNames_x', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - CALL AllocAry(InitOut%DerivOrder_x, NN, 'DerivOrder_x', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call allocAry(p%dx, p%totalStates, 'p%dx', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(InitOut%LinNames_x, p%totalStates, 'LinNames_x' , ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry(InitOut%DerivOrder_x, p%totalStates, 'DerivOrder_x', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return ! All Hydrodyn continuous states are max order = 1 if ( allocated(InitOut%DerivOrder_x) ) InitOut%DerivOrder_x = 1 ! set perturbation sizes: p%dx - - do i = 1, p%WAMIT%SS_Exctn%N - p%dx(i) = 20000.0_R8Ki * D2R_D + k = 1 + do j = 1, p%nWAMITObj + do i = 1, p%WAMIT(j)%SS_Exctn%numStates + p%dx(k) = 20000.0_R8Ki * D2R_D + k=k+1 + end do end do - - do i = 1, p%WAMIT%SS_Rdtn%N - p%dx(i+p%WAMIT%SS_Exctn%N) = 2.0_R8Ki * D2R_D + do j = 1, p%nWAMITObj + do i = 1, p%WAMIT(j)%SS_Rdtn%numStates + p%dx(k) = 2.0_R8Ki * D2R_D + k=k+1 + end do end do modLabels = (/'Exctn ','Rdtn '/) dofLabels = (/'PtfmSg ','PtfmSw ','PtfmHv ','PtfmR ','PtfmP ','PtfmY '/) - - ! set linearization state names: do k = 1, 2 ! 1 = Excitation, 2 = Radiation - - - do j = 1, 6 - - if (k == 1) then - spdof = p%WAMIT%SS_Exctn%spdof(j) - else - spdof = p%WAMIT%SS_Rdtn%spdof(j) - end if - - do i = 1,spdof - InitOut%LinNames_x(indx) = trim(modLabels(k))//trim(dofLabels(j))//trim(num2lstr(i)) - indx = indx + 1 + do l=1,p%nWAMITObj + + ! set linearization state names: + do j = 1, 6 + + if (k == 1) then + spdof = p%WAMIT(l)%SS_Exctn%spdof(j) + else + spdof = p%WAMIT(l)%SS_Rdtn%spdof(j) + end if + + if ( p%NBodyMod == 1 ) then + do i = 1,spdof + InitOut%LinNames_x(indx) = trim(modLabels(k))//trim(dofLabels(j))//trim(num2lstr(i)) + indx = indx + 1 + end do + else + do i = 1,spdof + InitOut%LinNames_x(indx) = 'B'//trim(num2lstr(l))//trim(modLabels(k))//trim(dofLabels(j))//trim(num2lstr(i)) + indx = indx + 1 + end do + end if + end do end do end do - END SUBROUTINE HD_Init_Jacobian_x !---------------------------------------------------------------------------------------------------------------------------------- !> This routine initializes the array that maps rows/columns of the Jacobian to specific mesh fields. @@ -2860,12 +3204,14 @@ SUBROUTINE HD_Init_Jacobian( p, u, y, InitOut, ErrStat, ErrMsg) ! determine how many inputs there are in the Jacobians nu = 0; - if ( u%Morison%DistribMesh%Committed ) then - nu = nu + u%Morison%DistribMesh%NNodes * 18 ! 3 TranslationDisp, Orientation, TranslationVel, RotationVel, TranslationAcc, and RotationAcc at each node - nu = nu + u%Morison%LumpedMesh%NNodes * 18 ! 3 TranslationDisp, Orientation, TranslationVel, RotationVel, TranslationAcc, and RotationAcc at each node + if ( u%Morison%Mesh%Committed ) then + nu = u%Morison%Mesh%NNodes * 18 ! 3 TranslationDisp, Orientation, TranslationVel, RotationVel, TranslationAcc, and RotationAcc at each node + end if + if ( u%WAMITMesh%Committed ) then + nu = nu + u%WAMITMesh%NNodes * 18 ! 3 TranslationDisp, Orientation, TranslationVel, RotationVel, TranslationAcc, and RotationAcc at each node end if - nu = nu + u%Mesh%NNodes * 18 ! 3 TranslationDisp, Orientation, TranslationVel, RotationVel, TranslationAcc, and RotationAcc at each node + nu = nu + u%PRPMesh%NNodes * 18 ! 3 TranslationDisp, Orientation, TranslationVel, RotationVel, TranslationAcc, and RotationAcc at each node ! DO NOT Add the extended input WaveElev0 when computing the size of p%Jac_u_indx @@ -2889,56 +3235,39 @@ SUBROUTINE HD_Init_Jacobian( p, u, y, InitOut, ErrStat, ErrMsg) index = 1 meshFieldCount = 0 - if ( u%Morison%DistribMesh%Committed ) then - !Module/Mesh/Field: u%Morison%DistribMesh%TranslationDisp = 1; - !Module/Mesh/Field: u%Morison%DistribMesh%Orientation = 2; - !Module/Mesh/Field: u%Morison%DistribMesh%TranslationVel = 3; - !Module/Mesh/Field: u%Morison%DistribMesh%RotationVel = 4; - !Module/Mesh/Field: u%Morison%DistribMesh%TranslationAcc = 5; - !Module/Mesh/Field: u%Morison%DistribMesh%RotationAcc = 6; - - do i_meshField = 1,6 - do i=1,u%Morison%DistribMesh%NNodes - do j=1,3 - p%Jac_u_indx(index,1) = i_meshField !Module/Mesh/Field: u%Morison%DistribMesh%{TranslationDisp/Orientation/TranslationVel/RotationVel/TranslationAcc/RotationAcc} = m - p%Jac_u_indx(index,2) = j !index: j - p%Jac_u_indx(index,3) = i !Node: i - index = index + 1 - end do !j - end do !i + + if ( u%Morison%Mesh%Committed ) then + !Module/Mesh/Field: u%Morison%Mesh%TranslationDisp = 1; + !Module/Mesh/Field: u%Morison%Mesh%Orientation = 2; + !Module/Mesh/Field: u%Morison%Mesh%TranslationVel = 3; + !Module/Mesh/Field: u%Morison%Mesh%RotationVel = 4; + !Module/Mesh/Field: u%Morison%Mesh%TranslationAcc = 5; + !Module/Mesh/Field: u%Morison%Mesh%RotationAcc = 6; + + do i_meshField = 1,6 + do i=1,u%Morison%Mesh%NNodes + do j=1,3 + p%Jac_u_indx(index,1) = i_meshField !Module/Mesh/Field: u%Morison%Mesh%{TranslationDisp/Orientation/TranslationVel/RotationVel/TranslationAcc/RotationAcc} = m + p%Jac_u_indx(index,2) = j !index: j + p%Jac_u_indx(index,3) = i !Node: i + index = index + 1 + end do !j + end do !i - end do !i_meshField - meshFieldCount = 6 - !Module/Mesh/Field: u%Morison%LumpedMesh%TranslationDisp = 7; - !Module/Mesh/Field: u%Morison%LumpedMesh%Orientation = 8; - !Module/Mesh/Field: u%Morison%LumpedMesh%TranslationVel = 9; - !Module/Mesh/Field: u%Morison%LumpedMesh%RotationVel = 10; - !Module/Mesh/Field: u%Morison%LumpedMesh%TranslationAcc = 11; - !Module/Mesh/Field: u%Morison%LumpedMesh%RotationAcc = 12; - - do i_meshField = 1,6 - do i=1,u%Morison%LumpedMesh%NNodes - do j=1,3 - p%Jac_u_indx(index,1) = meshFieldCount + i_meshField !if this mesh is allocated, then the previous DistribMesh would have been allocated - p%Jac_u_indx(index,2) = j !index: j - p%Jac_u_indx(index,3) = i !Node: i - index = index + 1 - end do !j - end do !i - - end do !i_meshField - meshFieldCount = meshFieldCount + 6 + end do !i_meshField + meshFieldCount = 6 + end if - !Module/Mesh/Field: u%Mesh%TranslationDisp = 13 or 1; - !Module/Mesh/Field: u%Mesh%Orientation = 14 or 2; - !Module/Mesh/Field: u%Mesh%TranslationVel = 15 or 3; - !Module/Mesh/Field: u%Mesh%RotationVel = 16 or 4; - !Module/Mesh/Field: u%Mesh%TranslationAcc = 17 or 5; - !Module/Mesh/Field: u%Mesh%RotationAcc = 18 or 6; - + if ( u%WAMITMesh%Committed ) then + !Module/Mesh/Field: u%WAMITMesh%TranslationDisp = 7 or 1; + !Module/Mesh/Field: u%WAMITMesh%Orientation = 8 or 2; + !Module/Mesh/Field: u%WAMITMesh%TranslationVel = 9 or 3; + !Module/Mesh/Field: u%WAMITMesh%RotationVel = 10 or 4; + !Module/Mesh/Field: u%WAMITMesh%TranslationAcc = 11 or 5; + !Module/Mesh/Field: u%WAMITMesh%RotationAcc = 12 or 6; do i_meshField = 1,6 - do i=1,u%Mesh%NNodes + do i=1,u%WAMITMesh%NNodes do j=1,3 p%Jac_u_indx(index,1) = meshFieldCount + i_meshField p%Jac_u_indx(index,2) = j !index: j @@ -2946,69 +3275,82 @@ SUBROUTINE HD_Init_Jacobian( p, u, y, InitOut, ErrStat, ErrMsg) index = index + 1 end do !j end do !i - end do !i_meshField - + end do !i_meshField + meshFieldCount = meshFieldCount + 6 + end if + + !Module/Mesh/Field: u%PRPMesh%TranslationDisp = 13 or 7 or 1; + !Module/Mesh/Field: u%PRPMesh%Orientation = 14 or 8 or 2; + !Module/Mesh/Field: u%PRPMesh%TranslationVel = 15 or 9 or 3; + !Module/Mesh/Field: u%PRPMesh%RotationVel = 16 or 10 or 4; + !Module/Mesh/Field: u%PRPMesh%TranslationAcc = 17 or 11 or 5; + !Module/Mesh/Field: u%PRPMesh%RotationAcc = 18 or 12 or 6; + do i_meshField = 1,6 + do i=1,u%PRPMesh%NNodes + do j=1,3 + p%Jac_u_indx(index,1) = meshFieldCount + i_meshField + p%Jac_u_indx(index,2) = j !index: j + p%Jac_u_indx(index,3) = i !Node: i + index = index + 1 + end do !j + end do !i + end do !i_meshField + meshFieldCount = meshFieldCount + 6 !................ ! input perturbations, du: !................ - if ( u%Morison%DistribMesh%Committed ) then - call AllocAry(p%du, 18, 'p%du', ErrStat2, ErrMsg2) ! number of unique values in p%Jac_u_indx(:,1) - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - if (ErrStat >= AbortErrLev) return - else - call AllocAry(p%du, 6, 'p%du', ErrStat2, ErrMsg2) ! number of unique values in p%Jac_u_indx(:,1) - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - if (ErrStat >= AbortErrLev) return - - end if - perturb_t = 0.02_ReKi*D2R * max(p%WtrDpth,1.0_ReKi) ! translation input scaling ! LIN-TODO What about MSL offset? + call AllocAry(p%du, meshFieldCount, 'p%du', ErrStat2, ErrMsg2) ! number of unique values in p%Jac_u_indx(:,1) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + + perturb_t = 0.02_ReKi*D2R * max(p%WtrDpth,1.0_ReKi) ! translation input scaling perturb = 2*D2R ! rotational input scaling index = 0 - if ( u%Morison%DistribMesh%Committed ) then - p%du(1) = perturb_t ! u%Morison%DistribMesh%TranslationDisp - p%du(2) = perturb ! u%Morison%DistribMesh%Orientation - p%du(3) = perturb_t ! u%Morison%DistribMesh%TranslationVel - p%du(4) = perturb ! u%Morison%DistribMesh%RotationVel - p%du(5) = perturb_t ! u%Morison%DistribMesh%TranslationAcc - p%du(6) = perturb ! u%Morison%DistribMesh%RotationAcc + if ( u%Morison%Mesh%Committed ) then + p%du(1) = perturb_t ! u%Morison%Mesh%TranslationDisp + p%du(2) = perturb ! u%Morison%Mesh%Orientation + p%du(3) = perturb_t ! u%Morison%Mesh%TranslationVel + p%du(4) = perturb ! u%Morison%Mesh%RotationVel + p%du(5) = perturb_t ! u%Morison%Mesh%TranslationAcc + p%du(6) = perturb ! u%Morison%Mesh%RotationAcc index = 6 - p%du(index + 1) = perturb_t ! u%Morison%LumpedMesh%TranslationDisp - p%du(index + 2) = perturb ! u%Morison%LumpedMesh%Orientation - p%du(index + 3) = perturb_t ! u%Morison%LumpedMesh%TranslationVel - p%du(index + 4) = perturb ! u%Morison%LumpedMesh%RotationVel - p%du(index + 5) = perturb_t ! u%Morison%LumpedMesh%TranslationAcc - p%du(index + 6) = perturb ! u%Morison%LumpedMesh%RotationAcc - index = index + 6 end if - - p%du(index + 1) = perturb_t ! u%Mesh%TranslationDisp - p%du(index + 2) = perturb ! u%Mesh%Orientation - p%du(index + 3) = perturb_t ! u%Mesh%TranslationVel - p%du(index + 4) = perturb ! u%Mesh%RotationVel - p%du(index + 5) = perturb_t ! u%Mesh%TranslationAcc - p%du(index + 6) = perturb ! u%Mesh%RotationAcc - index = index + 6 - + if ( u%WAMITMesh%Committed ) then + p%du(index + 1) = perturb_t ! u%WAMITMesh%TranslationDisp + p%du(index + 2) = perturb ! u%WAMITMesh%Orientation + p%du(index + 3) = perturb_t ! u%WAMITMesh%TranslationVel + p%du(index + 4) = perturb ! u%WAMITMesh%RotationVel + p%du(index + 5) = perturb_t ! u%WAMITMesh%TranslationAcc + p%du(index + 6) = perturb ! u%WAMITMesh%RotationAcc + index = index + 6 + end if + p%du(index + 1) = perturb_t ! u%PRPMesh%TranslationDisp + p%du(index + 2) = perturb ! u%PRPMesh%Orientation + p%du(index + 3) = perturb_t ! u%PRPMesh%TranslationVel + p%du(index + 4) = perturb ! u%PRPMesh%RotationVel + p%du(index + 5) = perturb_t ! u%PRPMesh%TranslationAcc + p%du(index + 6) = perturb ! u%PRPMesh%RotationAcc !................ ! names of the columns, InitOut%LinNames_u: !................ call AllocAry(InitOut%LinNames_u, nu+1, 'LinNames_u', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - !LIN-TODO: We do not need any RotFrame info, right? + ! We do not need RotFrame_u for this module and the glue code with handle the fact that we did not allocate the array and hence set all values to false at the glue-code level !call AllocAry(InitOut%RotFrame_u, nu+1, 'RotFrame_u', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - ! LIN-TODO: have we implemented IsLoad_u ? + call AllocAry(InitOut%IsLoad_u, nu+1, 'IsLoad_u', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return InitOut%IsLoad_u = .false. ! HD's inputs are NOT loads index = 1 - if ( u%Morison%DistribMesh%Committed ) then + if ( u%Morison%Mesh%Committed ) then FieldMask = .false. FieldMask(MASKID_TRANSLATIONDISP) = .true. FieldMask(MASKID_Orientation) = .true. @@ -3016,8 +3358,11 @@ SUBROUTINE HD_Init_Jacobian( p, u, y, InitOut, ErrStat, ErrMsg) FieldMask(MASKID_ROTATIONVEL) = .true. FieldMask(MASKID_TRANSLATIONACC) = .true. FieldMask(MASKID_ROTATIONACC) = .true. - call PackMotionMesh_Names(u%Morison%DistribMesh, 'Morison-Distrib', InitOut%LinNames_u, index, FieldMask=FieldMask) + call PackMotionMesh_Names(u%Morison%Mesh, 'Morison', InitOut%LinNames_u, index, FieldMask=FieldMask) + end if + + if ( u%WAMITMesh%Committed ) then FieldMask = .false. FieldMask(MASKID_TRANSLATIONDISP) = .true. FieldMask(MASKID_Orientation) = .true. @@ -3025,9 +3370,9 @@ SUBROUTINE HD_Init_Jacobian( p, u, y, InitOut, ErrStat, ErrMsg) FieldMask(MASKID_ROTATIONVel) = .true. FieldMask(MASKID_TRANSLATIONACC) = .true. FieldMask(MASKID_ROTATIONACC) = .true. - call PackMotionMesh_Names(u%Morison%LumpedMesh, 'Morison-Lumped', InitOut%LinNames_u, index, FieldMask=FieldMask) + call PackMotionMesh_Names(u%WAMITMesh, 'WAMIT', InitOut%LinNames_u, index, FieldMask=FieldMask) end if - + FieldMask = .false. FieldMask(MASKID_TRANSLATIONDISP) = .true. FieldMask(MASKID_Orientation) = .true. @@ -3035,8 +3380,8 @@ SUBROUTINE HD_Init_Jacobian( p, u, y, InitOut, ErrStat, ErrMsg) FieldMask(MASKID_ROTATIONVel) = .true. FieldMask(MASKID_TRANSLATIONACC) = .true. FieldMask(MASKID_ROTATIONACC) = .true. - call PackMotionMesh_Names(u%Mesh, 'Platform-RefPt', InitOut%LinNames_u, index, FieldMask=FieldMask) - + call PackMotionMesh_Names(u%PRPMesh, 'Platform-RefPt', InitOut%LinNames_u, index, FieldMask=FieldMask) + InitOut%LinNames_u(index) = 'Extended input: wave elevation at platform ref point, m' END SUBROUTINE HD_Init_Jacobian @@ -3054,9 +3399,9 @@ SUBROUTINE HD_Perturb_u( p, n, perturb_sign, u, du ) ! local variables integer :: fieldIndx - integer :: node + integer :: node, index - + index = 0 fieldIndx = p%Jac_u_indx(n,2) node = p%Jac_u_indx(n,3) @@ -3065,68 +3410,111 @@ SUBROUTINE HD_Perturb_u( p, n, perturb_sign, u, du ) ! determine which mesh we're trying to perturb and perturb the input: ! If we do not have Morison meshes, then the following select cases will vary - if ( u%Morison%DistribMesh%Committed ) then - + if ( u%Morison%Mesh%Committed ) then SELECT CASE( p%Jac_u_indx(n,1) ) - CASE ( 1) !Module/Mesh/Field: u%Morison%DistribMesh%TranslationDisp = 1 - u%Morison%DistribMesh%TranslationDisp (fieldIndx,node) = u%Morison%DistribMesh%TranslationDisp (fieldIndx,node) + du * perturb_sign - CASE ( 2) !Module/Mesh/Field: u%Morison%DistribMesh%Orientation = 2 - CALL PerturbOrientationMatrix( u%Morison%DistribMesh%Orientation(:,:,node), du * perturb_sign, fieldIndx ) - CASE ( 3) !Module/Mesh/Field: u%Morison%DistribMesh%TranslationVel = 3 - u%Morison%DistribMesh%TranslationVel( fieldIndx,node) = u%Morison%DistribMesh%TranslationVel( fieldIndx,node) + du * perturb_sign - CASE ( 4) !Module/Mesh/Field: u%Morison%DistribMesh%RotationVel = 4 - u%Morison%DistribMesh%RotationVel (fieldIndx,node) = u%Morison%DistribMesh%RotationVel (fieldIndx,node) + du * perturb_sign - CASE ( 5) !Module/Mesh/Field: u%Morison%DistribMesh%TranslationAcc = 5 - u%Morison%DistribMesh%TranslationAcc( fieldIndx,node) = u%Morison%DistribMesh%TranslationAcc( fieldIndx,node) + du * perturb_sign - CASE ( 6) !Module/Mesh/Field: u%Morison%DistribMesh%RotationAcc = 6 - u%Morison%DistribMesh%RotationAcc(fieldIndx,node) = u%Morison%DistribMesh%RotationAcc(fieldIndx,node) + du * perturb_sign - - CASE ( 7) !Module/Mesh/Field: u%Morison%LumpedMesh%TranslationDisp = 7 - u%Morison%LumpedMesh%TranslationDisp (fieldIndx,node) = u%Morison%LumpedMesh%TranslationDisp (fieldIndx,node) + du * perturb_sign - CASE ( 8) !Module/Mesh/Field: u%Morison%LumpedMesh%Orientation = 8 - CALL PerturbOrientationMatrix( u%Morison%LumpedMesh%Orientation(:,:,node), du * perturb_sign, fieldIndx ) - CASE ( 9) !Module/Mesh/Field: u%Morison%LumpedMesh%TranslationVel = 9 - u%Morison%LumpedMesh%TranslationVel( fieldIndx,node) = u%Morison%LumpedMesh%TranslationVel( fieldIndx,node) + du * perturb_sign - CASE (10) !Module/Mesh/Field: u%Morison%LumpedMesh%RotationVel = 10 - u%Morison%LumpedMesh%RotationVel (fieldIndx,node) = u%Morison%LumpedMesh%RotationVel (fieldIndx,node) + du * perturb_sign - CASE (11) !Module/Mesh/Field: u%Morison%LumpedMesh%TranslationAcc = 11 - u%Morison%LumpedMesh%TranslationAcc( fieldIndx,node) = u%Morison%LumpedMesh%TranslationAcc( fieldIndx,node) + du * perturb_sign - CASE (12) !Module/Mesh/Field: u%Morison%LumpedMesh%RotationAcc = 12 - u%Morison%LumpedMesh%RotationAcc(fieldIndx,node) = u%Morison%LumpedMesh%RotationAcc(fieldIndx,node) + du * perturb_sign - - CASE (13) !Module/Mesh/Field: u%Mesh%TranslationDisp = 13 - u%Mesh%TranslationDisp (fieldIndx,node) = u%Mesh%TranslationDisp (fieldIndx,node) + du * perturb_sign - CASE (14) !Module/Mesh/Field: u%Mesh%Orientation = 14 - CALL PerturbOrientationMatrix( u%Mesh%Orientation(:,:,node), du * perturb_sign, fieldIndx ) - CASE (15) !Module/Mesh/Field: u%Mesh%TranslationVel = 15 - u%Mesh%TranslationVel( fieldIndx,node) = u%Mesh%TranslationVel( fieldIndx,node) + du * perturb_sign - CASE (16) !Module/Mesh/Field: u%Mesh%RotationVel = 16 - u%Mesh%RotationVel (fieldIndx,node) = u%Mesh%RotationVel (fieldIndx,node) + du * perturb_sign - CASE (17) !Module/Mesh/Field: u%Mesh%TranslationAcc = 17 - u%Mesh%TranslationAcc( fieldIndx,node) = u%Mesh%TranslationAcc( fieldIndx,node) + du * perturb_sign - CASE (18) !Module/Mesh/Field: u%Mesh%RotationAcc = 18 - u%Mesh%RotationAcc(fieldIndx,node) = u%Mesh%RotationAcc(fieldIndx,node) + du * perturb_sign - - + CASE ( 1) !Module/Mesh/Field: u%Morison%Mesh%TranslationDisp = 1 + u%Morison%Mesh%TranslationDisp (fieldIndx,node) = u%Morison%Mesh%TranslationDisp (fieldIndx,node) + du * perturb_sign + CASE ( 2) !Module/Mesh/Field: u%Morison%Mesh%Orientation = 2 + CALL PerturbOrientationMatrix( u%Morison%Mesh%Orientation(:,:,node), du * perturb_sign, fieldIndx ) + CASE ( 3) !Module/Mesh/Field: u%Morison%Mesh%TranslationVel = 3 + u%Morison%Mesh%TranslationVel( fieldIndx,node) = u%Morison%Mesh%TranslationVel( fieldIndx,node) + du * perturb_sign + CASE ( 4) !Module/Mesh/Field: u%Morison%Mesh%RotationVel = 4 + u%Morison%Mesh%RotationVel (fieldIndx,node) = u%Morison%Mesh%RotationVel (fieldIndx,node) + du * perturb_sign + CASE ( 5) !Module/Mesh/Field: u%Morison%Mesh%TranslationAcc = 5 + u%Morison%Mesh%TranslationAcc( fieldIndx,node) = u%Morison%Mesh%TranslationAcc( fieldIndx,node) + du * perturb_sign + CASE ( 6) !Module/Mesh/Field: u%Morison%Mesh%RotationAcc = 6 + u%Morison%Mesh%RotationAcc(fieldIndx,node) = u%Morison%Mesh%RotationAcc(fieldIndx,node) + du * perturb_sign + end select + if ( u%WAMITMesh%Committed ) then + SELECT CASE( p%Jac_u_indx(n,1) ) + CASE ( 7) !Module/Mesh/Field: u%WAMITMesh%TranslationDisp = 7 + u%WAMITMesh%TranslationDisp (fieldIndx,node) = u%WAMITMesh%TranslationDisp (fieldIndx,node) + du * perturb_sign + CASE ( 8) !Module/Mesh/Field: u%WAMITMesh%Orientation = 8 + CALL PerturbOrientationMatrix( u%WAMITMesh%Orientation(:,:,node), du * perturb_sign, fieldIndx ) + CASE ( 9) !Module/Mesh/Field: u%WAMITMesh%TranslationVel = 9 + u%WAMITMesh%TranslationVel( fieldIndx,node) = u%WAMITMesh%TranslationVel( fieldIndx,node) + du * perturb_sign + CASE (10) !Module/Mesh/Field: u%WAMITMesh%RotationVel = 10 + u%WAMITMesh%RotationVel (fieldIndx,node) = u%WAMITMesh%RotationVel (fieldIndx,node) + du * perturb_sign + CASE (11) !Module/Mesh/Field: u%WAMITMesh%TranslationAcc = 11 + u%WAMITMesh%TranslationAcc( fieldIndx,node) = u%WAMITMesh%TranslationAcc( fieldIndx,node) + du * perturb_sign + CASE (12) !Module/Mesh/Field: u%WAMITMesh%RotationAcc = 12 + u%WAMITMesh%RotationAcc(fieldIndx,node) = u%WAMITMesh%RotationAcc(fieldIndx,node) + du * perturb_sign END SELECT - else + SELECT CASE( p%Jac_u_indx(n,1) ) + CASE (13) !Module/Mesh/Field: u%PRPMesh%TranslationDisp = 13 + u%PRPMesh%TranslationDisp (fieldIndx,node) = u%PRPMesh%TranslationDisp (fieldIndx,node) + du * perturb_sign + CASE (14) !Module/Mesh/Field: u%PRPMesh%Orientation = 14 + CALL PerturbOrientationMatrix( u%PRPMesh%Orientation(:,:,node), du * perturb_sign, fieldIndx ) + CASE (15) !Module/Mesh/Field: u%PRPMesh%TranslationVel = 15 + u%PRPMesh%TranslationVel( fieldIndx,node) = u%PRPMesh%TranslationVel( fieldIndx,node) + du * perturb_sign + CASE (16) !Module/Mesh/Field: u%PRPMesh%RotationVel = 16 + u%PRPMesh%RotationVel (fieldIndx,node) = u%PRPMesh%RotationVel (fieldIndx,node) + du * perturb_sign + CASE (17) !Module/Mesh/Field: u%PRPMesh%TranslationAcc = 17 + u%PRPMesh%TranslationAcc( fieldIndx,node) = u%PRPMesh%TranslationAcc( fieldIndx,node) + du * perturb_sign + CASE (18) !Module/Mesh/Field: u%PRPMesh%RotationAcc = 18 + u%PRPMesh%RotationAcc(fieldIndx,node) = u%PRPMesh%RotationAcc(fieldIndx,node) + du * perturb_sign + END SELECT + else + SELECT CASE( p%Jac_u_indx(n,1) ) + CASE ( 7) !Module/Mesh/Field: u%PRPMesh%TranslationDisp = 7 + u%PRPMesh%TranslationDisp (fieldIndx,node) = u%PRPMesh%TranslationDisp (fieldIndx,node) + du * perturb_sign + CASE ( 8) !Module/Mesh/Field: u%PRPMesh%Orientation = 8 + CALL PerturbOrientationMatrix( u%PRPMesh%Orientation(:,:,node), du * perturb_sign, fieldIndx ) + CASE ( 9) !Module/Mesh/Field: u%PRPMesh%TranslationVel = 9 + u%PRPMesh%TranslationVel( fieldIndx,node) = u%PRPMesh%TranslationVel( fieldIndx,node) + du * perturb_sign + CASE (10) !Module/Mesh/Field: u%PRPMesh%RotationVel = 10 + u%PRPMesh%RotationVel (fieldIndx,node) = u%PRPMesh%RotationVel (fieldIndx,node) + du * perturb_sign + CASE (11) !Module/Mesh/Field: u%PRPMesh%TranslationAcc = 11 + u%PRPMesh%TranslationAcc( fieldIndx,node) = u%PRPMesh%TranslationAcc( fieldIndx,node) + du * perturb_sign + CASE (12) !Module/Mesh/Field: u%PRPMesh%RotationAcc = 12 + u%PRPMesh%RotationAcc(fieldIndx,node) = u%PRPMesh%RotationAcc(fieldIndx,node) + du * perturb_sign + END SELECT + end if + else if ( u%WAMITMesh%Committed ) then SELECT CASE( p%Jac_u_indx(n,1) ) - CASE (1) !Module/Mesh/Field: u%Mesh%TranslationDisp = 13 - u%Mesh%TranslationDisp (fieldIndx,node) = u%Mesh%TranslationDisp (fieldIndx,node) + du * perturb_sign - CASE (2) !Module/Mesh/Field: u%Mesh%Orientation = 14 - CALL PerturbOrientationMatrix( u%Mesh%Orientation(:,:,node), du * perturb_sign, fieldIndx ) - CASE (3) !Module/Mesh/Field: u%Mesh%TranslationVel = 15 - u%Mesh%TranslationVel( fieldIndx,node) = u%Mesh%TranslationVel( fieldIndx,node) + du * perturb_sign - CASE (4) !Module/Mesh/Field: u%Mesh%RotationVel = 16 - u%Mesh%RotationVel (fieldIndx,node) = u%Mesh%RotationVel (fieldIndx,node) + du * perturb_sign - CASE (5) !Module/Mesh/Field: u%Mesh%TranslationAcc = 17 - u%Mesh%TranslationAcc( fieldIndx,node) = u%Mesh%TranslationAcc( fieldIndx,node) + du * perturb_sign - CASE (6) !Module/Mesh/Field: u%Mesh%RotationAcc = 18 - u%Mesh%RotationAcc(fieldIndx,node) = u%Mesh%RotationAcc(fieldIndx,node) + du * perturb_sign - - END SELECT + CASE (1) !Module/Mesh/Field: u%WAMITMesh%TranslationDisp = 1 + u%WAMITMesh%TranslationDisp (fieldIndx,node) = u%WAMITMesh%TranslationDisp (fieldIndx,node) + du * perturb_sign + CASE (2) !Module/Mesh/Field: u%WAMITMesh%Orientation = 2 + CALL PerturbOrientationMatrix( u%WAMITMesh%Orientation(:,:,node), du * perturb_sign, fieldIndx ) + CASE (3) !Module/Mesh/Field: u%WAMITMesh%TranslationVel = 3 + u%WAMITMesh%TranslationVel( fieldIndx,node) = u%WAMITMesh%TranslationVel( fieldIndx,node) + du * perturb_sign + CASE (4) !Module/Mesh/Field: u%WAMITMesh%RotationVel = 4 + u%WAMITMesh%RotationVel (fieldIndx,node) = u%WAMITMesh%RotationVel (fieldIndx,node) + du * perturb_sign + CASE (5) !Module/Mesh/Field: u%WAMITMesh%TranslationAcc = 5 + u%WAMITMesh%TranslationAcc( fieldIndx,node) = u%WAMITMesh%TranslationAcc( fieldIndx,node) + du * perturb_sign + CASE (6) !Module/Mesh/Field: u%WAMITMesh%RotationAcc = 6 + u%WAMITMesh%RotationAcc(fieldIndx,node) = u%WAMITMesh%RotationAcc(fieldIndx,node) + du * perturb_sign + END SELECT + SELECT CASE( p%Jac_u_indx(n,1) ) + CASE ( 7) !Module/Mesh/Field: u%PRPMesh%TranslationDisp = 7 + u%PRPMesh%TranslationDisp (fieldIndx,node) = u%PRPMesh%TranslationDisp (fieldIndx,node) + du * perturb_sign + CASE ( 8) !Module/Mesh/Field: u%PRPMesh%Orientation = 8 + CALL PerturbOrientationMatrix( u%PRPMesh%Orientation(:,:,node), du * perturb_sign, fieldIndx ) + CASE ( 9) !Module/Mesh/Field: u%PRPMesh%TranslationVel = 9 + u%PRPMesh%TranslationVel( fieldIndx,node) = u%PRPMesh%TranslationVel( fieldIndx,node) + du * perturb_sign + CASE (10) !Module/Mesh/Field: u%PRPMesh%RotationVel = 10 + u%PRPMesh%RotationVel (fieldIndx,node) = u%PRPMesh%RotationVel (fieldIndx,node) + du * perturb_sign + CASE (11) !Module/Mesh/Field: u%PRPMesh%TranslationAcc = 11 + u%PRPMesh%TranslationAcc( fieldIndx,node) = u%PRPMesh%TranslationAcc( fieldIndx,node) + du * perturb_sign + CASE (12) !Module/Mesh/Field: u%PRPMesh%RotationAcc = 12 + u%PRPMesh%RotationAcc(fieldIndx,node) = u%PRPMesh%RotationAcc(fieldIndx,node) + du * perturb_sign + END SELECT + else + SELECT CASE( p%Jac_u_indx(n,1) ) + CASE ( 1) !Module/Mesh/Field: u%PRPMesh%TranslationDisp = 1 + u%PRPMesh%TranslationDisp (fieldIndx,node) = u%PRPMesh%TranslationDisp (fieldIndx,node) + du * perturb_sign + CASE ( 2) !Module/Mesh/Field: u%PRPMesh%Orientation = 2 + CALL PerturbOrientationMatrix( u%PRPMesh%Orientation(:,:,node), du * perturb_sign, fieldIndx ) + CASE ( 3) !Module/Mesh/Field: u%PRPMesh%TranslationVel = 3 + u%PRPMesh%TranslationVel( fieldIndx,node) = u%PRPMesh%TranslationVel( fieldIndx,node) + du * perturb_sign + CASE ( 4) !Module/Mesh/Field: u%PRPMesh%RotationVel = 4 + u%PRPMesh%RotationVel (fieldIndx,node) = u%PRPMesh%RotationVel (fieldIndx,node) + du * perturb_sign + CASE ( 5) !Module/Mesh/Field: u%PRPMesh%TranslationAcc = 5 + u%PRPMesh%TranslationAcc( fieldIndx,node) = u%PRPMesh%TranslationAcc( fieldIndx,node) + du * perturb_sign + CASE ( 6) !Module/Mesh/Field: u%PRPMesh%RotationAcc = 6 + u%PRPMesh%RotationAcc(fieldIndx,node) = u%PRPMesh%RotationAcc(fieldIndx,node) + du * perturb_sign + END SELECT end if - END SUBROUTINE HD_Perturb_u !---------------------------------------------------------------------------------------------------------------------------------- @@ -3142,16 +3530,38 @@ SUBROUTINE HD_Perturb_x( p, n, perturb_sign, x, dx ) ! local variables - integer(intKi) :: indx + integer(intKi) :: i, offset1, offset2, n2 + + if ( p%totalStates == 0 ) return + !Note: All excitation states for all bodies are stored 1st, then all radiation states dx = p%dx(n) + offset1 = 1 + if ( n <= p%totalExctnStates ) then + + ! Find body index for exctn states + do i=1,p%nWAMITObj + offset2 = offset1 + p%WAMIT(i)%SS_Exctn%numStates + if ( n >= offset1 .and. n < offset2) then + n2 = n - offset1 + 1 + x%WAMIT(i)%SS_Exctn%x( n2 ) = x%WAMIT(i)%SS_Exctn%x( n2 ) + dx * perturb_sign + exit + end if + offset1 = offset2 + end do - if (n > p%WAMIT%SS_Exctn%N) then - indx = n - p%WAMIT%SS_Exctn%N - x%WAMIT%SS_Rdtn%x( indx ) = x%WAMIT%SS_Rdtn%x( indx ) + dx * perturb_sign else - indx = n - x%WAMIT%SS_Exctn%x( indx ) = x%WAMIT%SS_Exctn%x( indx ) + dx * perturb_sign + offset1 = p%totalExctnStates + 1 + ! Find body index for rdtn states + do i=1,p%nWAMITObj + offset2 = offset1 + p%WAMIT(i)%SS_Exctn%numStates + if ( n >= offset1 .and. n < offset2) then + n2 = n - offset1 + 1 + x%WAMIT(i)%SS_Rdtn%x( n2 ) = x%WAMIT(i)%SS_Rdtn%x( n2 ) + dx * perturb_sign + exit + end if + offset1 = offset2 + end do end if END SUBROUTINE HD_Perturb_x @@ -3177,13 +3587,12 @@ SUBROUTINE Compute_dY(p, y_p, y_m, delta, dY) indx_first = 1 - if ( y_p%Morison%DistribMesh%Committed ) then - call PackLoadMesh_dY(y_p%Morison%DistribMesh, y_m%Morison%DistribMesh, dY, indx_first) - call PackLoadMesh_dY(y_p%Morison%LumpedMesh , y_m%Morison%LumpedMesh , dY, indx_first) + if ( y_p%Morison%Mesh%Committed ) then + call PackLoadMesh_dY(y_p%Morison%Mesh, y_m%Morison%Mesh, dY, indx_first) + end if + if ( y_p%WAMITMesh%Committed ) then + call PackLoadMesh_dY(y_p%WAMITMesh, y_m%WAMITMesh, dY, indx_first) end if - - call PackLoadMesh_dY(y_p%Mesh, y_m%Mesh, dY, indx_first) - call PackLoadMesh_dY(y_p%AllHdroOrigin, y_m%AllHdroOrigin, dY, indx_first) do k=1,p%NumTotalOuts dY(k+indx_first-1) = y_p%WriteOutput(k) - y_m%WriteOutput(k) @@ -3219,7 +3628,7 @@ SUBROUTINE HD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, - INTEGER(IntKi) :: i, k, index, nu + INTEGER(IntKi) :: i, j, k, index, nu INTEGER(IntKi) :: ny INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 @@ -3241,16 +3650,16 @@ SUBROUTINE HD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, nu = size(p%Jac_u_indx,1) ! our operating point includes DCM (orientation) matrices, not just small angles like the perturbation matrices do - if ( u%Morison%DistribMesh%Committed ) then - nu = nu + u%Morison%DistribMesh%NNodes * 6 & ! p%Jac_u_indx has 3 for Orientation, but we need 9 at each node - + u%Morison%LumpedMesh%NNodes * 6 & ! p%Jac_u_indx has 3 for Orientation, but we need 9 at each node - + u%Mesh%NNodes * 6 ! p%Jac_u_indx has 3 for Orientation, but we need 9 at each node - nu = nu + 1 ! Extended input - else - nu = nu + u%Mesh%NNodes * 6 ! p%Jac_u_indx has 3 for Orientation, but we need 9 at each node - nu = nu + 1 ! Extended input + if ( u%Morison%Mesh%Committed ) then + nu = nu + u%Morison%Mesh%NNodes * 6 ! p%Jac_u_indx has 3 for Orientation, but we need 9 at each node + end if + if ( u%WAMITMesh%Committed ) then + nu = nu + u%WAMITMesh%NNodes * 6 ! p%Jac_u_indx has 3 for Orientation, but we need 9 at each node end if + nu = nu + u%PRPMesh%NNodes * 6 ! p%Jac_u_indx has 3 for Orientation, but we need 9 at each node + nu = nu + 1 ! Extended input + call AllocAry(u_op, nu,'u_op',ErrStat2,ErrMsg2) ! call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat>=AbortErrLev) return @@ -3266,13 +3675,16 @@ SUBROUTINE HD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, Mask(MASKID_ROTATIONACC) = .true. index = 1 - if ( u%Morison%DistribMesh%Committed ) then - call PackMotionMesh(u%Morison%DistribMesh, u_op, index, FieldMask=Mask) - call PackMotionMesh(u%Morison%LumpedMesh , u_op, index, FieldMask=Mask) + if ( u%Morison%Mesh%Committed ) then + call PackMotionMesh(u%Morison%Mesh, u_op, index, FieldMask=Mask) end if - call PackMotionMesh(u%Mesh, u_op, index, FieldMask=Mask) - + if ( u%WAMITMesh%Committed ) then + call PackMotionMesh(u%WAMITMesh, u_op, index, FieldMask=Mask) + end if + + call PackMotionMesh(u%PRPMesh, u_op, index, FieldMask=Mask) + ! extended input: u_op(index) = 0.0_R8Ki !u%WaveElev0 @@ -3289,13 +3701,12 @@ SUBROUTINE HD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, end if index = 1 - if ( y%Morison%DistribMesh%Committed ) then - call PackLoadMesh(y%Morison%DistribMesh, y_op, index) - call PackLoadMesh(y%Morison%LumpedMesh , y_op, index) + if ( y%Morison%Mesh%Committed ) then + call PackLoadMesh(y%Morison%Mesh, y_op, index) + end if + if ( y%WAMITMesh%Committed ) then + call PackLoadMesh(y%WAMITMesh, y_op, index) end if - - call PackLoadMesh(y%Mesh, y_op, index) - call PackLoadMesh(y%AllHdroOrigin, y_op, index) index = index - 1 do i=1,p%NumTotalOuts @@ -3306,47 +3717,64 @@ SUBROUTINE HD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, !.................................. IF ( PRESENT( x_op ) ) THEN - - if (.not. allocated(x_op)) then - call AllocAry(x_op, p%WAMIT%SS_Exctn%N+p%WAMIT%SS_Rdtn%N,'x_op',ErrStat2,ErrMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if (ErrStat>=AbortErrLev) return - end if - do i=1,p%WAMIT%SS_Exctn%N ! Loop through all DOFs - x_op(i) = x%WAMIT%SS_Exctn%x(i) - end do - do i=1,p%WAMIT%SS_Rdtn%N ! Loop through all DOFs - x_op(i+p%WAMIT%SS_Exctn%N) = x%WAMIT%SS_Rdtn%x(i) - end do + if ( p%totalStates == 0 ) return + if ( y%WAMITMesh%Committed ) then + if (.not. allocated(x_op)) then + call AllocAry(x_op, p%totalStates,'x_op',ErrStat2,ErrMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + if (ErrStat>=AbortErrLev) return + end if + index = 1 + do j=1, p%nWAMITObj + do i=1,p%WAMIT(j)%SS_Exctn%numStates ! Loop through all DOFs + x_op(index) = x%WAMIT(j)%SS_Exctn%x(i) + index = index + 1 + end do + end do + do j=1, p%nWAMITObj + do i=1,p%WAMIT(j)%SS_Rdtn%numStates ! Loop through all DOFs + x_op(index) = x%WAMIT(j)%SS_Rdtn%x(i) + index = index + 1 + end do + end do + end if END IF !.................................. IF ( PRESENT( dx_op ) ) THEN - - if (.not. allocated(dx_op)) then - call AllocAry(dx_op, p%WAMIT%SS_Exctn%N+p%WAMIT%SS_Rdtn%N,'dx_op',ErrStat2,ErrMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if (ErrStat>=AbortErrLev) return - end if - call HydroDyn_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dx, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if (ErrStat>=AbortErrLev) then - call HydroDyn_DestroyContState( dx, ErrStat2, ErrMsg2) - return + if ( p%totalStates == 0 ) return + + if ( y%WAMITMesh%Committed ) then + if (.not. allocated(dx_op)) then + call AllocAry(dx_op, p%totalStates,'dx_op',ErrStat2,ErrMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + if (ErrStat>=AbortErrLev) return end if - - do i=1,p%WAMIT%SS_Exctn%N ! Loop through all DOFs - dx_op(i) = dx%WAMIT%SS_Exctn%x(i) - end do - do i=1,p%WAMIT%SS_Rdtn%N ! Loop through all DOFs - dx_op(i+p%WAMIT%SS_Exctn%N) = dx%WAMIT%SS_Rdtn%x(i) - end do - call HydroDyn_DestroyContState( dx, ErrStat2, ErrMsg2) - + call HydroDyn_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dx, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + if (ErrStat>=AbortErrLev) then + call HydroDyn_DestroyContState( dx, ErrStat2, ErrMsg2) + return + end if + index = 1 + do j=1, p%nWAMITObj + do i=1,p%WAMIT(j)%SS_Exctn%numStates ! Loop through all DOFs + dx_op(index) = dx%WAMIT(j)%SS_Exctn%x(i) + index = index + 1 + end do + end do + do j=1, p%nWAMITObj + do i=1,p%WAMIT(j)%SS_Rdtn%numStates ! Loop through all DOFs + dx_op(index) = dx%WAMIT(j)%SS_Rdtn%x(i) + index = index + 1 + end do + end do + call HydroDyn_DestroyContState( dx, ErrStat2, ErrMsg2) + end if END IF !.................................. diff --git a/modules/hydrodyn/src/HydroDyn.txt b/modules/hydrodyn/src/HydroDyn.txt index ca379172d8..33f2852f8e 100644 --- a/modules/hydrodyn/src/HydroDyn.txt +++ b/modules/hydrodyn/src/HydroDyn.txt @@ -24,7 +24,7 @@ usefrom WAMIT.txt usefrom WAMIT2.txt usefrom Morison.txt #usefrom FIT.txt -param HydroDyn/HydroDyn unused INTEGER MaxHDOutputs - 54 - "The maximum number of output channels supported by this module" - +param HydroDyn/HydroDyn unused INTEGER MaxHDOutputs - 537 - "The maximum number of output channels supported by this module" - typedef HydroDyn/HydroDyn InitInputType CHARACTER(1024) InputFile - - - "Supplied by Driver: full path and filename for the HydroDyn module" - typedef ^ ^ LOGICAL UseInputFile - - - "Supplied by Driver: .TRUE. if using a input file, .FALSE. if all inputs are being passed in by the caller" - typedef ^ ^ CHARACTER(1024) OutRootName - - - "Supplied by Driver: The name of the root file (without extension) including the full path" - @@ -36,26 +36,27 @@ typedef ^ ^ LOGICAL typedef ^ ^ SiKi WaveElevXY {:}{:} - - "Supplied by Driver: X-Y locations for WaveElevation output (for visualization). First dimension is the X (1) and Y (2) coordinate. Second dimension is the point number." "m,-" typedef ^ ^ ReKi PtfmLocationX - - - "Supplied by Driver: X coordinate of platform location in the wave field" "m" typedef ^ ^ ReKi PtfmLocationY - - - "Supplied by Driver: Y coordinate of platform location in the wave field" "m" -typedef ^ ^ CHARACTER(80) PtfmSgFChr - - - "Platform horizontal surge translation force (flag) or DEFAULT" - -typedef ^ ^ LOGICAL PtfmSgF - - - "Optionally Supplied by Driver: Platform horizontal surge translation force (flag)" - -typedef ^ ^ CHARACTER(80) PtfmSwFChr - - - "Platform horizontal sway translation force (flag) or DEFAULT" - -typedef ^ ^ LOGICAL PtfmSwF - - - "Optionally Supplied by Driver: Platform horizontal sway translation force (flag)" - -typedef ^ ^ CHARACTER(80) PtfmHvFChr - - - "Platform vertical heave translation force (flag) or DEFAULT" - -typedef ^ ^ LOGICAL PtfmHvF - - - "Optionally Supplied by Driver: Platform vertical heave translation force (flag)" - -typedef ^ ^ CHARACTER(80) PtfmRFChr - - - "Platform roll tilt rotation force (flag) or DEFAULT" - -typedef ^ ^ LOGICAL PtfmRF - - - "Optionally Supplied by Driver: Platform roll tilt rotation force (flag)" - -typedef ^ ^ CHARACTER(80) PtfmPFChr - - - "Platform pitch tilt rotation force (flag) or DEFAULT" - -typedef ^ ^ LOGICAL PtfmPF - - - "Optionally Supplied by Driver: Platform pitch tilt rotation force (flag)" - -typedef ^ ^ CHARACTER(80) PtfmYFChr - - - "Platform yaw rotation force (flag) or DEFAULT" - -typedef ^ ^ LOGICAL PtfmYF - - - "Optionally Supplied by Driver: Platform yaw rotation force (flag)" - -typedef ^ ^ ReKi AddF0 {6} - - "Additional pre-load forces and moments (N,N,N,N-m,N-m,N-m)" - -typedef ^ ^ ReKi AddCLin {6}{6} - - "Additional stiffness matrix" - -typedef ^ ^ ReKi AddBLin {6}{6} - - "Additional linear damping matrix" - -typedef ^ ^ ReKi AddBQuad {6}{6} - - "Additional quadratic damping (drag) matrix" - +typedef ^ ^ ReKi AddF0 {:}{:} - - "Additional pre-load forces and moments (N,N,N,N-m,N-m,N-m)" - +typedef ^ ^ ReKi AddCLin {:}{:}{:} - - "Additional stiffness matrix" - +typedef ^ ^ ReKi AddBLin {:}{:}{:} - - "Additional linear damping matrix" - +typedef ^ ^ ReKi AddBQuad {:}{:}{:} - - "Additional quadratic damping (drag) matrix" - typedef ^ ^ Waves_InitInputType Waves - - - "Initialization data for Waves module" - typedef ^ ^ Waves2_InitInputType Waves2 - - - "Initialization data for Waves module" - typedef ^ ^ Current_InitInputType Current - - - "Initialization data for Current module" - -typedef ^ ^ CHARACTER(1024) PotFile - - - "The name of the root potential flow file (without extension for WAMIT, complete name for FIT)" - +typedef ^ ^ CHARACTER(1024) PotFile {:} - - "The name of the root potential flow file (without extension for WAMIT, complete name for FIT)" - +typedef ^ ^ INTEGER nWAMITObj - - - "number of WAMIT input files. If NBodyMod = 1 then nPotFiles will be 1 even if NBody > 1" - +typedef ^ ^ INTEGER vecMultiplier - - - "multiplier for the WAMIT vectors and matrices. If NBodyMod=1 then this = NBody, else 1" - +typedef ^ ^ INTEGER NBody - - - "[>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6]" - +typedef ^ ^ INTEGER NBodyMod - - - "Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1]" - +typedef ^ ^ ReKi PtfmVol0 {:} - - "" - +typedef ^ ^ LOGICAL HasWAMIT - - - ".TRUE. if using WAMIT model, .FALSE. otherwise" - +typedef ^ ^ ReKi WAMITULEN {:} - - "" - +typedef ^ ^ ReKi PtfmRefxt {:} - - "The xt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1; must be 0.0 if NBodyMod=2 ]" (m) +typedef ^ ^ ReKi PtfmRefyt {:} - - "The yt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1; must be 0.0 if NBodyMod=2 ]" (m) +typedef ^ ^ ReKi PtfmRefzt {:} - - "The zt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1; must be 0.0 if NBodyMod=2 ]" (m) +typedef ^ ^ R8Ki PtfmRefztRot {:} - - "The rotation about zt of the body reference frame(s) from xt/yt" radians +typedef ^ ^ ReKi PtfmCOBxt {:} - - "" - +typedef ^ ^ ReKi PtfmCOByt {:} - - "" - typedef ^ ^ WAMIT_InitInputType WAMIT - - - "Initialization data for WAMIT module" - typedef ^ ^ WAMIT2_InitInputType WAMIT2 - - - "Initialization data for WAMIT2 module" - typedef ^ ^ Morison_InitInputType Morison - - - "Initialization data for Morison module" - @@ -66,7 +67,7 @@ typedef ^ ^ CHARACTER(C typedef ^ ^ INTEGER OutSwtch - - - "Output requested channels to: [1=Hydrodyn.out 2=GlueCode.out 3=both files]" - typedef ^ ^ LOGICAL OutAll - - - "Output all user-specified member and joint loads (only at each member end, not interior locations) [T/F]" - typedef ^ ^ INTEGER NumOuts - - - "The number of outputs for this module as requested in the input file" - -typedef ^ ^ CHARACTER(ChanLen) OutList {54} - - "The user-requested output channel labels for this modules. This should really be dimensioned with MaxOutPts" - +typedef ^ ^ CHARACTER(ChanLen) OutList {:} - - "The user-requested output channel labels for this modules. This should really be dimensioned with MaxOutPts" - typedef ^ ^ LOGICAL HDSum - - - "Generate a HydroDyn summary file [T/F]" - typedef ^ ^ INTEGER UnSum - - - "File unit for the HydroDyn summary file [-1 = no summary file]" - typedef ^ ^ CHARACTER(20) OutFmt - - - "Output format for numerical results" - @@ -75,9 +76,9 @@ typedef ^ ^ CHARACTER(2 # # Define outputs from the initialization routine here: # -typedef ^ InitOutputType WAMIT_InitOutputType WAMIT - - - "Initialization output from the WAMIT module" - -typedef ^ ^ WAMIT2_InitOutputType WAMIT2 - - - "Initialization output from the WAMIT2 module" - -typedef ^ ^ Waves2_InitOutputType Waves2 - - - "Initialization output from the Waves2 module" - +typedef ^ InitOutputType WAMIT_InitOutputType WAMIT {:} - - "Initialization output from the WAMIT module" - +typedef ^ InitOutputType WAMIT2_InitOutputType WAMIT2 {:} - - "Initialization output from the WAMIT2 module" - +typedef ^ InitOutputType Waves2_InitOutputType Waves2 - - - "Initialization output from the Waves2 module" - typedef ^ ^ Morison_InitOutputType Morison - - - "Initialization output from the Morison module" - typedef ^ ^ CHARACTER(ChanLen) WriteOutputHdr {:} - - "The is the list of all HD-related output channel header strings (includes all sub-module channels)" - typedef ^ ^ CHARACTER(ChanLen) WriteOutputUnt {:} - - "The is the list of all HD-related output channel unit strings (includes all sub-module channels)" - @@ -94,25 +95,25 @@ typedef ^ ^ LOGICAL # ..... HD_ModuleMapType .................................................................................................................... -typedef ^ HD_ModuleMapType MeshMapType HD_P_2_WRP_P -typedef ^ HD_ModuleMapType MeshMapType M_P_2_WRP_P -typedef ^ HD_ModuleMapType MeshMapType M_L_2_WRP_P +typedef ^ HD_ModuleMapType MeshMapType uW_P_2_PRP_P - - - "Mesh mapping data: WAMIT body kinematics to PRP node at (0,0,0)" - +typedef ^ HD_ModuleMapType MeshMapType W_P_2_PRP_P - - - "Mesh mapping data: WAMIT loads to PRP node at (0,0,0)" - +typedef ^ HD_ModuleMapType MeshMapType M_P_2_PRP_P - - - "Mesh mapping data: lumped Morison loads to PRP node at (0,0,0)" - # # # ..... States .................................................................................................................... # Define continuous (differentiable) states here: # -typedef ^ ContinuousStateType WAMIT_ContinuousStateType WAMIT - - - "continuous states from the wamit module" - -typedef ^ ContinuousStateType WAMIT2_ContinuousStateType WAMIT2 - - - "continuous states from the wamit2 module" - +typedef ^ ContinuousStateType WAMIT_ContinuousStateType WAMIT {:} - - "continuous states from the wamit module" - +typedef ^ ContinuousStateType WAMIT2_ContinuousStateType WAMIT2 {:} - - "continuous states from the wamit2 module" - typedef ^ ContinuousStateType Waves2_ContinuousStateType Waves2 - - - "continuous states from the waves2 module" - typedef ^ ContinuousStateType Morison_ContinuousStateType Morison - - - "continuous states from the Morison module" - # # # Define discrete (nondifferentiable) states here: # -typedef ^ DiscreteStateType WAMIT_DiscreteStateType WAMIT - - - "discrete states from the wamit module" - -typedef ^ DiscreteStateType WAMIT2_DiscreteStateType WAMIT2 - - - "discrete states from the wamit2 module" - +typedef ^ DiscreteStateType WAMIT_DiscreteStateType WAMIT {:} - - "discrete states from the wamit module" - +typedef ^ DiscreteStateType WAMIT2_DiscreteStateType WAMIT2 {:} - - "discrete states from the wamit2 module" - #typedef ^ DiscreteStateType FIT_DiscreteStateType FIT - - - "discrete states from the FIT module" - typedef ^ DiscreteStateType Waves2_DiscreteStateType Waves2 - - - "discrete states from the waves2 module" - typedef ^ DiscreteStateType Morison_DiscreteStateType Morison - - - "discrete states from the Morison module" - @@ -120,7 +121,7 @@ typedef ^ DiscreteStateType Morison_Dis # # Define constraint states here: # -typedef ^ ConstraintStateType WAMIT_ConstraintStateType WAMIT - - - "constraint states from WAMIT (may be empty)" - +typedef ^ ConstraintStateType WAMIT_ConstraintStateType WAMIT - - - "constraint states from WAMIT (may be empty)" - typedef ^ ConstraintStateType WAMIT2_ConstraintStateType WAMIT2 - - - "constraint states from WAMIT2 (may be empty)" - typedef ^ ConstraintStateType Waves2_ConstraintStateType Waves2 - - - "constraint states from the waves2 module" - typedef ^ ConstraintStateType Morison_ConstraintStateType Morison - - - "constraint states from the Morison module" - @@ -128,8 +129,8 @@ typedef ^ ConstraintStateType Morison_Con # # Define any other states here: # -typedef ^ OtherStateType WAMIT_OtherStateType WAMIT - - - "OtherState information from the WAMIT module" - -typedef ^ OtherStateType WAMIT2_OtherStateType WAMIT2 - - - "OtherState information from the WAMIT2 module" - +typedef ^ OtherStateType WAMIT_OtherStateType WAMIT {:} - - "OtherState information from the WAMIT module" - +typedef ^ OtherStateType WAMIT2_OtherStateType WAMIT2 {:} - - "OtherState information from the WAMIT2 module" - #typedef ^ OtherStateType FIT_OtherStateType FIT - - - "OtherState information from the FIT module" - typedef ^ OtherStateType Waves2_OtherStateType Waves2 - - - "OtherState information from the Waves2 module" - typedef ^ ^ Morison_OtherStateType Morison - - - "OtherState information from the Morison module" - @@ -137,44 +138,51 @@ typedef ^ ^ Morison_Oth # ..... 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 MeshType y_mapped - - - "An intermediate mesh used to transfer hydrodynamic loads from the various HD-related meshes to the AllHdroOrigin mesh" - -typedef ^ ^ MeshType AllHdroOrigin_position - - - "A motions mesh which has all translational displacements set to zero. Used in the transfer of hydrodynamic loads from the various HD-related meshes to the AllHdroOrigin mesh" - -typedef ^ ^ MeshType MrsnLumpedMesh_position - - - "A motions mesh which has all translational displacements set to zero. Used in the transfer of hydrodynamic loads from the various HD-related meshes to the AllHdroOrigin mesh" - -typedef ^ ^ MeshType MrsnDistribMesh_position - - - "A motions mesh which has all translational displacements set to zero. Used in the transfer of hydrodynamic loads from the various HD-related meshes to the AllHdroOrigin mesh" - +typedef ^ MiscVarType MeshType AllHdroOrigin - - - "An intermediate mesh used to transfer hydrodynamic loads from the various HD-related meshes to the AllHdroOrigin mesh" - +typedef ^ ^ MeshType MrsnMesh_position - - - "A motions mesh which has all translational displacements set to zero. Used in the transfer of hydrodynamic loads from the various HD-related meshes to the AllHdroOrigin mesh" - typedef ^ ^ HD_ModuleMapType HD_MeshMap - - - typedef ^ ^ INTEGER Decimate - - - "The output decimation counter" - typedef ^ ^ DbKi LastOutTime - - - "Last time step which was written to the output file (sec)" - typedef ^ ^ INTEGER LastIndWave - - - "The last index used in the wave kinematics arrays, used to optimize interpolation" - -typedef ^ ^ ReKi F_PtfmAdd {6} - - "The total forces and moments due to additional pre-load, stiffness, and damping" - -typedef ^ ^ ReKi F_Hydro {6} - - "The total hydrodynamic forces and moments integrated about the WAMIT reference point" - -typedef ^ ^ ReKi F_Waves {6} - - "The total waves forces on a WAMIT body calculated by first and second order methods (WAMIT and WAMIT2 modules)" - -typedef ^ ^ WAMIT_MiscVarType WAMIT - - - "misc var information from the WAMIT module" - -typedef ^ ^ WAMIT2_MiscVarType WAMIT2 - - - "misc var information from the WAMIT2 module" - +typedef ^ ^ ReKi F_PtfmAdd {:} - - "The total forces and moments due to additional pre-load, stiffness, and damping" - +typedef ^ ^ ReKi F_Hydro {6} - - "The total hydrodynamic forces and moments integrated about the (0,0,0) platform reference point" - +typedef ^ ^ ReKi F_Waves {:} - - "The total waves forces on a WAMIT body calculated by first and second order methods (WAMIT and WAMIT2 modules)" - +typedef ^ ^ WAMIT_MiscVarType WAMIT {:} - - "misc var information from the WAMIT module" - +typedef ^ ^ WAMIT2_MiscVarType WAMIT2 {:} - - "misc var information from the WAMIT2 module" - typedef ^ ^ Waves2_MiscVarType Waves2 - - - "misc var information from the Waves2 module" - typedef ^ ^ Morison_MiscVarType Morison - - - "misc var information from the Morison module" - -typedef ^ ^ WAMIT_InputType u_WAMIT - - - "WAMIT module inputs" - -typedef ^ ^ WAMIT2_InputType u_WAMIT2 - - - "WAMIT2 module inputs" - +typedef ^ ^ WAMIT_InputType u_WAMIT {:} - - "WAMIT module inputs" - +typedef ^ ^ WAMIT2_InputType u_WAMIT2 {:} - - "WAMIT2 module inputs" - typedef ^ ^ Waves2_InputType u_Waves2 - - - "Waves2 module inputs" - # ..... Parameters ................................................................................................................ # Define parameters here: # Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: # -typedef ^ ParameterType WAMIT_ParameterType WAMIT - - - "Parameter data for the WAMIT module" - -typedef ^ ParameterType WAMIT2_ParameterType WAMIT2 - - - "Parameter data for the WAMIT2 module" - +typedef ^ ParameterType INTEGER nWAMITObj - - - "number of WAMIT input files and matrices. If NBodyMod = 1 then nPotFiles will be 1 even if NBody > 1" - +typedef ^ ^ INTEGER vecMultiplier - - - "multiplier for the WAMIT vectors and matrices. If NBodyMod=1 then this = NBody, else 1" - +typedef ^ ^ WAMIT_ParameterType WAMIT {:} - - "Parameter data for the WAMIT module" - +typedef ^ ^ WAMIT2_ParameterType WAMIT2 {:} - - "Parameter data for the WAMIT2 module" - +typedef ^ ^ LOGICAL WAMIT2used - .FALSE. - "Indicates when WAMIT2 is used. Shortcuts some calculations" - #typedef ^ ^ FIT_ParameterType FIT - - - "Parameter data for the FIT module" - -typedef ^ ParameterType Waves2_ParameterType Waves2 - - - "Parameter data for the Waves2 module" - +typedef ^ ^ Waves2_ParameterType Waves2 - - - "Parameter data for the Waves2 module" - typedef ^ ^ Morison_ParameterType Morison - - - "Parameter data for the Morison module" - typedef ^ ^ INTEGER PotMod - - - "1 if using WAMIT model, 0 if no potential flow model, or 2 if FIT model" - +typedef ^ ^ INTEGER NBody - - - "[>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6]" - +typedef ^ ^ INTEGER NBodyMod - - - "Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1]" - +typedef ^ ^ INTEGER totalStates - - - "Number of excitation and radiation states for all WAMIT bodies" - +typedef ^ ^ INTEGER totalExctnStates - - - "Number of excitation states for all WAMIT bodies" - +typedef ^ ^ INTEGER totalRdtnStates - - - "Number of radiation states for all WAMIT bodies" - typedef ^ ^ SiKi WaveTime {:} - - "Array of time samples, (sec)" - typedef ^ ^ INTEGER NStepWave - - - "Number of data points in the wave kinematics arrays" - typedef ^ ^ INTEGER NWaveElev - - - "Number of wave elevation outputs" - typedef ^ ^ SiKi WaveElev {:}{:} - - "Total wave elevation" - typedef ^ ^ SiKi WaveElev1 {:}{:} - - "First order wave elevation" - -typedef ^ ^ ReKi WtrDpth - - - "Water depth" (m) -typedef ^ ^ ReKi AddF0 {6} - - "Additional pre-load forces and moments (N,N,N,N-m,N-m,N-m)" - -typedef ^ ^ ReKi AddCLin {6}{6} - - "Additional stiffness matrix" - -typedef ^ ^ ReKi AddBLin {6}{6} - - "Additional linear damping matrix" - -typedef ^ ^ ReKi AddBQuad {6}{6} - - "Additional quadratic damping (drag) matrix" - +typedef ^ ^ SiKi WaveElev2 {:}{:} - - "Second order wave elevation" - +typedef ^ ^ ReKi WtrDpth - - - "Water depth" (m) +typedef ^ ^ ReKi AddF0 {:}{:} - - "Additional pre-load forces and moments (N,N,N,N-m,N-m,N-m)" - +typedef ^ ^ ReKi AddCLin {:}{:}{:} - - "Additional stiffness matrix" - +typedef ^ ^ ReKi AddBLin {:}{:}{:} - - "Additional linear damping matrix" - +typedef ^ ^ ReKi AddBQuad {:}{:}{:} - - "Additional quadratic damping (drag) matrix" - typedef ^ ^ DbKi DT - - - "Time step in seconds for integration of continuous states (if a fixed-step integrator is used) and update of discrete states" - typedef ^ ^ OutParmType OutParam {:} - - "" - typedef ^ ^ INTEGER NumOuts - - - "Number of HydroDyn module-level outputs (not the total number including sub-modules" - @@ -185,25 +193,25 @@ typedef ^ ^ CHARACTER(2 typedef ^ ^ CHARACTER(ChanLen) Delim - - - "Delimiter string for outputs, defaults to tab-delimiters" - typedef ^ ^ INTEGER UnOutFile - - - "File unit for the HydroDyn outputs" - typedef ^ ^ INTEGER OutDec - - - "Write every OutDec time steps" - -typedef ^ ^ Integer Jac_u_indx {:}{:} - - "matrix to help fill/pack the u vector in computing the jacobian" - -typedef ^ ^ R8Ki du {:} - - "vector that determines size of perturbation for u (inputs)" - -typedef ^ ^ R8Ki dx {:} - - "vector that determines size of perturbation for x (continuous states)" - -typedef ^ ^ Integer Jac_ny - - - "number of outputs in jacobian matrix" - +typedef ^ ^ Integer Jac_u_indx {:}{:} - - "matrix to help fill/pack the u vector in computing the jacobian" - +typedef ^ ^ R8Ki du {:} - - "vector that determines size of perturbation for u (inputs)" - +typedef ^ ^ R8Ki dx {:} - - "vector that determines size of perturbation for x (continuous states)" - +typedef ^ ^ Integer Jac_ny - - - "number of outputs in jacobian matrix" - # # # ..... Inputs .................................................................................................................... # Define inputs that are contained on the mesh here: # typedef ^ InputType Morison_InputType Morison - - - "Morison module inputs" - -typedef ^ InputType MeshType Mesh - - - "Displacements at the WAMIT reference point in the inertial frame" - +typedef ^ InputType MeshType WAMITMesh - - - "Motions at the WAMIT reference point(s) in the inertial frame" - +typedef ^ InputType MeshType PRPMesh - - - "Motions at the Platform reference point in the inertial frame" - # # # ..... Outputs ................................................................................................................... # Define outputs that are contained on the mesh here: -typedef ^ OutputType WAMIT_OutputType WAMIT - - - "WAMIT module outputs" - -typedef ^ OutputType WAMIT2_OutputType WAMIT2 - - - "WAMIT2 module outputs" - +typedef ^ OutputType WAMIT_OutputType WAMIT {:} - - "WAMIT module outputs" - +typedef ^ OutputType WAMIT2_OutputType WAMIT2 {:} - - "WAMIT2 module outputs" - typedef ^ OutputType Waves2_OutputType Waves2 - - - "Waves2 module outputs" - typedef ^ ^ Morison_OutputType Morison - - - "Morison module outputs" - -typedef ^ OutputType MeshType Mesh - - - "Point Loads at the WAMIT reference point in the inertial frame" - -typedef ^ OutputType MeshType AllHdroOrigin - - - "All HD-related loads integrated to the origin, (0,0,0) in the inertial frame" - -typedef ^ ^ ReKi WriteOutput {:} - - "" - +typedef ^ OutputType MeshType WAMITMesh - - - "Point Loads at the WAMIT reference point(s) in the inertial frame" - +typedef ^ ^ ReKi WriteOutput {:} - - "Outputs to be written to the output file(s)" - diff --git a/modules/hydrodyn/src/HydroDyn_DriverCode.f90 b/modules/hydrodyn/src/HydroDyn_DriverCode.f90 index 88c003c732..3bb493be1d 100644 --- a/modules/hydrodyn/src/HydroDyn_DriverCode.f90 +++ b/modules/hydrodyn/src/HydroDyn_DriverCode.f90 @@ -39,16 +39,11 @@ PROGRAM HydroDynDriver LOGICAL :: Linearize INTEGER :: NSteps REAL(DbKi) :: TimeInterval - INTEGER :: WAMITInputsMod - CHARACTER(1024) :: WAMITInputsFile - REAL(ReKi) :: uWAMITInSteady(6) - REAL(ReKi) :: uDotWAMITInSteady(6) - REAL(ReKi) :: uDotDotWAMITInSteady(6) - INTEGER :: MorisonInputsMod - CHARACTER(1024) :: MorisonInputsFile - REAL(ReKi) :: uMorisonInSteady(6) - REAL(ReKi) :: uDotMorisonInSteady(6) - REAL(ReKi) :: uDotDotMorisonInSteady(6) + INTEGER :: PRPInputsMod + CHARACTER(1024) :: PRPInputsFile + REAL(ReKi) :: uPRPInSteady(6) + REAL(ReKi) :: uDotPRPInSteady(6) + REAL(ReKi) :: uDotDotPRPInSteady(6) LOGICAL :: WaveElevSeriesFlag !< Should we put together a wave elevation series and save it to file? REAL(ReKi) :: WaveElevdX !< Spacing in the X direction for wave elevation series (m) REAL(ReKi) :: WaveElevdY !< Spacing in the Y direction for the wave elevation series (m) @@ -92,22 +87,20 @@ PROGRAM HydroDynDriver TYPE(HydroDyn_ContinuousStateType) :: dxdt ! First time derivatives of the continuous states - INTEGER(IntKi) :: UnWAMITInp ! WAMIT Inputs file identifier + INTEGER(IntKi) :: UnPRPInp ! PRP Inputs file identifier INTEGER(IntKi) :: UnMorisonInp ! Morison Inputs file identifier INTEGER(IntKi) :: UnHD_Out ! Output file identifier - REAL(ReKi), ALLOCATABLE :: WAMITin(:,:) ! Variable for storing time, forces, and body velocities, in m/s or rad/s for WAMIT + REAL(ReKi), ALLOCATABLE :: PRPin(:,:) ! Variable for storing time, forces, and body velocities, in m/s or rad/s for PRP REAL(ReKi), ALLOCATABLE :: Morisonin(:,:) ! Variable for storing time, forces, and body velocities, in m/s or rad/s for Morison elements - - TYPE(MeshType) :: PMesh ! Point mesh that we will use to map to Morison and u(1)%Mesh - TYPE(MeshMapType) :: Map_P_to_MorisonDist - TYPE(MeshMapType) :: Map_P_to_MorisonLumped - + + INTEGER(IntKi) :: NBody ! Number of WAMIT bodies to work with if prescribing kinematics on each body (PRPInputsMod<0) + INTEGER(IntKi) :: I ! Generic loop counter INTEGER(IntKi) :: J ! Generic loop counter INTEGER(IntKi) :: n ! Loop counter (for time step) - INTEGER(IntKi) :: ErrStat ! Status of error message - CHARACTER(1024) :: ErrMsg ! Error message if ErrStat /= ErrID_None - REAL(ReKi) :: dcm (3,3) ! The resulting transformation matrix from X to x, (-). + INTEGER(IntKi) :: ErrStat,ErrStat2 ! Status of error message + CHARACTER(1024) :: ErrMsg,ErrMsg2 ! Error message if ErrStat /= ErrID_None + REAL(R8Ki) :: dcm (3,3) ! The resulting transformation matrix from X to x, (-). 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(HD_Drvr_InitInput) :: drvrInitInp ! Initialization data for the driver program @@ -121,6 +114,10 @@ PROGRAM HydroDynDriver real(DbKi) :: SttsTime ! Amount of time between screen status messages (sec) integer :: n_SttsTime ! Number of time steps between screen status messages (-) + type(MeshType) :: RefPtMesh ! 1-node Point mesh located at (0,0,0) in global system where all PRP-related driver inputs are set + type(MeshMapType) :: HD_Ref_2_WB_P ! Mesh mapping between Reference pt mesh and WAMIT body(ies) mesh + type(MeshMapType) :: HD_Ref_2_M_P ! Mesh mapping between Reference pt mesh and Morison mesh + real(R8Ki) :: theta(3) ! mesh creation helper data ! For testing LOGICAL :: DoTight = .FALSE. @@ -195,9 +192,6 @@ PROGRAM HydroDynDriver !BJJ: added this for IceFloe/IceDyn InitInData%hasIce = .FALSE. - - - !------------------------------------------------------------------------------------- @@ -205,65 +199,78 @@ PROGRAM HydroDynDriver !------------------------------------------------------------------------------------- - IF ( drvrInitInp%WAMITInputsMod == 2 ) THEN + IF ( drvrInitInp%PRPInputsMod == 2 ) THEN - ! Open the WAMIT inputs data file - CALL GetNewUnit( UnWAMITInp ) - CALL OpenFInpFile ( UnWAMITInp, drvrInitInp%WAMITInputsFile, ErrStat, ErrMsg ) - IF (ErrStat >=AbortErrLev) STOP + ! Open the PRP inputs data file + CALL GetNewUnit( UnPRPInp ) + CALL OpenFInpFile ( UnPRPInp, drvrInitInp%PRPInputsFile, ErrStat, ErrMsg ) + IF (ErrStat >=AbortErrLev) THEN + call WrScr( ErrMsg ) + STOP + ENDIF - ALLOCATE ( WAMITin(drvrInitInp%NSteps, 19), STAT = ErrStat ) + ALLOCATE ( PRPin(drvrInitInp%NSteps, 19), STAT = ErrStat ) IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for WAMITin array.' + ErrMsg = ' Error allocating space for PRPin array.' CALL WrScr( ErrMsg ) - CLOSE( UnWAMITInp ) + CLOSE( UnPRPInp ) STOP END IF DO n = 1,drvrInitInp%NSteps - READ (UnWAMITInp,*,IOSTAT=ErrStat) (WAMITin (n,J), J=1,19) + READ (UnPRPInp,*,IOSTAT=ErrStat) (PRPin (n,J), J=1,19) IF ( ErrStat /= 0 ) THEN - ErrMsg = ' Error reading the WAMIT input time-series file. ' + ErrMsg = ' Error reading the PRP input time-series file. ' CALL WrScr( ErrMsg ) STOP END IF END DO ! Close the inputs file - CLOSE ( UnWAMITInp ) + CLOSE ( UnPRPInp ) END IF - IF ( drvrInitInp%MorisonInputsMod == 2 ) THEN + ! multi-body kinematics driver option (time, PRP DOFs 1-6, body1 DOFs 1-6, body2 DOFs 1-6...) + IF ( drvrInitInp%PRPInputsMod < 0 ) THEN - ! Open the Morison inputs data file - CALL GetNewUnit( UnMorisonInp ) - CALL OpenFInpFile ( UnMorisonInp, drvrInitInp%MorisonInputsFile, ErrStat, ErrMsg ) - IF (ErrStat >=AbortErrLev) STOP + NBODY = -drvrInitInp%PRPInputsMod + ! Open the WAMIT inputs data file + CALL GetNewUnit( UnPRPInp ) + CALL OpenFInpFile ( UnPRPInp, drvrInitInp%PRPInputsFile, ErrStat, ErrMsg ) + IF (ErrStat >=AbortErrLev) THEN + call WrScr( ErrMsg ) + STOP + ENDIF - ALLOCATE ( MorisonIn(drvrInitInp%NSteps, 19), STAT = ErrStat ) + ALLOCATE ( PRPin(drvrInitInp%NSteps, 7+6*NBODY), STAT = ErrStat ) IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for MorisonIn array.' + ErrMsg = ' Error allocating space for PRPin array.' CALL WrScr( ErrMsg ) - CLOSE( UnMorisonInp ) + CLOSE( UnPRPInp ) STOP END IF + PRINT *, 'NBody is '//trim(Num2LStr(NBody))//' and planning to read in '//trim(Num2LStr(7+6*NBODY))//' columns from the input file' + DO n = 1,drvrInitInp%NSteps - READ (UnMorisonInp,*,IOSTAT=ErrStat) (MorisonIn (n,J), J=1,19) + READ (UnPRPInp,*,IOSTAT=ErrStat) (PRPin (n,J), J=1,7+6*NBODY) IF ( ErrStat /= 0 ) THEN - ErrMsg = ' Error reading the Morison input time-series file. ' + ErrMsg = ' Error reading the WAMIT input time-series file (for multiple bodies). ' CALL WrScr( ErrMsg ) STOP END IF END DO ! Close the inputs file - CLOSE ( UnMorisonInp ) - END IF + CLOSE ( UnPRPInp ) + ELSE + NBody = 0 + END IF + ! Setup the arrays for the wave elevation timeseries if requested by the driver input file @@ -290,48 +297,6 @@ PROGRAM HydroDynDriver ENDDO ENDIF - - ! Setup mesh for input motions for Morison and WAMIT - CALL MeshCreate( BlankMesh = PMesh & - ,IOS = COMPONENT_INPUT & - ,Nnodes = 1 & - ,ErrStat = ErrStat & - ,ErrMess = ErrMsg & - ,TranslationDisp = .TRUE. & - ,Orientation = .TRUE. & - ,TranslationVel = .TRUE. & - ,RotationVel = .TRUE. & - ,TranslationAcc = .TRUE. & - ,RotationAcc = .TRUE.) - IF ( ErrStat >= ErrID_Fatal ) THEN - CALL WrScr( ErrMsg ) - STOP - END IF - - CALL MeshPositionNode (PMesh & - , 1 & - , (/0.0_ReKi, 0.0_ReKi, 0.0_ReKi/) & - , ErrStat & - , ErrMsg ) - IF ( ErrStat >= ErrID_Fatal ) THEN - CALL WrScr( ErrMsg ) - STOP - END IF - - CALL MeshConstructElement( PMesh, ELEMENT_POINT, ErrStat, ErrMsg, 1 ) - IF ( ErrStat >= ErrID_Fatal ) THEN - CALL WrScr( ErrMsg ) - STOP - END IF - - CALL MeshCommit ( PMesh, ErrStat, ErrMsg ) - IF ( ErrStat >= ErrID_Fatal ) THEN - CALL WrScr( ErrMsg ) - STOP - END IF - - - ! Initialize the module Interval = drvrInitInp%TimeInterval CALL HydroDyn_Init( InitInData, u(1), p, x, xd, z, OtherState, y, m, Interval, InitOutData, ErrStat, ErrMsg ) @@ -361,158 +326,198 @@ PROGRAM HydroDynDriver CALL HydroDyn_DestroyInitInput( InitInData, ErrStat, ErrMsg ) CALL HydroDyn_DestroyInitOutput( InitOutData, ErrStat, ErrMsg ) + + ! Create Mesh mappings + if ( u(1)%WAMITMesh%Initialized ) then + ! Create mesh mappings between (0,0,0) reference point mesh and the WAMIT body(ies) mesh [ 1 node per body ] + CALL MeshMapCreate( u(1)%PRPMesh, u(1)%WAMITMesh, HD_Ref_2_WB_P, ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'HydroDynDriver') + if (errStat >= AbortErrLev) then + ! Clean up and exit + call HD_DvrCleanup() + end if + endif + if ( u(1)%Morison%Mesh%Initialized ) then + ! Create mesh mappings between (0,0,0) reference point mesh and the Morison mesh + CALL MeshMapCreate( u(1)%PRPMesh, u(1)%Morison%Mesh, HD_Ref_2_M_P, ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'HydroDynDriver') + if (errStat >= AbortErrLev) then + ! Clean up and exit + call HD_DvrCleanup() + end if + endif + - ! Set any steady-state inputs, once before the time-stepping loop - IF ( u(1)%Mesh%Initialized ) THEN + ! Set any steady-state inputs, once before the time-stepping loop - IF ( drvrInitInp%WAMITInputsMod /= 2 ) THEN + IF (( drvrInitInp%PRPInputsMod /= 2 ) .AND. ( drvrInitInp%PRPInputsMod >= 0 )) THEN + + u(1)%PRPMesh%TranslationDisp(:,1) = drvrInitInp%uPRPInSteady(1:3) + + ! Compute direction cosine matrix from the rotation angles + CALL SmllRotTrans( 'InputRotation', REAL(drvrInitInp%uPRPInSteady(4), ReKi), REAL(drvrInitInp%uPRPInSteady(5), ReKi), REAL(drvrInitInp%uPRPInSteady(6), ReKi), dcm, 'Junk', ErrStat, ErrMsg ) + u(1)%PRPMesh%Orientation(:,:,1) = dcm + + u(1)%PRPMesh%TranslationVel(:,1) = drvrInitInp%uDotPRPInSteady(1:3) + u(1)%PRPMesh%RotationVel(:,1) = drvrInitInp%uDotPRPInSteady(4:6) + u(1)%PRPMesh%TranslationAcc(:,1) = drvrInitInp%uDotDotPRPInSteady(1:3) + u(1)%PRPMesh%RotationAcc(:,1) = drvrInitInp%uDotDotPRPInSteady(4:6) + IF ( u(1)%WAMITMesh%Initialized ) THEN - u(1)%Mesh%TranslationDisp(:,1) = drvrInitInp%uWAMITInSteady(1:3) - - - ! Compute direction cosine matrix from the rotation angles - CALL SmllRotTrans( 'InputRotation', REAL(drvrInitInp%uWAMITInSteady(4), ReKi), REAL(drvrInitInp%uWAMITInSteady(5), ReKi), REAL(drvrInitInp%uWAMITInSteady(6), ReKi), dcm, 'Junk', ErrStat, ErrMsg ) - u(1)%Mesh%Orientation(:,:,1) = dcm - - u(1)%Mesh%TranslationVel(:,1) = drvrInitInp%uDotWAMITInSteady(1:3) - u(1)%Mesh%RotationVel(:,1) = drvrInitInp%uDotWAMITInSteady(4:6) - u(1)%Mesh%TranslationAcc(:,1) = drvrInitInp%uDotDotWAMITInSteady(1:3) - u(1)%Mesh%RotationAcc(:,1) = drvrInitInp%uDotDotWAMITInSteady(4:6) - - END IF - END IF - - - IF ( drvrInitInp%MorisonInputsMod /= 2 ) THEN - IF ( u(1)%Morison%DistribMesh%Initialized ) THEN - u(1)%Morison%DistribMesh%TranslationDisp(1,:) = drvrInitInp%uMorisonInSteady(1) - u(1)%Morison%DistribMesh%TranslationDisp(2,:) = drvrInitInp%uMorisonInSteady(2) - u(1)%Morison%DistribMesh%TranslationDisp(3,:) = drvrInitInp%uMorisonInSteady(3) - - ! Compute direction cosine matrix from the rotation angles - CALL SmllRotTrans( 'InputRotation', REAL(drvrInitInp%uMorisonInSteady(4),ReKi), REAL(drvrInitInp%uMorisonInSteady(5),ReKi), REAL(drvrInitInp%uMorisonInSteady(6),ReKi), dcm, 'Junk', ErrStat, ErrMsg ) - DO I = 1, u(1)%Morison%DistribMesh%nNodes - u(1)%Morison%DistribMesh%Orientation(:,:,I) = dcm - END DO + ! Map PRP kinematics to the WAMIT mesh with 1 to NBody nodes + CALL Transfer_Point_to_Point( u(1)%PRPMesh, u(1)%WAMITMesh, HD_Ref_2_WB_P, ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'HydroDynDriver') + if (errStat >= AbortErrLev) then + ! Clean up and exit + call HD_DvrCleanup() + end if - u(1)%Morison%DistribMesh%TranslationVel(1,:) = drvrInitInp%uDotMorisonInSteady(1) - u(1)%Morison%DistribMesh%TranslationVel(2,:) = drvrInitInp%uDotMorisonInSteady(2) - u(1)%Morison%DistribMesh%TranslationVel(3,:) = drvrInitInp%uDotMorisonInSteady(3) - u(1)%Morison%DistribMesh%RotationVel(1,:) = drvrInitInp%uDotMorisonInSteady(4) - u(1)%Morison%DistribMesh%RotationVel(2,:) = drvrInitInp%uDotMorisonInSteady(5) - u(1)%Morison%DistribMesh%RotationVel(3,:) = drvrInitInp%uDotMorisonInSteady(6) - u(1)%Morison%DistribMesh%TranslationAcc(1,:) = drvrInitInp%uDotDotMorisonInSteady(1) - u(1)%Morison%DistribMesh%TranslationAcc(2,:) = drvrInitInp%uDotDotMorisonInSteady(2) - u(1)%Morison%DistribMesh%TranslationAcc(3,:) = drvrInitInp%uDotDotMorisonInSteady(3) - u(1)%Morison%DistribMesh%RotationAcc(1,:) = drvrInitInp%uDotDotMorisonInSteady(4) - u(1)%Morison%DistribMesh%RotationAcc(2,:) = drvrInitInp%uDotDotMorisonInSteady(5) - u(1)%Morison%DistribMesh%RotationAcc(3,:) = drvrInitInp%uDotDotMorisonInSteady(6) - END IF - IF ( u(1)%Morison%LumpedMesh%Initialized ) THEN - DO I = 1, u(1)%Morison%LumpedMesh%nNodes - u(1)%Morison%LumpedMesh%Orientation(:,:,I) = dcm - END DO - u(1)%Morison%LumpedMesh%TranslationVel(1,:) = drvrInitInp%uDotMorisonInSteady(1) - u(1)%Morison%LumpedMesh%TranslationVel(2,:) = drvrInitInp%uDotMorisonInSteady(2) - u(1)%Morison%LumpedMesh%TranslationVel(3,:) = drvrInitInp%uDotMorisonInSteady(3) - u(1)%Morison%LumpedMesh%RotationVel(1,:) = drvrInitInp%uDotMorisonInSteady(4) - u(1)%Morison%LumpedMesh%RotationVel(2,:) = drvrInitInp%uDotMorisonInSteady(5) - u(1)%Morison%LumpedMesh%RotationVel(3,:) = drvrInitInp%uDotMorisonInSteady(6) - u(1)%Morison%LumpedMesh%TranslationAcc(1,:) = drvrInitInp%uDotDotMorisonInSteady(1) - u(1)%Morison%LumpedMesh%TranslationAcc(2,:) = drvrInitInp%uDotDotMorisonInSteady(2) - u(1)%Morison%LumpedMesh%TranslationAcc(3,:) = drvrInitInp%uDotDotMorisonInSteady(3) - u(1)%Morison%LumpedMesh%RotationAcc(1,:) = drvrInitInp%uDotDotMorisonInSteady(4) - u(1)%Morison%LumpedMesh%RotationAcc(2,:) = drvrInitInp%uDotDotMorisonInSteady(5) - u(1)%Morison%LumpedMesh%RotationAcc(3,:) = drvrInitInp%uDotDotMorisonInSteady(6) + END IF ! u(1)%WAMITMesh%Initialized + + if ( u(1)%Morison%Mesh%Initialized ) then - END IF + ! Map PRP kinematics to the Morison mesh + CALL Transfer_Point_to_Point( u(1)%PRPMesh, u(1)%Morison%Mesh, HD_Ref_2_M_P, ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'HydroDynDriver') + if (errStat >= AbortErrLev) then + ! Clean up and exit + call HD_DvrCleanup() + end if + end if ! u(1)%Morison%Mesh%Initialized + END IF - ! Setup mesh mapping for Morison motion - IF ( drvrInitInp%MorisonInputsMod == 2 ) THEN - IF ( u(1)%Morison%DistribMesh%Initialized ) THEN - ! create mapping from PMesh (used for WAMIT mesh among others) to Morison. This will be used to map the motions for Morison timeseries inputs - CALL MeshMapCreate( PMesh, u(1)%Morison%DistribMesh, Map_P_to_MorisonDist, ErrStat, ErrMsg ) - if (errStat >= AbortErrLev) call HD_DvrCleanup() - ENDIF - IF ( u(1)%Morison%LumpedMesh%Initialized ) THEN - ! create mapping from PMesh (used for WAMIT mesh among others) to Morison. This will be used to map the motions for Morison timeseries inputs - CALL MeshMapCreate( PMesh, u(1)%Morison%LumpedMesh, Map_P_to_MorisonLumped, ErrStat, ErrMsg ) - if (errStat >= AbortErrLev) call HD_DvrCleanup() - ENDIF - ENDIF - + !............................................................................................................................... ! Routines called in loose coupling -- the glue code may implement this in various ways !............................................................................................................................... Time = 0.0 CALL SimStatus_FirstTime( TiLstPrn, PrevClockTime, SimStrtTime, UsrTime2, time, InitInData%TMax ) + ! loop through time steps + maxAngle = 0.0 + DO n = 1, drvrInitInp%NSteps Time = (n-1) * drvrInitInp%TimeInterval InputTime(1) = Time ! Modify u (likely from the outputs of another module or a set of test conditions) here: - - IF ( u(1)%Mesh%Initialized ) THEN - - IF ( drvrInitInp%WAMITInputsMod == 2 ) THEN - - - u(1)%Mesh%TranslationDisp(:,1) = WAMITin(n,2:4) + + ! PRPInputsMod 2: Reads time series of positions, velocities, and accelerations for the platform reference point + IF ( drvrInitInp%PRPInputsMod == 2 ) THEN + + u(1)%PRPMesh%TranslationDisp(:,1) = PRPin(n,2:4) + + ! Compute direction cosine matrix from the rotation angles + + IF ( abs(PRPin(n,5)) > maxAngle ) maxAngle = abs(PRPin(n,5)) + IF ( abs(PRPin(n,6)) > maxAngle ) maxAngle = abs(PRPin(n,6)) + IF ( abs(PRPin(n,7)) > maxAngle ) maxAngle = abs(PRPin(n,7)) + CALL SmllRotTrans( 'InputRotation', REAL(PRPin(n,5),ReKi), REAL(PRPin(n,6),ReKi), REAL(PRPin(n,7),ReKi), dcm, 'Junk', ErrStat, ErrMsg ) + u(1)%PRPMesh%Orientation(:,:,1) = dcm + u(1)%PRPMesh%TranslationVel(:,1) = PRPin(n,8:10) + u(1)%PRPMesh%RotationVel(:,1) = PRPin(n,11:13) + u(1)%PRPMesh%TranslationAcc(:,1) = PRPin(n,14:16) + u(1)%PRPMesh%RotationAcc(:,1) = PRPin(n,17:19) - ! Compute direction cosine matrix from the rotation angles + IF ( u(1)%WAMITMesh%Initialized ) THEN + ! Map kinematics to the WAMIT mesh with 1 to NBody nodes + CALL Transfer_Point_to_Point( u(1)%PRPMesh, u(1)%WAMITMesh, HD_Ref_2_WB_P, ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'HydroDynDriver') + if (errStat >= AbortErrLev) then + ! Clean up and exit + call HD_DvrCleanup() + end if + END IF + + IF ( u(1)%Morison%Mesh%Initialized ) THEN + ! Map kinematics to the WAMIT mesh with 1 to NBody nodes + CALL Transfer_Point_to_Point( u(1)%PRPMesh, u(1)%Morison%Mesh, HD_Ref_2_M_P, ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'HydroDynDriver') + if (errStat >= AbortErrLev) then + ! Clean up and exit + call HD_DvrCleanup() + end if + END IF + + end if + + !@mhall: new kinematics input for moving bodies individually + ! PRPInputsMod < 0: Reads time series of positions for each body individually, and uses finite differences to also get velocities and accelerations. + ! The number of bodies is the negative of PRPInputsMod. + IF ( drvrInitInp%PRPInputsMod < 0 ) THEN - IF ( abs(WAMITin(n,5)) > maxAngle ) maxAngle = abs(WAMITin(n,5)) - IF ( abs(WAMITin(n,6)) > maxAngle ) maxAngle = abs(WAMITin(n,6)) - IF ( abs(WAMITin(n,7)) > maxAngle ) maxAngle = abs(WAMITin(n,7)) + ! platform reference point (PRP), and body 1-NBody displacements + u(1)%PRPMesh%TranslationDisp(:,1) = PRPin(n,2:4) + DO I=1,NBody + u(1)%WAMITMesh%TranslationDisp(:,I) = PRPin(n, 6*I+2:6*I+4) + END DO + + ! PRP and body 1-NBody orientations (skipping the maxAngle stuff) + CALL SmllRotTrans( 'InputRotation', REAL(PRPin(n,5),ReKi), REAL(PRPin(n,6),ReKi), REAL(PRPin(n,7),ReKi), dcm, 'PRP orientation', ErrStat, ErrMsg ) + u(1)%PRPMesh%Orientation(:,:,1) = dcm + DO I=1, NBody + CALL SmllRotTrans( 'InputRotation', REAL(PRPin(n,6*I+5),ReKi), REAL(PRPin(n,6*I+6),ReKi), REAL(PRPin(n,6*I+7),ReKi), dcm, 'body orientation', ErrStat, ErrMsg ) + u(1)%PRPMesh%Orientation(:,:,1) = dcm + END DO + + ! use finite differences for velocities and accelerations + IF (n == 1) THEN ! use forward differences for first time step - CALL SmllRotTrans( 'InputRotation', REAL(WAMITin(n,5),ReKi), REAL(WAMITin(n,6),ReKi), REAL(WAMITin(n,7),ReKi), dcm, 'Junk', ErrStat, ErrMsg ) - u(1)%Mesh%Orientation(:,:,1) = dcm + u(1)%PRPMesh%TranslationVel(:,1) = (PRPin(n+1, 2:4) - PRPin(n , 2:4))/drvrInitInp%TimeInterval + u(1)%PRPMesh%RotationVel( :,1) = (PRPin(n+1, 5:7) - PRPin(n , 5:7))/drvrInitInp%TimeInterval + u(1)%PRPMesh%TranslationAcc(:,1) = (PRPin(n+2, 2:4) - 2*PRPin(n+1, 2:4) + PRPin(n, 2:4))/(drvrInitInp%TimeInterval*drvrInitInp%TimeInterval) + u(1)%PRPMesh%RotationAcc( :,1) = (PRPin(n+2, 5:7) - 2*PRPin(n+1, 5:7) + PRPin(n, 5:7))/(drvrInitInp%TimeInterval*drvrInitInp%TimeInterval) + + DO I=1,NBody + u(1)%WAMITMesh%TranslationVel(:,I) = (PRPin(n+1, 6*I+2:6*I+4) - PRPin(n , 6*I+2:6*I+4))/drvrInitInp%TimeInterval + u(1)%WAMITMesh%RotationVel( :,I) = (PRPin(n+1, 6*I+5:6*I+7) - PRPin(n , 6*I+5:6*I+7))/drvrInitInp%TimeInterval + u(1)%WAMITMesh%TranslationAcc(:,I) = (PRPin(n+2, 6*I+2:6*I+4) - 2*PRPin(n+1, 6*I+2:6*I+4) + PRPin(n, 6*I+2:6*I+4))/(drvrInitInp%TimeInterval*drvrInitInp%TimeInterval) + u(1)%WAMITMesh%RotationAcc( :,I) = (PRPin(n+2, 6*I+5:6*I+7) - 2*PRPin(n+1, 6*I+5:6*I+7) + PRPin(n, 6*I+5:6*I+7))/(drvrInitInp%TimeInterval*drvrInitInp%TimeInterval) + END DO + + ELSE IF (n == drvrInitInp%NSteps) THEN ! use backward differences for last time step + u(1)%PRPMesh%TranslationVel(:,1) = (PRPin(n, 2:4) - PRPin(n-1, 2:4))/drvrInitInp%TimeInterval + u(1)%PRPMesh%RotationVel( :,1) = (PRPin(n, 5:7) - PRPin(n-1, 5:7))/drvrInitInp%TimeInterval + u(1)%PRPMesh%TranslationAcc(:,1) = (PRPin(n, 2:4) - 2*PRPin(n-1, 2:4) + PRPin(n-2, 2:4))/(drvrInitInp%TimeInterval*drvrInitInp%TimeInterval) + u(1)%PRPMesh%RotationAcc( :,1) = (PRPin(n, 5:7) - 2*PRPin(n-1, 5:7) + PRPin(n-2, 5:7))/(drvrInitInp%TimeInterval*drvrInitInp%TimeInterval) + + DO I=1,NBody + u(1)%WAMITMesh%TranslationVel(:,I) = (PRPin(n, 6*I+2:6*I+4) - PRPin(n-1, 6*I+2:6*I+4))/drvrInitInp%TimeInterval + u(1)%WAMITMesh%RotationVel( :,I) = (PRPin(n, 6*I+5:6*I+7) - PRPin(n-1, 6*I+5:6*I+7))/drvrInitInp%TimeInterval + u(1)%WAMITMesh%TranslationAcc(:,I) = (PRPin(n, 6*I+2:6*I+4) - 2*PRPin(n-1, 6*I+2:6*I+4) + PRPin(n-2, 6*I+2:6*I+4))/(drvrInitInp%TimeInterval*drvrInitInp%TimeInterval) + u(1)%WAMITMesh%RotationAcc( :,I) = (PRPin(n, 6*I+5:6*I+7) - 2*PRPin(n-1, 6*I+5:6*I+7) + PRPin(n-2, 6*I+5:6*I+7))/(drvrInitInp%TimeInterval*drvrInitInp%TimeInterval) + END DO - u(1)%Mesh%TranslationVel(:,1) = WAMITin(n,8:10) - u(1)%Mesh%RotationVel(:,1) = WAMITin(n,11:13) - u(1)%Mesh%TranslationAcc(:,1) = WAMITin(n,14:16) - u(1)%Mesh%RotationAcc(:,1) = WAMITin(n,17:19) + ELSE ! otherwise use central differences for intermediate time steps + + u(1)%PRPMesh%TranslationVel(:,1) = (PRPin(n+1, 2:4) - PRPin(n-1, 2:4))*0.5/drvrInitInp%TimeInterval + u(1)%PRPMesh%RotationVel( :,1) = (PRPin(n+1, 5:7) - PRPin(n-1, 5:7))*0.5/drvrInitInp%TimeInterval + u(1)%PRPMesh%TranslationAcc(:,1) = (PRPin(n+1, 2:4) - 2*PRPin(n, 2:4) + PRPin(n-1, 2:4))/(drvrInitInp%TimeInterval*drvrInitInp%TimeInterval) + u(1)%PRPMesh%RotationAcc( :,1) = (PRPin(n+1, 5:7) - 2*PRPin(n, 5:7) + PRPin(n-1, 5:7))/(drvrInitInp%TimeInterval*drvrInitInp%TimeInterval) + + DO I=1,NBody + u(1)%WAMITMesh%TranslationVel(:,I) = (PRPin(n+1, 6*I+2:6*I+4) - PRPin(n-1, 6*I+2:6*I+4))*0.5/drvrInitInp%TimeInterval + u(1)%WAMITMesh%RotationVel( :,I) = (PRPin(n+1, 6*I+5:6*I+7) - PRPin(n-1, 6*I+5:6*I+7))*0.5/drvrInitInp%TimeInterval + u(1)%WAMITMesh%TranslationAcc(:,I) = (PRPin(n+1, 6*I+2:6*I+4) - 2*PRPin(n, 6*I+2:6*I+4) + PRPin(n-1, 6*I+2:6*I+4))/(drvrInitInp%TimeInterval*drvrInitInp%TimeInterval) + u(1)%WAMITMesh%RotationAcc( :,I) = (PRPin(n+1, 6*I+5:6*I+7) - 2*PRPin(n, 6*I+5:6*I+7) + PRPin(n-1, 6*I+5:6*I+7))/(drvrInitInp%TimeInterval*drvrInitInp%TimeInterval) + END DO + + END IF + IF ( u(1)%Morison%Mesh%Initialized ) THEN + ! Map kinematics to the WAMIT mesh with 1 to NBody nodes + CALL Transfer_Point_to_Point( u(1)%PRPMesh, u(1)%Morison%Mesh, HD_Ref_2_M_P, ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'HydroDynDriver') + if (errStat >= AbortErrLev) then + ! Clean up and exit + call HD_DvrCleanup() + end if + END IF + END IF - - END IF - - - IF ( drvrInitInp%MorisonInputsMod == 2 ) THEN - ! Set the Morison Inputs from a time series input file - PMesh%TranslationDisp(:,1) = MorisonIn(n,2:4) - - ! Compute direction cosine matrix from the rotation angles - IF ( abs(MorisonIn(n,5)) > maxAngle ) maxAngle = abs(MorisonIn(n,5)) - IF ( abs(MorisonIn(n,6)) > maxAngle ) maxAngle = abs(MorisonIn(n,6)) - IF ( abs(MorisonIn(n,7)) > maxAngle ) maxAngle = abs(MorisonIn(n,7)) - - CALL SmllRotTrans( 'InputRotation', REAL(MorisonIn(n,5),ReKi), REAL(MorisonIn(n,6),ReKi), REAL(MorisonIn(n,7),ReKi), dcm, 'Junk', ErrStat, ErrMsg ) - PMesh%Orientation(:,:,1) = dcm - - PMesh%TranslationVel(:,1) = MorisonIn(n,8:10) - PMesh%RotationVel(:,1) = MorisonIn(n,11:13) - PMesh%TranslationAcc(:,1) = MorisonIn(n,14:16) - PMesh%RotationAcc(:,1) = MorisonIn(n,17:19) - - IF ( u(1)%Morison%DistribMesh%Initialized ) THEN - CALL Transfer_Point_to_Line2( PMesh, u(1)%Morison%DistribMesh, Map_P_to_MorisonDist, ErrStat, ErrMsg ) - if (errStat >= AbortErrLev) call HD_DvrCleanup() - END IF - IF ( u(1)%Morison%LumpedMesh%Initialized ) THEN - CALL Transfer_Point_to_Point( PMesh, u(1)%Morison%LumpedMesh, Map_P_to_MorisonLumped, ErrStat, ErrMsg ) - if (errStat >= AbortErrLev) call HD_DvrCleanup() - END IF - END IF - + !@mhall: end of addition + + ! Calculate outputs at n CALL HydroDyn_CalcOutput( Time, u(1), p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) @@ -649,7 +654,10 @@ SUBROUTINE ReadDriverInputFile( inputFile, InitInp, ErrStat, ErrMsg ) CALL GetNewUnit( UnIn ) CALL OpenFInpFile ( UnIn, FileName, ErrStat, ErrMsg ) - IF (ErrStat >=AbortErrLev) RETURN + IF (ErrStat >=AbortErrLev) THEN + call WrScr( ErrMsg ) + STOP + ENDIF CALL WrScr( 'Opening HydroDyn Driver input file: '//FileName ) @@ -857,12 +865,12 @@ SUBROUTINE ReadDriverInputFile( inputFile, InitInp, ErrStat, ErrMsg ) !------------------------------------------------------------------------------------------------- - ! WAMIT INPUTS section + ! PRP INPUTS section !------------------------------------------------------------------------------------------------- ! Header - CALL ReadCom( UnIn, FileName, 'WAMIT INPUTS header', ErrStat, ErrMsg, UnEchoLocal ) + CALL ReadCom( UnIn, FileName, 'PRP INPUTS header', ErrStat, ErrMsg, UnEchoLocal ) IF ( ErrStat /= ErrID_None ) THEN ErrMsg = ' Failed to read Comment line.' @@ -874,13 +882,13 @@ SUBROUTINE ReadDriverInputFile( inputFile, InitInp, ErrStat, ErrMsg ) - ! WAMITInputsMod + ! PRPInputsMod - CALL ReadVar ( UnIn, FileName, InitInp%WAMITInputsMod, 'WAMITInputsMod', & - 'Model for the WAMIT inputs', ErrStat, ErrMsg, UnEchoLocal ) + CALL ReadVar ( UnIn, FileName, InitInp%PRPInputsMod, 'PRPInputsMod', & + 'Model for the PRP (principal reference point) inputs', ErrStat, ErrMsg, UnEchoLocal ) IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read WAMITInputsMod parameter.' + ErrMsg = ' Failed to read PRPInputsMod parameter.' ErrStat = ErrID_Fatal CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) CLOSE( UnIn ) @@ -888,13 +896,13 @@ SUBROUTINE ReadDriverInputFile( inputFile, InitInp, ErrStat, ErrMsg ) END IF - ! WAMITInputsFile + ! PRPInputsFile - CALL ReadVar ( UnIn, FileName, InitInp%WAMITInputsFile, 'WAMITInputsFile', & - 'Filename for the HydroDyn inputs', ErrStat, ErrMsg, UnEchoLocal ) + CALL ReadVar ( UnIn, FileName, InitInp%PRPInputsFile, 'PRPInputsFile', & + 'Filename for the PRP HydroDyn inputs', ErrStat, ErrMsg, UnEchoLocal ) IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read WAMITInputsFile parameter.' + ErrMsg = ' Failed to read PRPInputsFile parameter.' ErrStat = ErrID_Fatal CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) CLOSE( UnIn ) @@ -903,12 +911,12 @@ SUBROUTINE ReadDriverInputFile( inputFile, InitInp, ErrStat, ErrMsg ) !------------------------------------------------------------------------------------------------- - ! WAMIT STEADY STATE INPUTS section + ! PRP STEADY STATE INPUTS section !------------------------------------------------------------------------------------------------- ! Header - CALL ReadCom( UnIn, FileName, 'WAMIT STEADY STATE INPUTS header', ErrStat, ErrMsg, UnEchoLocal ) + CALL ReadCom( UnIn, FileName, 'PRP STEADY STATE INPUTS header', ErrStat, ErrMsg, UnEchoLocal ) IF ( ErrStat /= ErrID_None ) THEN ErrMsg = ' Failed to read Comment line.' @@ -920,13 +928,13 @@ SUBROUTINE ReadDriverInputFile( inputFile, InitInp, ErrStat, ErrMsg ) - ! uWAMITInSteady + ! uPRPInSteady - CALL ReadAry ( UnIn, FileName, InitInp%uWAMITInSteady, 6, 'uWAMITInSteady', & - 'WAMIT Steady-state displacements and rotations.', ErrStat, ErrMsg, UnEchoLocal) + CALL ReadAry ( UnIn, FileName, InitInp%uPRPInSteady, 6, 'uPRPInSteady', & + 'PRP Steady-state displacements and rotations.', ErrStat, ErrMsg, UnEchoLocal) IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read uWAMITInSteady parameter.' + ErrMsg = ' Failed to read uPRPInSteady parameter.' ErrStat = ErrID_Fatal CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) CLOSE( UnIn ) @@ -934,13 +942,13 @@ SUBROUTINE ReadDriverInputFile( inputFile, InitInp, ErrStat, ErrMsg ) END IF - ! uDotWAMITInSteady + ! uDotPRPInSteady - CALL ReadAry ( UnIn, FileName, InitInp%uDotWAMITInSteady, 6, 'uDotWAMITInSteady', & - 'WAMIT Steady-state translational and rotational velocities.', ErrStat, ErrMsg, UnEchoLocal) + CALL ReadAry ( UnIn, FileName, InitInp%uDotPRPInSteady, 6, 'uDotPRPInSteady', & + 'PRP Steady-state translational and rotational velocities.', ErrStat, ErrMsg, UnEchoLocal) IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read uDotWAMITInSteady parameter.' + ErrMsg = ' Failed to read uDotPRPInSteady parameter.' ErrStat = ErrID_Fatal CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) CLOSE( UnIn ) @@ -948,138 +956,26 @@ SUBROUTINE ReadDriverInputFile( inputFile, InitInp, ErrStat, ErrMsg ) END IF - ! uDotDotWAMITInSteady + ! uDotDotPRPInSteady - CALL ReadAry ( UnIn, FileName, InitInp%uDotDotWAMITInSteady, 6, 'uDotDotWAMITInSteady', & - 'WAMIT Steady-state translational and rotational accelerations.', ErrStat, ErrMsg, UnEchoLocal) + CALL ReadAry ( UnIn, FileName, InitInp%uDotDotPRPInSteady, 6, 'uDotDotPRPInSteady', & + 'PRP Steady-state translational and rotational accelerations.', ErrStat, ErrMsg, UnEchoLocal) IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read uDotDotWAMITInSteady parameter.' + ErrMsg = ' Failed to read uDotDotPRPInSteady parameter.' ErrStat = ErrID_Fatal CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) CLOSE( UnIn ) RETURN END IF - IF ( InitInp%WAMITInputsMod /= 1 ) THEN - InitInp%uWAMITInSteady = 0.0 - InitInp%uDotWAMITInSteady = 0.0 - InitInp%uDotDotWAMITInSteady = 0.0 - END IF - - - !------------------------------------------------------------------------------------------------- - ! Morison INPUTS section - !------------------------------------------------------------------------------------------------- - - ! Header - - CALL ReadCom( UnIn, FileName, 'Morison INPUTS header', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read Comment line.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - - ! MorisonInputsMod - - CALL ReadVar ( UnIn, FileName, InitInp%MorisonInputsMod, 'MorisonInputsMod', & - 'Model for the Morison inputs', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read MorisonInputsMod parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - ! MorisonInputsFile - - CALL ReadVar ( UnIn, FileName, InitInp%MorisonInputsFile, 'MorisonInputsFile', & - 'Filename for the HydroDyn inputs', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read MorisonInputsFile parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - !------------------------------------------------------------------------------------------------- - ! Morison STEADY STATE INPUTS section - !------------------------------------------------------------------------------------------------- - - ! Header - - CALL ReadCom( UnIn, FileName, 'Morison STEADY STATE INPUTS header', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read Comment line.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN + IF ( InitInp%PRPInputsMod /= 1 ) THEN + InitInp%uPRPInSteady = 0.0 + InitInp%uDotPRPInSteady = 0.0 + InitInp%uDotDotPRPInSteady = 0.0 END IF - - ! uMorisonInSteady - - CALL ReadAry ( UnIn, FileName, InitInp%uMorisonInSteady, 6, 'uMorisonInSteady', & - 'Morison Steady-state displacements and rotations.', ErrStat, ErrMsg, UnEchoLocal) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read uMorisonInSteady parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - ! uDotMorisonInSteady - - CALL ReadAry ( UnIn, FileName, InitInp%uDotMorisonInSteady, 6, 'uDotMorisonInSteady', & - 'Morison Steady-state translational and rotational velocities.', ErrStat, ErrMsg, UnEchoLocal) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read uDotMorisonInSteady parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - ! uDotDotMorisonInSteady - - CALL ReadAry ( UnIn, FileName, InitInp%uDotDotMorisonInSteady, 6, 'uDotDotMorisonInSteady', & - 'Morison Steady-state translational and rotational accelerations.', ErrStat, ErrMsg, UnEchoLocal) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read uDotDotMorisonInSteady parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - IF ( InitInp%MorisonInputsMod /= 1 ) THEN - InitInp%uMorisonInSteady = 0.0 - InitInp%uDotMorisonInSteady = 0.0 - InitInp%uDotDotMorisonInSteady = 0.0 - END IF - - !------------------------------------------------------------------------------------------------- !> ### Waves elevation series section !------------------------------------------------------------------------------------------------- @@ -1234,19 +1130,6 @@ SUBROUTINE WaveElevGrid_Output (drvrInitInp, HDynInitInp, HDynInitOut, HDyn_p, E CLOSE (WaveElevFileUn) END SUBROUTINE WaveElevGrid_Output - - - -subroutine print_help() - print '(a)', 'usage: ' - print '(a)', '' - print '(a)', 'HydroDyn.exe driverfilename' - print '(a)', '' - print '(a)', 'Where driverfilename is the name of the HydroDyn driver input file.' - print '(a)', '' - -end subroutine print_help - !---------------------------------------------------------------------------------------------------------------------------------- diff --git a/modules/hydrodyn/src/HydroDyn_Input.f90 b/modules/hydrodyn/src/HydroDyn_Input.f90 index 025e7e3226..b4eb4cba5b 100644 --- a/modules/hydrodyn/src/HydroDyn_Input.f90 +++ b/modules/hydrodyn/src/HydroDyn_Input.f90 @@ -25,10 +25,8 @@ MODULE HydroDyn_Input USE HydroDyn_Types USE HydroDyn_Output USE Waves - USE Morison - USE WAMIT_Output - USE WAMIT2_Output USE Waves2_Output + USE Morison USE Morison_Output USE NWTC_RandomNumber IMPLICIT NONE @@ -37,6 +35,66 @@ MODULE HydroDyn_Input PRIVATE :: CheckMeshOutput CONTAINS + +SUBROUTINE ReadFileList ( UnIn, Fil, CharAry, AryName, AryDescr, ErrStat, ErrMsg, UnEc ) + + ! Argument declarations: + + INTEGER, INTENT(IN) :: UnIn !< I/O unit for input file. + INTEGER, INTENT(IN) :: UnEc !< I/O unit for echo file (if > 0). + INTEGER, INTENT(OUT) :: ErrStat !< Error status + CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message + + CHARACTER(*), INTENT(INOUT) :: CharAry(:) !< Character array being read (calling routine dimensions it to max allowable size). + + CHARACTER(*), INTENT(IN) :: Fil !< Name of the input file. + CHARACTER(*), INTENT(IN) :: AryDescr !< Text string describing the variable. + CHARACTER(*), INTENT(IN) :: AryName !< Text string containing the variable name. + + + ! Local declarations: + + INTEGER :: MaxAryLen ! Maximum length of the array being read + INTEGER :: NumWords ! Number of words contained on a line + + CHARACTER(1000) :: OutLine ! Character string read from file, containing output list + CHARACTER(3) :: EndOfFile + + + ! Initialize some values + + ErrStat = ErrID_None + ErrMsg = '' + MaxAryLen = SIZE(CharAry) + + CharAry = '' + + ! Read the line containing output parameters and store them in CharAry(:). + + CALL ReadVar ( UnIn, Fil, OutLine, AryName, AryDescr, ErrStat, ErrMsg, UnEc ) + IF ( ErrStat >= AbortErrLev ) RETURN + + + NumWords = CountWords( OutLine ) ! The number of words in OutLine. + + + ! Check to see if we found the required number of words. + + IF ( NumWords < MaxAryLen ) THEN + + ErrStat = ErrID_Fatal + ErrMsg = 'ReadOutputList: Did not find the required number of Potfile strings on the input file line: only found '//TRIM( Int2LStr(NumWords) )//'.' + RETURN + + ELSE + + CALL GetWords ( OutLine, CharAry(1:NumWords), NumWords ) + + END IF + + RETURN + +END SUBROUTINE ReadFileList !==================================================================================================== FUNCTION CheckMeshOutput( output, numMemberOut, MOutLst, numJointOut ) @@ -201,23 +259,16 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) ! Local variables - INTEGER :: I ! generic integer for counting -! INTEGER :: J ! generic integer for counting + INTEGER :: I, j ! generic integer for counting CHARACTER( 2) :: strI ! string version of the loop counter - INTEGER :: UnIn ! Unit number for the input file -! LOGICAL :: EchoStore ! Stored version of NWTC_Library Echo variable -! INTEGER :: UnEchoStore ! Stored unit name for another module's echo file INTEGER :: UnEchoLocal ! The local unit number for this module's echo file CHARACTER(1024) :: EchoFile ! Name of HydroDyn echo file CHARACTER(1024) :: Line ! String to temporarially hold value of read line -! CHARACTER(1024) :: TmpPath ! Temporary storage for relative path name -! CHARACTER(1024) :: TmpFmt ! Temporary storage for format statement CHARACTER(1024) :: FileName ! Name of HydroDyn input file CHARACTER( 35) :: Frmt ! Output format for logical parameters. (matches NWTC Subroutine Library format) -! INTEGER :: JointID ! Temporary storage of JointID read from HydroDyn input file -! INTEGER :: PropSetID ! Temporary storage of PropSetID read from HydroDyn input file -! INTEGER :: MemberID ! Temporary storage of MemberID read from HydroDyn input file + real(ReKi), ALLOCATABLE :: tmpVec1(:), tmpVec2(:) ! Temporary arrays for WAMIT data + integer(IntKi) :: startIndx, endIndx ! indices into working arrays INTEGER, ALLOCATABLE :: tmpArray(:) ! Temporary array storage of the joint output list CHARACTER(1) :: Line1 ! The first character of an input line INTEGER(IntKi) :: ErrStat2 @@ -850,20 +901,22 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) RETURN END IF + ! ExctnMod - Wave Excitation model {0: None, 1: DFT, 2: state-space} (switch) + ! [STATE-SPACE REQUIRES *.ssexctn INPUT FILE] - ! PotFile - Root name of Potential flow data files (Could be WAMIT files or the FIT input file) - - CALL ReadVar ( UnIn, FileName, InitInp%PotFile, 'PotFile', 'Root name of Potential flow model files', ErrStat2, ErrMsg2, UnEchoLocal ) + CALL ReadVar ( UnIn, FileName, InitInp%WAMIT%ExctnMod, 'ExctnMod', & + 'Wave Excitation model', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() RETURN END IF + ! RdtnMod - Radiation memory-effect model {1: convolution, 2: state-space} (switch) + ! [STATE-SPACE REQUIRES *.ss INPUT FILE] - ! WAMITULEN - WAMIT characteristic body length scale - - CALL ReadVar ( UnIn, FileName, InitInp%WAMIT%WAMITULEN, 'WAMITULEN', 'WAMIT characteristic body length scale', ErrStat2, ErrMsg2, UnEchoLocal ) + CALL ReadVar ( UnIn, FileName, InitInp%WAMIT%RdtnMod, 'RdtnMod', & + 'Radiation memory-effect model', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() @@ -871,10 +924,12 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) END IF - ! PtfmVol0 - Displaced volume of water when the platform is in its undisplaced position + ! RdtnTMax - Analysis time for wave radiation kernel calculations + ! NOTE: Use RdtnTMax = 0.0 to eliminate wave radiation damping + + CALL ReadVar ( UnIn, FileName, InitInp%WAMIT%RdtnTMax, 'RdtnTMax', & + 'Analysis time for wave radiation kernel calculations', ErrStat2, ErrMsg2, UnEchoLocal ) - CALL ReadVar ( UnIn, FileName, InitInp%WAMIT%PtfmVol0, 'PtfmVol0', & - 'Displaced volume of water when the platform is in its undisplaced position', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() @@ -882,129 +937,128 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) END IF - ! PtfmCOBxt - The xt offset of the center of buoyancy (COB) from the WAMIT reference point + ! RdtnDT - Time step for wave radiation kernel calculations + + + CALL ReadVar ( UnIn, FileName, InitInp%WAMIT%Conv_Rdtn%RdtnDTChr, 'RdtnDT', 'Time step for wave radiation kernel calculations', ErrStat2, ErrMsg2, UnEchoLocal ) - CALL ReadVar ( UnIn, FileName, InitInp%WAMIT%PtfmCOBxt, 'PtfmCOBxt', & - 'xt offset of the center of buoyancy (COB) from the WAMIT reference point', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() RETURN END IF + ! NBody - Number of WAMIT bodies to be used (-) [>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data + ! contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there + ! are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6] - ! PtfmCOByt - The yt offset of the center of buoyancy (COB) from the WAMIT reference point - - CALL ReadVar ( UnIn, FileName, InitInp%WAMIT%PtfmCOByt, 'PtfmCOByt', & - 'yt offset of the center of buoyancy (COB) from the WAMIT reference point', ErrStat2, ErrMsg2, UnEchoLocal ) + CALL ReadVar ( UnIn, FileName, InitInp%NBody, 'NBody', 'Number of WAMIT bodies', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() RETURN END IF - ! ExctnMod - Wave Excitation model {0: None, 1: DFT, 2: state-space} (switch) - ! [STATE-SPACE REQUIRES *.ssexctn INPUT FILE] + ! NBodyMod - Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, + ! 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms + ! between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1] - CALL ReadVar ( UnIn, FileName, InitInp%WAMIT%ExctnMod, 'ExctnMod', & - 'Wave Excitation model', ErrStat2, ErrMsg2, UnEchoLocal ) + CALL ReadVar ( UnIn, FileName, InitInp%NBodyMod, 'NBodyMod', 'Body coupling model', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() RETURN END IF - ! RdtnMod - Radiation memory-effect model {1: convolution, 2: state-space} (switch) - ! [STATE-SPACE REQUIRES *.ss INPUT FILE] + ! PotFile - Root name of Potential flow data files (Could be WAMIT files or the FIT input file) + + ! allocate space for the WAMIT-related data arrays: + + if ( InitInp%NBodyMod == 1 ) then + InitInp%nWAMITObj = 1 ! Special case where all data in a single WAMIT input file as opposed to InitInp%NBody number of separate input files. + InitInp%vecMultiplier = InitInp%NBody + else + InitInp%nWAMITObj = InitInp%NBody + InitInp%vecMultiplier = 1 + end if + + CALL AllocAry( InitInp%PotFile , InitInp%nWAMITObj, 'PotFile' , ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL AllocAry( InitInp%WAMITULEN, InitInp%nWAMITObj, 'WAMITULEN' , ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL AllocAry( InitInp%PtfmRefxt, InitInp%NBody, 'PtfmRefxt' , ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL AllocAry( InitInp%PtfmRefyt, InitInp%NBody, 'PtfmRefyt' , ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL AllocAry( InitInp%PtfmRefzt, InitInp%NBody, 'PtfmRefzt' , ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL AllocAry( InitInp%PtfmRefztRot, InitInp%NBody, 'PtfmRefztRot' , ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL AllocAry( InitInp%PtfmVol0 , InitInp%NBody, 'PtfmVol0' , ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL AllocAry( InitInp%PtfmCOBxt, InitInp%NBody, 'PtfmCOBxt' , ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL AllocAry( InitInp%PtfmCOByt, InitInp%NBody, 'PtfmCOByt' , ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) - CALL ReadVar ( UnIn, FileName, InitInp%WAMIT%RdtnMod, 'RdtnMod', & - 'Radiation memory-effect model', ErrStat2, ErrMsg2, UnEchoLocal ) + IF (ErrStat >= AbortErrLev) THEN + CALL CleanUp() + RETURN + END IF + call ReadFileList ( UnIn, FileName, InitInp%PotFile, 'PotFile', 'Root name of Potential flow model files', ErrStat2, ErrMsg2, UnEchoLocal ) + !CALL ReadAry ( UnIn, FileName, InitInp%PotFile, InitInp%nWAMITObj, 'PotFile', 'Root name of Potential flow model files', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() RETURN END IF + ! WAMITULEN - WAMIT characteristic body length scale - ! RdtnTMax - Analysis time for wave radiation kernel calculations - ! NOTE: Use RdtnTMax = 0.0 to eliminate wave radiation damping - - CALL ReadVar ( UnIn, FileName, InitInp%WAMIT%RdtnTMax, 'RdtnTMax', & - 'Analysis time for wave radiation kernel calculations', ErrStat2, ErrMsg2, UnEchoLocal ) - + CALL ReadAry ( UnIn, FileName, InitInp%WAMITULEN, InitInp%nWAMITObj, 'WAMITULEN', 'WAMIT characteristic body length scale', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() RETURN END IF + ! PtfmRefxt - The xt offset of the body reference point(s) from (0,0,0) (meters) - ! RdtnDT - Time step for wave radiation kernel calculations - - - CALL ReadVar ( UnIn, FileName, InitInp%WAMIT%Conv_Rdtn%RdtnDTChr, 'RdtnDT', 'Time step for wave radiation kernel calculations', ErrStat2, ErrMsg2, UnEchoLocal ) - + CALL ReadAry ( UnIn, FileName, InitInp%PtfmRefxt, InitInp%NBody, 'PtfmRefxt', & + 'xt offset of the body reference point(s) from (0,0,0)', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() RETURN END IF - -!bjj: should we add this? -!test for numerical stability -! IF ( FP_InitData%RdtnDT <= FP_InitData%RdtnTMax*EPSILON(FP_InitData%RdtnDT) ) THEN ! Test RdtnDT and RdtnTMax to ensure numerical stability -- HINT: see the use of OnePlusEps." -! ErrMsg = ' RdtnDT must be greater than '//TRIM ( Num2LStr( RdtnTMax*EPSILON(RdtnDT) ) )//' seconds.' -! ErrStat = ErrID_Fatal -! CLOSE( UnIn ) -! RETURN -! END IF - - - - !------------------------------------------------------------------------------------------------- - ! Data section for 2nd order WAMIT forces - !------------------------------------------------------------------------------------------------- - - - ! Header - CALL ReadCom( UnIn, FileName, '2nd order forces header (WAMIT2 module)', ErrStat2, ErrMsg2, UnEchoLocal ) + ! PtfmRefyt - The yt offset of the body reference point(s) from (0,0,0) (meters) + CALL ReadAry ( UnIn, FileName, InitInp%PtfmRefyt, InitInp%NBody, 'PtfmRefyt', & + 'yt offset of the body reference point(s) from (0,0,0)', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() RETURN END IF + ! PtfmRefzt - The zt offset of the body reference point(s) from (0,0,0) (meters) - ! MnDrift -- Mean drift forces computed from WAMIT file: {0: No mean drift, [7, 8, 9, 10, 11, or 12]: WAMIT file to use} - - CALL ReadVar ( UnIn, FileName, InitInp%WAMIT2%MnDrift, 'MnDrift', 'Mean drift forces computed from WAMIT file: {0: No mean drift, [7, 8, 9, 10, 11, or 12]: WAMIT file to use}', ErrStat2, ErrMsg2, UnEchoLocal ) - + CALL ReadAry ( UnIn, FileName, InitInp%PtfmRefzt, InitInp%NBody, 'PtfmRefzt', & + 'zt offset of the body reference point(s) from (0,0,0)', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() RETURN END IF + ! PtfmRefztRot - The rotation about zt of the body reference frame(s) from xt/yt (deg) - ! NewmanApp -- Slow drift forces computed with Newman's approximation from WAMIT file: {0: No mean drift, [7, 8, 9, 10, 11, or 12]: WAMIT file to use} - - CALL ReadVar ( UnIn, FileName, InitInp%WAMIT2%NewmanApp, 'NewmanApp', 'Mean drift forces computed from WAMIT file: {0: No mean drift, [7, 8, 9, 10, 11, or 12]: WAMIT file to use}', ErrStat2, ErrMsg2, UnEchoLocal ) - + CALL ReadAry ( UnIn, FileName, InitInp%PtfmRefztRot, InitInp%NBody, 'PtfmRefzt', & + 'The rotation about zt of the body reference frame(s) from xt/yt', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() RETURN END IF + InitInp%PtfmRefztRot = InitInp%PtfmRefztRot*D2R_D ! Convert to radians + + ! PtfmVol0 - Displaced volume of water when the platform is in its undisplaced position - - ! DiffQTF -- Full Difference-Frequency forces computed with full QTFs from WAMIT file: {0: No difference-frequency forces, [10, 11, or 12]: WAMIT file to use} -- Only one of MnDrift, NewmanApp, or DiffQYT can be non-zero - - CALL ReadVar ( UnIn, FileName, InitInp%WAMIT2%DiffQTF, 'DiffQTF', 'Full Difference-Frequency forces computed with full QTFs from WAMIT file: '// & - '{0: No difference-frequency forces, [10, 11, or 12]: WAMIT file to use} -- Only one of MnDrift, NewmanApp, or DiffQYT can be non-zero', ErrStat2, ErrMsg2, UnEchoLocal ) - + CALL ReadAry ( UnIn, FileName, InitInp%PtfmVol0, InitInp%NBody, 'PtfmVol0', & + 'Displaced volume of water when the platform is in its undisplaced position', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() @@ -1012,10 +1066,10 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) END IF - ! SumQTF -- Full Sum-Frequency forces computed with full QTFs from WAMIT file: {0: No Sum-frequency forces, [10, 11, or 12]: WAMIT file to use} - - CALL ReadVar ( UnIn, FileName, InitInp%WAMIT2%SumQTF, 'SumQTF', 'Full Sum-Frequency forces computed with full QTFs from WAMIT file: {0: No Sum-frequency forces, [10, 11, or 12]: WAMIT file to use}', ErrStat2, ErrMsg2, UnEchoLocal ) + ! PtfmCOBxt - The xt offset of the center of buoyancy (COB) from the WAMIT reference point + CALL ReadAry ( UnIn, FileName, InitInp%PtfmCOBxt, InitInp%NBody, 'PtfmCOBxt', & + 'xt offset of the center of buoyancy (COB) from the WAMIT reference point', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() @@ -1023,15 +1077,10 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) END IF + ! PtfmCOByt - The yt offset of the center of buoyancy (COB) from the WAMIT reference point - !------------------------------------------------------------------------------------------------- - ! Data section for Floating platform force flags - !------------------------------------------------------------------------------------------------- - - ! Header - - CALL ReadCom( UnIn, FileName, 'Floating platform force flags header', ErrStat2, ErrMsg2, UnEchoLocal ) - + CALL ReadAry ( UnIn, FileName, InitInp%PtfmCOByt, InitInp%NBody, 'PtfmCOByt', & + 'yt offset of the center of buoyancy (COB) from the WAMIT reference point', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() @@ -1039,22 +1088,26 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) END IF - ! PtfmSgFChr - Platform horizontal surge translation force flag + +!bjj: should we add this? +!test for numerical stability +! IF ( FP_InitData%RdtnDT <= FP_InitData%RdtnTMax*EPSILON(FP_InitData%RdtnDT) ) THEN ! Test RdtnDT and RdtnTMax to ensure numerical stability -- HINT: see the use of OnePlusEps." +! ErrMsg = ' RdtnDT must be greater than '//TRIM ( Num2LStr( RdtnTMax*EPSILON(RdtnDT) ) )//' seconds.' +! ErrStat = ErrID_Fatal +! CLOSE( UnIn ) +! RETURN +! END IF - CALL ReadVar ( UnIn, FileName, InitInp%PtfmSgFChr, 'PtfmSgFChr', 'Platform horizontal surge translation force flag', ErrStat2, ErrMsg2, UnEchoLocal ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - END IF - CALL Conv2UC( InitInp%PtfmSgFChr ) ! Convert Line to upper case. + !------------------------------------------------------------------------------------------------- + ! Data section for 2nd order WAMIT forces + !------------------------------------------------------------------------------------------------- - ! PtfmSwFChr - Platform horizontal sway translation force flag + ! Header - CALL ReadVar ( UnIn, FileName, InitInp%PtfmSwFChr, 'PtfmSwFChr', 'Platform horizontal sway translation force flag', ErrStat2, ErrMsg2, UnEchoLocal ) + CALL ReadCom( UnIn, FileName, '2nd order forces header (WAMIT2 module)', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN @@ -1062,12 +1115,10 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) RETURN END IF - CALL Conv2UC( InitInp%PtfmSwFChr ) ! Convert Line to upper case. + ! MnDrift -- Mean drift forces computed from WAMIT file: {0: No mean drift, [7, 8, 9, 10, 11, or 12]: WAMIT file to use} - ! PtfmHvFChr - Platform vertical heave translation force flag - - CALL ReadVar ( UnIn, FileName, InitInp%PtfmHvFChr, 'PtfmHvFChr', 'Platform vertical heave translation force flag', ErrStat2, ErrMsg2, UnEchoLocal ) + CALL ReadVar ( UnIn, FileName, InitInp%WAMIT2%MnDrift, 'MnDrift', 'Mean drift forces computed from WAMIT file: {0: No mean drift, [7, 8, 9, 10, 11, or 12]: WAMIT file to use}', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN @@ -1075,12 +1126,10 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) RETURN END IF - CALL Conv2UC( InitInp%PtfmHvFChr ) ! Convert Line to upper case. + ! NewmanApp -- Slow drift forces computed with Newman's approximation from WAMIT file: {0: No mean drift, [7, 8, 9, 10, 11, or 12]: WAMIT file to use} - ! PtfmRFChr - Platform roll tilt rotation force flag - - CALL ReadVar ( UnIn, FileName, InitInp%PtfmRFChr, 'PtfmRFChr', 'Platform roll tilt rotation force flag', ErrStat2, ErrMsg2, UnEchoLocal ) + CALL ReadVar ( UnIn, FileName, InitInp%WAMIT2%NewmanApp, 'NewmanApp', 'Mean drift forces computed from WAMIT file: {0: No mean drift, [7, 8, 9, 10, 11, or 12]: WAMIT file to use}', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN @@ -1088,12 +1137,11 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) RETURN END IF - CALL Conv2UC( InitInp%PtfmRFChr ) ! Convert Line to upper case. - - ! PtfmPFChr - Platform pitch tilt rotation force flag + ! DiffQTF -- Full Difference-Frequency forces computed with full QTFs from WAMIT file: {0: No difference-frequency forces, [10, 11, or 12]: WAMIT file to use} -- Only one of MnDrift, NewmanApp, or DiffQYT can be non-zero - CALL ReadVar ( UnIn, FileName, InitInp%PtfmPFChr, 'PtfmPFChr', 'Platform pitch tilt rotation force flag', ErrStat2, ErrMsg2, UnEchoLocal ) + CALL ReadVar ( UnIn, FileName, InitInp%WAMIT2%DiffQTF, 'DiffQTF', 'Full Difference-Frequency forces computed with full QTFs from WAMIT file: '// & + '{0: No difference-frequency forces, [10, 11, or 12]: WAMIT file to use} -- Only one of MnDrift, NewmanApp, or DiffQYT can be non-zero', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN @@ -1101,12 +1149,10 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) RETURN END IF - CALL Conv2UC( InitInp%PtfmPFChr ) ! Convert Line to upper case. + ! SumQTF -- Full Sum-Frequency forces computed with full QTFs from WAMIT file: {0: No Sum-frequency forces, [10, 11, or 12]: WAMIT file to use} - ! PtfmYFChr - Platform yaw rotation force flag - - CALL ReadVar ( UnIn, FileName, InitInp%PtfmYFChr, 'PtfmYFChr', 'Platform yaw rotation force flag', ErrStat2, ErrMsg2, UnEchoLocal ) + CALL ReadVar ( UnIn, FileName, InitInp%WAMIT2%SumQTF, 'SumQTF', 'Full Sum-Frequency forces computed with full QTFs from WAMIT file: {0: No Sum-frequency forces, [10, 11, or 12]: WAMIT file to use}', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF (ErrStat >= AbortErrLev) THEN @@ -1114,16 +1160,21 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) RETURN END IF - CALL Conv2UC( InitInp%PtfmYFChr ) ! Convert Line to upper case. - !------------------------------------------------------------------------------------------------- ! Floating Platform Additional Stiffness and Damping Section !------------------------------------------------------------------------------------------------- + ! If NBodyMod = 1 then vecMultiplier = NBody and nWAMITObj = 1 + ! Else vecMultiplier = 1 and nWAMITObj = NBody + CALL AllocAry( InitInp%AddF0, InitInp%vecMultiplier*6, InitInp%nWAMITObj, 'InitInp%AddF0' , ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL AllocAry( InitInp%AddCLin, InitInp%vecMultiplier*6, InitInp%vecMultiplier*6, InitInp%nWAMITObj, 'InitInp%AddCLin' , ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL AllocAry( InitInp%AddBLin, InitInp%vecMultiplier*6, InitInp%vecMultiplier*6, InitInp%nWAMITObj, 'InitInp%AddBLin' , ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL AllocAry( InitInp%AddBQuad, InitInp%vecMultiplier*6, InitInp%vecMultiplier*6, InitInp%nWAMITObj, 'InitInp%AddBQuad' , ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL AllocAry( tmpVec1, InitInp%nWAMITObj, 'tmpVec1', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL AllocAry( tmpVec2, 6*InitInp%NBody, 'tmpVec2', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) - - ! Header + ! Header CALL ReadCom( UnIn, FileName, 'Additional stiffness and damping header', ErrStat2, ErrMsg2, UnEchoLocal ) @@ -1135,38 +1186,46 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) ! AddF0 - Additional preload - - CALL ReadAry ( UnIn, FileName, InitInp%AddF0, 6, 'AddF0', & - ' Additional preload vector', ErrStat2, ErrMsg2, UnEchoLocal ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - END IF - + do i = 1,6*InitInp%vecMultiplier + CALL ReadAry ( UnIn, FileName, tmpVec1, InitInp%nWAMITObj, 'AddF0', & + ' Additional preload vector', ErrStat2, ErrMsg2, UnEchoLocal ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + IF (ErrStat >= AbortErrLev) THEN + CALL CleanUp() + RETURN + END IF + do j = 1, InitInp%nWAMITObj + InitInp%AddF0(i,j) = tmpVec1(j) + end do + end do ! AddCLin - DO I=1,6 + do i=1,6*InitInp%vecMultiplier - WRITE(strI,'(I1)') I - CALL ReadAry ( UnIn, FileName, InitInp%AddCLin(I,:), 6, 'AddCLin', & + write(strI,'(I1)') i + call ReadAry ( UnIn, FileName, tmpVec2, 6*InitInp%NBody, 'AddCLin', & ' Row '//strI//' of the additional linear stiffness matrix', ErrStat2, ErrMsg2, UnEchoLocal ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - END IF - END DO + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + if (ErrStat >= AbortErrLev) then + call CleanUp() + return + end if + do j = 1, InitInp%nWAMITObj + startIndx = 6*InitInp%vecMultiplier*(j-1) + 1 + endIndx = startIndx + 6*InitInp%vecMultiplier - 1 + InitInp%AddCLin(i,:,j) = tmpVec2(startIndx:endIndx) + end do + end do ! AddBLin - DO I=1,6 + DO I=1,6*InitInp%vecMultiplier WRITE(strI,'(I1)') I - CALL ReadAry ( UnIn, FileName, InitInp%AddBLin(I,:), 6, 'AddBLin', & + CALL ReadAry ( UnIn, FileName, tmpVec2, 6*InitInp%NBody, 'AddBLin', & ' Row '//strI//' of the additional linear damping matrix', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) @@ -1174,15 +1233,20 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) CALL CleanUp() RETURN END IF + do j = 1, InitInp%nWAMITObj + startIndx = 6*InitInp%vecMultiplier*(j-1) + 1 + endIndx = startIndx + 6*InitInp%vecMultiplier - 1 + InitInp%AddBLin(I,:,j) = tmpVec2(startIndx:endIndx) + end do END DO ! AddBQuad - DO I=1,6 + DO I=1,6*InitInp%vecMultiplier WRITE(strI,'(I1)') I - CALL ReadAry ( UnIn, FileName, InitInp%AddBQuad(I,:), 6, 'AddBQuad', & + CALL ReadAry ( UnIn, FileName, tmpVec2, 6*InitInp%NBody, 'AddBQuad', & ' Row '//strI//' of the additional quadratic damping matrix', ErrStat2, ErrMsg2, UnEchoLocal ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) @@ -1190,6 +1254,11 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) CALL CleanUp() RETURN END IF + do j = 1, InitInp%nWAMITObj + startIndx = 6*InitInp%vecMultiplier*(j-1) + 1 + endIndx = startIndx + 6*InitInp%vecMultiplier - 1 + InitInp%AddBQuad(I,:,j) = tmpVec2(startIndx:endIndx) + end do END DO @@ -1337,7 +1406,7 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) READ(UnIn,'(A)',IOSTAT=ErrStat2) Line !read into a line IF (ErrStat2 == 0) THEN - READ(Line,*,IOSTAT=ErrStat2) InitInp%Morison%InpJoints(I)%JointID, InitInp%Morison%InpJoints(I)%JointPos(1), InitInp%Morison%InpJoints(I)%JointPos(2), InitInp%Morison%InpJoints(I)%JointPos(3), InitInp%Morison%InpJoints(I)%JointAxID, InitInp%Morison%InpJoints(I)%JointOvrlp + READ(Line,*,IOSTAT=ErrStat2) InitInp%Morison%InpJoints(I)%JointID, InitInp%Morison%InpJoints(I)%Position(1), InitInp%Morison%InpJoints(I)%Position(2), InitInp%Morison%InpJoints(I)%Position(3), InitInp%Morison%InpJoints(I)%JointAxID, InitInp%Morison%InpJoints(I)%JointOvrlp END IF IF ( ErrStat2 /= 0 ) THEN @@ -1478,7 +1547,7 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) READ(UnIn,'(A)',IOSTAT=ErrStat2) Line !read into a line IF (ErrStat2 == 0) THEN - READ(Line,*,IOSTAT=ErrStat2) InitInp%Morison%SimplCd, InitInp%Morison%SimplCdMG, InitInp%Morison%SimplCa, InitInp%Morison%SimplCaMG, InitInp%Morison%SimplCp, InitInp%Morison%SimplCpMG, InitInp%Morison%SimplAxCa, InitInp%Morison%SimplAxCaMG, InitInp%Morison%SimplAxCp, InitInp%Morison%SimplAxCpMG + READ(Line,*,IOSTAT=ErrStat2) InitInp%Morison%SimplCd, InitInp%Morison%SimplCdMG, InitInp%Morison%SimplCa, InitInp%Morison%SimplCaMG, InitInp%Morison%SimplCp, InitInp%Morison%SimplCpMG, InitInp%Morison%SimplAxCd, InitInp%Morison%SimplAxCdMG, InitInp%Morison%SimplAxCa, InitInp%Morison%SimplAxCaMG, InitInp%Morison%SimplAxCp, InitInp%Morison%SimplAxCpMG END IF IF ( ErrStat2 /= 0 ) THEN @@ -1560,7 +1629,8 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) IF (ErrStat2 == 0) THEN READ(Line,*,IOSTAT=ErrStat2) InitInp%Morison%CoefDpths(I)%Dpth, InitInp%Morison%CoefDpths(I)%DpthCd, InitInp%Morison%CoefDpths(I)%DpthCdMG, & InitInp%Morison%CoefDpths(I)%DpthCa, InitInp%Morison%CoefDpths(I)%DpthCaMG, InitInp%Morison%CoefDpths(I)%DpthCp, InitInp%Morison%CoefDpths(I)%DpthCpMG, & - InitInp%Morison%CoefDpths(I)%DpthAxCa, InitInp%Morison%CoefDpths(I)%DpthAxCaMG, InitInp%Morison%CoefDpths(I)%DpthAxCp, InitInp%Morison%CoefDpths(I)%DpthAxCpMG + InitInp%Morison%CoefDpths(I)%DpthAxCd, InitInp%Morison%CoefDpths(I)%DpthAxCdMG, InitInp%Morison%CoefDpths(I)%DpthAxCa, & + InitInp%Morison%CoefDpths(I)%DpthAxCaMG, InitInp%Morison%CoefDpths(I)%DpthAxCp, InitInp%Morison%CoefDpths(I)%DpthAxCpMG END IF IF (ErrStat2 /= 0) THEN @@ -1650,6 +1720,8 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) InitInp%Morison%CoefMembers(I)%MemberCaMG1, InitInp%Morison%CoefMembers(I)%MemberCaMG2, & InitInp%Morison%CoefMembers(I)%MemberCp1, InitInp%Morison%CoefMembers(I)%MemberCp2, & InitInp%Morison%CoefMembers(I)%MemberCpMG1, InitInp%Morison%CoefMembers(I)%MemberCpMG2, & + InitInp%Morison%CoefMembers(I)%MemberAxCd1, InitInp%Morison%CoefMembers(I)%MemberAxCd2, & + InitInp%Morison%CoefMembers(I)%MemberAxCdMG1, InitInp%Morison%CoefMembers(I)%MemberAxCdMG2, & InitInp%Morison%CoefMembers(I)%MemberAxCa1, InitInp%Morison%CoefMembers(I)%MemberAxCa2, & InitInp%Morison%CoefMembers(I)%MemberAxCaMG1, InitInp%Morison%CoefMembers(I)%MemberAxCaMG2, & InitInp%Morison%CoefMembers(I)%MemberAxCp1, InitInp%Morison%CoefMembers(I)%MemberAxCp2, & @@ -2023,20 +2095,31 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) END IF - ALLOCATE ( InitInp%Morison%MOutLst(I)%Marker1(InitInp%Morison%MOutLst(I)%NOutLoc), STAT = ErrStat2 ) + ALLOCATE ( InitInp%Morison%MOutLst(I)%MeshIndx1(InitInp%Morison%MOutLst(I)%NOutLoc), STAT = ErrStat2 ) IF ( ErrStat2 /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, 'Error allocating space for Marker1 array.', ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL SetErrStat( ErrID_Fatal, 'Error allocating space for %MeshIndx1 array.', ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) CALL CleanUp() RETURN END IF + ALLOCATE ( InitInp%Morison%MOutLst(I)%MemberIndx1(InitInp%Morison%MOutLst(I)%NOutLoc), STAT = ErrStat2 ) + IF ( ErrStat2 /= 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Error allocating space for %MemberIndx1 array.', ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL CleanUp() + RETURN + END IF - - ALLOCATE ( InitInp%Morison%MOutLst(I)%Marker2(InitInp%Morison%MOutLst(I)%NOutLoc), STAT = ErrStat2 ) + ALLOCATE ( InitInp%Morison%MOutLst(I)%MeshIndx2(InitInp%Morison%MOutLst(I)%NOutLoc), STAT = ErrStat2 ) IF ( ErrStat2 /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, 'Error allocating space for Marker2 array.', ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL SetErrStat( ErrID_Fatal, 'Error allocating space for %MeshIndx2 array.', ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) CALL CleanUp() RETURN END IF + ALLOCATE ( InitInp%Morison%MOutLst(I)%MemberIndx2(InitInp%Morison%MOutLst(I)%NOutLoc), STAT = ErrStat2 ) + IF ( ErrStat2 /= 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Error allocating space for %MemberIndx2 array.', ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) + CALL CleanUp() + RETURN + END IF ALLOCATE ( InitInp%Morison%MOutLst(I)%s(InitInp%Morison%MOutLst(I)%NOutLoc), STAT = ErrStat2 ) @@ -2238,9 +2321,7 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) ! OutList - list of requested parameters to output to a file - !CALL ReadOutputList ( UnIn, FileName, InitInp%WAMIT%OutList, InitInp%WAMIT%NumOuts, & - ! 'OutList', 'List of floating platform outputs requested', ErrStat2, ErrMsg2, UnEchoLocal ) - ALLOCATE( InitInp%UserOutputs(2778), Stat=ErrStat2) !todo: bjj: what is this 2778? + ALLOCATE( InitInp%UserOutputs(4583), Stat=ErrStat2) ! Total possible number of output channels: Waves2 = 18 + SS_Excitation = 7 + SS_Radiation = 7 + Morison= 4032 + HydroDyn=519 = 4583 IF (ErrStat2 /= 0) THEN CALL SetErrStat( ErrID_Fatal, 'Error allocating UserOutputs.', ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) CALL CleanUp() @@ -2256,32 +2337,6 @@ SUBROUTINE HydroDynInput_GetInput( InitInp, ErrStat, ErrMsg ) RETURN END IF - ! - ! - !!------------------------------------------------------------------------------------------------- - !! Data section for MESH-BASED OUTPUTS - !!------------------------------------------------------------------------------------------------- - ! - ! ! Header - ! - !CALL ReadCom( UnIn, FileName, 'Mesh-based Outputs header', ErrStat2, ErrMsg2, UnEchoLocal ) - ! - ! CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) - ! IF (ErrStat >= AbortErrLev) THEN - ! CALL CleanUp() - ! RETURN - ! END IF - ! - ! ! OutList - list of requested parameters to output to a file - ! - !CALL ReadOutputList ( UnIn, FileName, InitInp%Morison%OutList, InitInp%Morison%NumOuts, & - ! 'OutList', 'List of mesh-based outputs requested', ErrStat2, ErrMsg2, UnEchoLocal ) - ! - !CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) - !IF (ErrStat >= AbortErrLev) THEN - ! CALL CleanUp() - ! RETURN - !END IF !------------------------------------------------------------------------------------------------- ! This is the end of the input file @@ -2370,7 +2425,10 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) ! WtrDpth - Water depth - + + ! First adjust water depth based on MSL2SWL values + InitInp%Morison%WtrDpth = InitInp%Morison%WtrDpth + InitInp%Morison%MSL2SWL + IF ( InitInp%Morison%WtrDpth <= 0.0 ) THEN CALL SetErrStat( ErrID_Fatal,'WtrDpth must be greater than zero.',ErrStat,ErrMsg,RoutineName) RETURN @@ -2383,12 +2441,7 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) CALL SetErrStat( ErrID_Fatal,'MSL2SWL must be 0 when PotMod = 1 (WAMIT).',ErrStat,ErrMsg,RoutineName) RETURN END IF - - !IF ( .NOT. EqualRealNos(InitInp%Morison%MSL2SWL, 0.0_ReKi) ) THEN !TODO Alter this check when we support MSL2SWL - ! CALL SetErrStat( ErrID_Fatal,'MSL2SWL must be 0. Future versions of HydroDyn will once again support any value of MSL2SWL.' - ! RETURN - !END IF - + ! WaveMod - Wave kinematics model switch. @@ -2970,24 +3023,28 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) ! PotFile - Root name of potential flow files IF ( InitInp%PotMod > 0 ) THEN - IF ( LEN_TRIM( InitInp%PotFile ) == 0 ) THEN - CALL SetErrStat( ErrID_Fatal,'PotFile must not be an empty string.',ErrStat,ErrMsg,RoutineName) - RETURN - END IF + do i = 1,InitInp%nWAMITObj + IF ( LEN_TRIM( InitInp%PotFile(i) ) == 0 ) THEN + CALL SetErrStat( ErrID_Fatal,'PotFile must not be an empty string.',ErrStat,ErrMsg,RoutineName) + RETURN + END IF - ! if this is a relative path, let's make it relative to the location of the main input file - ! tell the WAMIT and WAMIT2 modules what the filename is + ! if this is a relative path, let's make it relative to the location of the main input file + ! tell the WAMIT and WAMIT2 modules what the filename is - IF ( PathIsRelative( InitInp%PotFile ) ) THEN - CALL GetPath( TRIM(InitInp%InputFile), TmpPath ) - InitInp%PotFile = TRIM(TmpPath)//TRIM(InitInp%PotFile) - END IF - InitInp%WAMIT%WAMITFile = InitInp%PotFile - InitInp%WAMIT2%WAMITFile = InitInp%PotFile + IF ( PathIsRelative( InitInp%PotFile(i) ) ) THEN + CALL GetPath( TRIM(InitInp%InputFile), TmpPath ) + InitInp%PotFile(i) = TRIM(TmpPath)//TRIM(InitInp%PotFile(i)) + END IF + end do + + !TODO: Move this to where the WAMIT modules are initialized + InitInp%WAMIT%WAMITFile = InitInp%PotFile(1) + InitInp%WAMIT2%WAMITFile = InitInp%PotFile(1) ! Set the flag for multidirectional waves for WAMIT2 module. It needs to know since the Newman approximation ! can only use uni-directional waves. - InitInp%WAMIT2%WaveMultiDir = InitInp%Waves%WaveMultiDir + InitInp%WAMIT2%WaveMultiDir = InitInp%Waves%WaveMultiDir ELSE InitInp%PotFile = "" @@ -3001,15 +3058,17 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) ! WAMITULEN - WAMIT characteristic body length scale IF ( InitInp%PotMod == 1 ) THEN - - InitInp%WAMIT2%WAMITULEN = InitInp%WAMIT%WAMITULEN ! Copy to the WAMIT2 module info - IF ( InitInp%WAMIT%WAMITULEN < 0.0 ) THEN - CALL SetErrStat( ErrID_Fatal,'WAMITULEN must be positive.',ErrStat,ErrMsg,RoutineName) - RETURN - END IF +!TODO: Deal with WAMIT2 and check each WAMITULEN not just the first + InitInp%WAMIT2%WAMITULEN = InitInp%WAMITULEN(1) ! Copy to the WAMIT2 module info + do i = 1,InitInp%nWAMITObj + IF ( InitInp%WAMITULEN(i) < 0.0 ) THEN + CALL SetErrStat( ErrID_Fatal,'WAMITULEN must be positive.',ErrStat,ErrMsg,RoutineName) + RETURN + END IF + end do ELSE - InitInp%WAMIT%WAMITULEN = 1.0 + InitInp%WAMITULEN = 1.0 InitInp%WAMIT2%WAMITULEN = 1.0 END IF @@ -3018,18 +3077,29 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) ! PtfmVol0 - Displaced volume of water when the platform is in its undisplaced position IF ( InitInp%PotMod == 1 ) THEN - - IF ( InitInp%WAMIT%PtfmVol0 < 0.0 ) THEN - CALL SetErrStat( ErrID_Fatal,'PtfmVol0 must not be negative.',ErrStat,ErrMsg,RoutineName) - RETURN - END IF - + do i = 1,InitInp%nWAMITObj + IF ( InitInp%PtfmVol0(i) < 0.0 ) THEN + CALL SetErrStat( ErrID_Fatal,'PtfmVol0 must not be negative.',ErrStat,ErrMsg,RoutineName) + RETURN + END IF + end do ELSE - InitInp%WAMIT%PtfmVol0 = 0.0 + InitInp%PtfmVol0 = 0.0 END IF + ! PtfmRefzt - The zt offset of the body reference point(s) from (0,0,0) (meters) [1 to NBody] + ! NOTE: only used when PotMod=1. If NBodyMod=2,PtfmRefzt=0.0 + + IF ( InitInp%PotMod == 1 .and. InitInp%NBodyMod == 2) THEN + do i = 1,InitInp%NBody + IF ( .not. EqualRealNos( InitInp%PtfmRefzt(i), 0.0_ReKi ) )THEN + CALL SetErrStat( ErrID_Fatal,'PtfmRefzt must be 0.0 for all WAMIT bodies when NBodyMod=2.',ErrStat,ErrMsg,RoutineName) + RETURN + END IF + end do + END IF ! RdtnTMax - Analysis time for wave radiation kernel calculations ! NOTE: Use RdtnTMax = 0.0 to eliminate wave radiation damping @@ -3082,98 +3152,10 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) END IF - !------------------------------------------------------------------------------------------------- - ! Data section for Floating platform force flags - !------------------------------------------------------------------------------------------------- - -!FIXME: ADP -- the error handling in this section is broken. - - ! If DEFAULT was requested, then the required value has already been set by the calling program - IF ( TRIM(InitInp%PtfmSgFChr) /= 'DEFAULT' ) THEN - - READ (InitInp%PtfmSgFChr,*,IOSTAT=IOS) InitInp%PtfmSgF - CALL CheckIOS ( IOS, "", 'PtfmSgF', NumType, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - END IF - - IF ( TRIM(InitInp%PtfmSwFChr) /= 'DEFAULT' ) THEN - - READ (InitInp%PtfmSwFChr,*,IOSTAT=IOS) InitInp%PtfmSwF - CALL CheckIOS ( IOS, "", 'PtfmSwF', NumType, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - END IF - - IF ( TRIM(InitInp%PtfmHvFChr) /= 'DEFAULT' ) THEN - - READ (InitInp%PtfmHvFChr,*,IOSTAT=IOS) InitInp%PtfmHvF - CALL CheckIOS ( IOS, "", 'PtfmHvF', NumType, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - END IF - - IF ( TRIM(InitInp%PtfmRFChr) /= 'DEFAULT' ) THEN - - READ (InitInp%PtfmRFChr,*,IOSTAT=IOS) InitInp%PtfmRF - CALL CheckIOS ( IOS, "", 'PtfmRF', NumType, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - END IF - - IF ( TRIM(InitInp%PtfmPFChr) /= 'DEFAULT' ) THEN - - READ (InitInp%PtfmPFChr,*,IOSTAT=IOS) InitInp%PtfmPF - CALL CheckIOS ( IOS, "", 'PtfmPF', NumType, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - END IF - - IF ( TRIM(InitInp%PtfmYFChr) /= 'DEFAULT' ) THEN - - READ (InitInp%PtfmYFChr,*,IOSTAT=IOS) InitInp%PtfmYF - CALL CheckIOS ( IOS, "", 'PtfmYF', NumType, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - END IF - - - ! Add checks that all platform DOF flags are true. TODO: Allow true or false once these have been implemented - - IF ( ( .NOT. InitInp%PtfmSgF ) .OR. ( .NOT. InitInp%PtfmSwF ) .OR. ( .NOT. InitInp%PtfmHvF ) .OR. ( .NOT. InitInp%PtfmRF ) .OR. ( .NOT. InitInp%PtfmPF ) .OR. ( .NOT. InitInp%PtfmYF ) )THEN -! CALL SetErrStat( ErrID_Fatal,'All platform DOF parameters must be set to TRUE. Future versions of HydroDyn will support values of TRUE, FALSE, or DEFAULT.',ErrStat,ErrMsg,RoutineName) - CALL SetErrStat( ErrID_Warn,' Only the second-order floating platform force calculations (WAMIT2 sub-module) allow for selectively dissabling force DOF parameters, the first order (WAMIT sub-module) does not and will calculate all dimensions. Future versions of HydroDyn will support values of TRUE, FALSE, or DEFAULT for both modules.',ErrStat,ErrMsg,RoutineName) - END IF - - - - !------------------------------------------------------------------------------------------------- - ! Second order Forces Flags (WAMIT2 Module) - !------------------------------------------------------------------------------------------------- - ! We don't have separate inputs for the second order force component flags, rather they are taken - ! from the platform section in the input file and copied into the InitInp%WAMIT2 derived type. - ! Within the WAMIT2_Init subroutine, they are reset if necessary (some second order output files - ! from WAMIT don't support all force components -- i.e. the *.8 files). - - InitInp%WAMIT2%PtfmSgF2 = InitInp%PtfmSgF - InitInp%WAMIT2%PtfmSwF2 = InitInp%PtfmSwF - InitInp%WAMIT2%PtfmHvF2 = InitInp%PtfmHvF - InitInp%WAMIT2%PtfmRF2 = InitInp%PtfmRF - InitInp%WAMIT2%PtfmPF2 = InitInp%PtfmPF - InitInp%WAMIT2%PtfmYF2 = InitInp%PtfmYF - - !------------------------------------------------------------------------------------------------- ! Second order Forces due to Waves section (WAMIT2 Module) !------------------------------------------------------------------------------------------------- - ! Check that we only specified one of MnDrift, NewmanApp, or DiffQTF ! (compared pairwise -- if any two are both true, we have a problem) @@ -3185,6 +3167,17 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) END IF + if ( InitInp%NBody > 1 .and. InitInp%WAMIT2%MnDrift == 8 ) then + call SetErrStat( ErrID_Fatal,'MnDrift cannot equal 8 when NBody > 1.',ErrStat,ErrMsg,RoutineName) + return + end if + + if ( InitInp%NBody > 1 .and. InitInp%WAMIT2%NewmanApp == 8 ) then + call SetErrStat( ErrID_Fatal,'NewmanApp cannot equal 8 when NBody > 1.',ErrStat,ErrMsg,RoutineName) + return + end if + + ! Check MnDrift and set the flag indicating WAMIT2 should perform the mean drift calculation. ! Also make sure we have a valid input value for the file extension @@ -3192,7 +3185,12 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) InitInp%WAMIT2%MnDriftF = .FALSE. ELSE IF ( InitInp%WAMIT2%MnDrift == 7 .OR. InitInp%WAMIT2%MnDrift == 8 .OR. InitInp%WAMIT2%MnDrift == 9 .OR. & InitInp%WAMIT2%MnDrift == 10 .OR. InitInp%WAMIT2%MnDrift == 11 .OR. InitInp%WAMIT2%MnDrift == 12 ) THEN ! Valid values for MnDrift - InitInp%WAMIT2%MnDriftF = .TRUE. + IF ( InitInp%PotMod /= 1 ) THEN + CALL SetErrStat( ErrID_warn,'MnDrift can only be used with PotMod==1. Turning off',ErrStat,ErrMsg,RoutineName) + InitInp%WAMIT2%MnDriftF = .FALSE. + ELSE + InitInp%WAMIT2%MnDriftF = .TRUE. + ENDIF ELSE ! Must have received an invalid value CALL SetErrStat( ErrID_Fatal,'MnDrift can only have values of 0, 7, 8, 9, 10, 11, or 12.',ErrStat,ErrMsg,RoutineName) RETURN @@ -3206,7 +3204,12 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) InitInp%WAMIT2%NewmanAppF = .FALSE. ELSE IF ( InitInp%WAMIT2%NewmanApp == 7 .OR. InitInp%WAMIT2%NewmanApp == 8 .OR. InitInp%WAMIT2%NewmanApp == 9 .OR. & InitInp%WAMIT2%NewmanApp == 10 .OR. InitInp%WAMIT2%NewmanApp == 11 .OR. InitInp%WAMIT2%NewmanApp == 12 ) THEN ! Valid values for NewmanApp - InitInp%WAMIT2%NewmanAppF = .TRUE. + IF ( InitInp%PotMod /= 1 ) THEN + CALL SetErrStat( ErrID_warn,'NewmanApp can only be used with PotMod==1. Turning off',ErrStat,ErrMsg,RoutineName) + InitInp%WAMIT2%NewmanAppF = .FALSE. + ELSE + InitInp%WAMIT2%NewmanAppF = .TRUE. + ENDIF ELSE ! Must have received an invalid value CALL SetErrStat( ErrID_Fatal,'NewmanApp can only have values of 0, 7, 8, 9, 10, 11, or 12.',ErrStat,ErrMsg,RoutineName) RETURN @@ -3219,7 +3222,12 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) IF ( InitInp%WAMIT2%DiffQTF == 0 ) THEN ! not using DiffQTF method InitInp%WAMIT2%DiffQTFF = .FALSE. ELSE IF ( InitInp%WAMIT2%DiffQTF == 10 .OR. InitInp%WAMIT2%DiffQTF == 11 .OR. InitInp%WAMIT2%DiffQTF == 12 ) THEN ! Valid values for DiffQTF - InitInp%WAMIT2%DiffQTFF = .TRUE. + IF ( InitInp%PotMod /= 1 ) THEN + CALL SetErrStat( ErrID_warn,'DiffQTF can only be used with PotMod==1. Turning off',ErrStat,ErrMsg,RoutineName) + InitInp%WAMIT2%DiffQTFF = .FALSE. + ELSE + InitInp%WAMIT2%DiffQTFF = .TRUE. + ENDIF ELSE CALL SetErrStat( ErrID_Fatal,'DiffQTF can only have values of 0, 10, 11, or 12.',ErrStat,ErrMsg,RoutineName) RETURN @@ -3232,7 +3240,12 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) IF ( InitInp%WAMIT2%SumQTF == 0 ) THEN ! not using SumQTF method InitInp%WAMIT2%SumQTFF = .FALSE. ELSE IF ( InitInp%WAMIT2%SumQTF == 10 .OR. InitInp%WAMIT2%SumQTF == 11 .OR. InitInp%WAMIT2%SumQTF == 12 ) THEN ! Valid values for SumQTF - InitInp%WAMIT2%SumQTFF = .TRUE. + IF ( InitInp%PotMod /= 1 ) THEN + CALL SetErrStat( ErrID_warn,'SumQTF can only be used with PotMod==1. Turning off',ErrStat,ErrMsg,RoutineName) + InitInp%WAMIT2%SumQTFF = .FALSE. + ELSE + InitInp%WAMIT2%SumQTFF = .TRUE. + ENDIF ELSE CALL SetErrStat( ErrID_Fatal,'SumQTF can only have values of 0, 10, 11, or 12.',ErrStat,ErrMsg,RoutineName) RETURN @@ -3265,7 +3278,7 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) ! now that it has been established that the input parameters for second order are good, we check to make sure that the WAMIT files actually exist. ! Check MnDrift file - IF ( InitInp%WAMIT2%MnDrift /= 0) THEN + IF ( InitInp%WAMIT2%MnDriftF ) THEN ! Check if using QTF file types (10d, 11d, 12d) or not (7,8,9) IF ( InitInp%WAMIT2%MnDrift <= 9 ) THEN TmpExtension = TRIM(Num2LStr(InitInp%WAMIT2%MnDrift)) @@ -3282,7 +3295,7 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) END IF ! Check existence of NewmanApp file - IF ( InitInp%WAMIT2%NewmanApp /= 0) THEN + IF ( InitInp%WAMIT2%NewmanAppF ) THEN ! Check if using QTF file types (10d, 11d, 12d) or not (7,8,9) IF ( InitInp%WAMIT2%NewmanApp <= 9 ) THEN TmpExtension = TRIM(Num2LStr(InitInp%WAMIT2%NewmanApp)) @@ -3298,7 +3311,7 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) END IF END IF - IF ( InitInp%WAMIT2%DiffQTF /= 0) THEN + IF ( InitInp%WAMIT2%DiffQTFF ) THEN TmpExtension = TRIM(Num2LStr(InitInp%WAMIT2%DiffQTF))//'d' INQUIRE( file=TRIM(InitInp%WAMIT2%WAMITFile)//'.'//TRIM(TmpExtension), exist=TmpFileExist ) IF ( .not. TmpFileExist ) THEN @@ -3308,7 +3321,7 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) END IF END IF - IF ( InitInp%WAMIT2%SumQTF /= 0) THEN + IF ( InitInp%WAMIT2%SumQTFF ) THEN TmpExtension = TRIM(Num2LStr(InitInp%WAMIT2%SumQTF))//'s' INQUIRE( file=TRIM(InitInp%WAMIT2%WAMITFile)//'.'//TRIM(TmpExtension), exist=TmpFileExist ) IF ( .not. TmpFileExist ) THEN @@ -3436,19 +3449,7 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) IF ( InitInp%Morison%NAxCoefs > 0 ) THEN DO I = 1,InitInp%Morison%NAxCoefs - - !IF ( .NOT. EqualRealNos(InitInp%Morison%AxialCoefs(I)%AxCd, 0.0) ) THEN - ! ErrMsg = ' AxCd must be equal to zero. Future versions will allow for non-zero axial coefficients.' - ! ErrStat = ErrID_Fatal - ! RETURN - !END IF - !IF ( .NOT. EqualRealNos(InitInp%Morison%AxialCoefs(I)%AxCa, 0.0) ) THEN - ! ErrMsg = ' AxCa must be equal to zero. Future versions will allow for non-zero axial coefficients.' - ! ErrStat = ErrID_Fatal - ! RETURN - !END IF - - ! TODO: Once Axial Coefs are working remove the above checks and uncomment the checks below. GJH 9/29/2013 + IF ( InitInp%Morison%AxialCoefs(I)%AxCd < 0 ) THEN CALL SetErrStat( ErrID_Fatal,'AxCd must be greater or equal to zero.',ErrStat,ErrMsg,RoutineName) RETURN @@ -3472,7 +3473,7 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) ! Check JointOvrlp values - InitInp%Morison%TotalPossibleSuperMembers = 0 + !NOTE: This is ignored in the current version of Morison. 3/15/2020 GJH IF ( InitInp%Morison%NJoints > 1 ) THEN @@ -3495,9 +3496,9 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) END DO ! Add up total number of joints flagged with JoinOvrlp = 1 option - IF ( InitInp%Morison%InpJoints(I)%JointOvrlp == 1 ) THEN - InitInp%Morison%TotalPossibleSuperMembers = InitInp%Morison%TotalPossibleSuperMembers + 1 - END IF + !IF ( InitInp%Morison%InpJoints(I)%JointOvrlp == 1 ) THEN + ! InitInp%Morison%TotalPossibleSuperMembers = InitInp%Morison%TotalPossibleSuperMembers + 1 + !END IF ! Check that every joint id is used at least once in the members table JointUsed = .FALSE. @@ -3598,15 +3599,23 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) CALL SetErrStat( ErrID_Fatal,'SimplCaMG must be greater or equal to zero.',ErrStat,ErrMsg,RoutineName) RETURN END IF + IF ( InitInp%Morison%SimplAxCd < 0 ) THEN + CALL SetErrStat( ErrID_Fatal,'SimplAxCd must be greater or equal to zero.',ErrStat,ErrMsg,RoutineName) + RETURN + END IF + IF ( InitInp%Morison%SimplAxCdMG < 0 ) THEN + CALL SetErrStat( ErrID_Fatal,'SimplAxCdMG must be greater or equal to zero.',ErrStat,ErrMsg,RoutineName) + RETURN + END IF IF ( InitInp%Morison%SimplAxCa < 0 ) THEN - CALL SetErrStat( ErrID_Fatal,'SimplCa must be greater or equal to zero.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat( ErrID_Fatal,'SimplAxCa must be greater or equal to zero.',ErrStat,ErrMsg,RoutineName) RETURN END IF IF ( InitInp%Morison%SimplAxCaMG < 0 ) THEN - CALL SetErrStat( ErrID_Fatal,'SimplCaMG must be greater or equal to zero.',ErrStat,ErrMsg,RoutineName) + CALL SetErrStat( ErrID_Fatal,'SimplAxCaMG must be greater or equal to zero.',ErrStat,ErrMsg,RoutineName) RETURN END IF - + !TODO: Do we need a test for AxCp !------------------------------------------------------------------------------------------------- ! Depth-based Hydrodynamic Coefficients Section @@ -3659,6 +3668,14 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) CALL SetErrStat( ErrID_Fatal,'In the Depth-based hydrodynamic coefficients table, DpthCaMG must be greater or equal to zero.',ErrStat,ErrMsg,RoutineName) RETURN END IF + IF ( InitInp%Morison%CoefDpths(I)%DpthAxCd < 0 ) THEN + CALL SetErrStat( ErrID_Fatal,'In the Depth-based hydrodynamic coefficients table, DpthAxCd must be greater or equal to zero.',ErrStat,ErrMsg,RoutineName) + RETURN + END IF + IF ( InitInp%Morison%CoefDpths(I)%DpthAxCdMG < 0 ) THEN + CALL SetErrStat( ErrID_Fatal,'In the Depth-based hydrodynamic coefficients table, DpthAxCdMG must be greater or equal to zero.',ErrStat,ErrMsg,RoutineName) + RETURN + END IF IF ( InitInp%Morison%CoefDpths(I)%DpthAxCa < 0 ) THEN CALL SetErrStat( ErrID_Fatal,'In the Depth-based hydrodynamic coefficients table, DpthAxCa must be greater or equal to zero.',ErrStat,ErrMsg,RoutineName) RETURN @@ -3777,8 +3794,6 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) InitInp%Morison%InpMembers(I)%MPropSetID2Indx = -1 InitInp%Morison%InpMembers(I)%MmbrFilledIDIndx = -1 InitInp%Morison%InpMembers(I)%MmbrCoefIDIndx = -1 - InitInp%Morison%InpMembers(I)%NumSplits = 0 - InitInp%Morison%InpMembers(I)%Splits = 0.0_ReKi END DO DO I = 1,InitInp%Morison%NMembers @@ -3801,7 +3816,7 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) IF ( InitInp%Morison%InpMembers(I)%MJointID2 == InitInp%Morison%InpJoints(J)%JointID ) THEN InitInp%Morison%InpMembers(I)%MJointID2Indx = J InitInp%Morison%InpJoints(J)%NConnections = InitInp%Morison%InpJoints(J)%NConnections + 1 - InitInp%Morison%InpJoints(J)%ConnectionList(InitInp%Morison%InpJoints(J)%NConnections) = I + InitInp%Morison%InpJoints(J)%ConnectionList(InitInp%Morison%InpJoints(J)%NConnections) = -I !TODO: Come up with a better method for this work GJH 4/6/20 END IF END DO @@ -3816,7 +3831,7 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) END IF ! Make sure we do not have any zero length members - lvec = InitInp%Morison%InpJoints(InitInp%Morison%InpMembers(I)%MJointID1Indx)%JointPos - InitInp%Morison%InpJoints(InitInp%Morison%InpMembers(I)%MJointID2Indx)%JointPos + lvec = InitInp%Morison%InpJoints(InitInp%Morison%InpMembers(I)%MJointID1Indx)%Position - InitInp%Morison%InpJoints(InitInp%Morison%InpMembers(I)%MJointID2Indx)%Position l = sqrt( lvec(1)*lvec(1) + lvec(2)*lvec(2) + lvec(3)*lvec(3) ) IF ( EqualRealNos(0.0_ReKi, l) ) THEN CALL SetErrStat( ErrID_Fatal,'A member cannot have zero length.',ErrStat,ErrMsg,RoutineName) @@ -3867,8 +3882,8 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) END IF ! We will not extrapolate depth-based coefficient values, so make sure that the depth-based table has values that are outside the depth range of this member ! NOTE: This is actually potentially overly conservative because the final member may be shorter due to joint overlap handling. - z1 = InitInp%Morison%InpJoints( InitInp%Morison%InpMembers(I)%MJointID1Indx )%JointPos(3) - z2 = InitInp%Morison%InpJoints( InitInp%Morison%InpMembers(I)%MJointID2Indx )%JointPos(3) + z1 = InitInp%Morison%InpJoints( InitInp%Morison%InpMembers(I)%MJointID1Indx )%Position(3) + z2 = InitInp%Morison%InpJoints( InitInp%Morison%InpMembers(I)%MJointID2Indx )%Position(3) MinMembrDpth = min( z1, z2 ) MaxMembrDpth = max( z1, z2 ) IF ( ( MinMembrDpth < MinDepth ) .OR. ( MaxMembrDpth > MaxDepth ) ) THEN @@ -3988,9 +4003,11 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) InitInp%Morison%MGTop = -999999.0 InitInp%Morison%MGBottom = 999999.0 - + do I = 1,InitInp%Morison%NMGDepths + ! Adjust the depth values based on MSL2SWL + InitInp%Morison%MGDepths(I)%MGDpth = InitInp%Morison%MGDepths(I)%MGDpth - InitInp%Morison%MSL2SWL + end do DO I = 1,InitInp%Morison%NMGDepths - ! Store the boundaries of the marine growth zone IF ( InitInp%Morison%MGDepths(I)%MGDpth > InitInp%Morison%MGTop ) THEN InitInp%Morison%MGTop = InitInp%Morison%MGDepths(I)%MGDpth @@ -4074,13 +4091,6 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) ! Joint Output List Section !------------------------------------------------------------------------------------------------- - !IF ( InitInp%Morison%NJOutputs /= 0 ) THEN ! TODO Remove this check and add back the other checks once Joint Outputs are supported - !CALL SetErrStat( ErrID_Fatal,'NJOutputs in the Joint output list must be equal to zero. Future versions of HydroDyn will support values greater or equal to zero and less than 10.' - ! ErrStat = ErrID_Fatal - ! RETURN - !END IF - - IF ( ( InitInp%Morison%NJOutputs < 0 ) .OR. ( InitInp%Morison%NMOutputs > 9 ) ) THEN CALL SetErrStat( ErrID_Fatal,'NJOutputs in the Joint output list must be greater or equal to zero and less than 10.',ErrStat,ErrMsg,RoutineName) RETURN @@ -4100,7 +4110,7 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) END IF END DO - ! Make sure that a PropSetID entry in the Member cross-section properties table was found + ! Make sure that a Joint Output ID found in the JOutLst is in the Joints table IF ( InitInp%Morison%JOutLst(I)%JointIDIndx == -1 ) THEN CALL SetErrStat( ErrID_Fatal,'JointID in the Joint output list table does not appear in the Joints table.',ErrStat,ErrMsg,RoutineName) RETURN @@ -4150,31 +4160,25 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) END IF foundMask = .FALSE. ! Extract Waves2 list - InitInp%Waves2%NumOuts = GetWaves2Channels ( InitInp%NUserOutputs, InitInp%UserOutputs, InitInp%Waves2%OutList, foundMask, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + InitInp%Waves2%NumOuts = GetWaves2Channels ( InitInp%NUserOutputs, InitInp%UserOutputs, InitInp%Waves2%OutList, foundMask, ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - ! Extract WAMIT list - InitInp%WAMIT%NumOuts = GetWAMITChannels ( InitInp%NUserOutputs, InitInp%UserOutputs, InitInp%WAMIT%OutList, foundMask, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - ! Extract WAMIT2 list - InitInp%WAMIT2%NumOuts = GetWAMIT2Channels ( InitInp%NUserOutputs, InitInp%UserOutputs, InitInp%WAMIT2%OutList, foundMask, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - +! ! Extract WAMIT2 list +! InitInp%WAMIT2%NumOuts = GetWAMIT2Channels ( InitInp%NUserOutputs, InitInp%UserOutputs, InitInp%WAMIT2%OutList, foundMask, ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) +! ! Extract Morison list !foundMask = .FALSE. - InitInp%Morison%NumOuts = GetMorisonChannels ( InitInp%NUserOutputs, InitInp%UserOutputs, InitInp%Morison%OutList, foundMask, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + InitInp%Morison%NumOuts = GetMorisonChannels ( InitInp%NUserOutputs, InitInp%UserOutputs, InitInp%Morison%OutList, foundMask, ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) ! Attach remaining items to the HydroDyn list !foundMask = .FALSE. - InitInp%NumOuts = HDOut_GetChannels ( InitInp%NUserOutputs, InitInp%UserOutputs, InitInp%OutList , foundMask, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - CALL PrintBadChannelWarning(InitInp%NUserOutputs, InitInp%UserOutputs , foundMask, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call Allocary(InitInp%OutList, InitInp%NUserOutputs, "InitInp%OutList", ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + InitInp%NumOuts = HDOut_GetChannels ( InitInp%NUserOutputs, InitInp%UserOutputs, InitInp%OutList , foundMask, ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + CALL PrintBadChannelWarning(InitInp%NUserOutputs, InitInp%UserOutputs , foundMask, ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + IF (ErrStat >= AbortErrLev ) RETURN DEALLOCATE(foundMask) + END IF ! Now that we have the sub-lists organized, lets do some additional validation. @@ -4209,14 +4213,14 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) ! Current ! For wave kinematic calculations, the effective water depth is the user input water depth (positive valued) + MSL2SWL (positive when SWL is above MSL). - InitInp%Current%WtrDpth = InitInp%Morison%WtrDpth + InitInp%Morison%MSL2SWL ! Adjust for the MSL2SWL. + InitInp%Current%WtrDpth = InitInp%Morison%WtrDpth ! already adjusted for the MSL2SWL. ! Waves InitInp%Waves%Gravity = InitInp%Gravity InitInp%Waves%UnSum = InitInp%UnSum ! For wave kinematic calculations, the effective water depth is the user input water depth (positive valued) + MSL2SWL (positive when SWL is above MSL). - InitInp%Waves%WtrDpth = InitInp%Morison%WtrDpth + InitInp%Morison%MSL2SWL ! Adjust for the MSL2SWL + InitInp%Waves%WtrDpth = InitInp%Morison%WtrDpth ! already adjusted for the MSL2SWL. ! Waves2 IF (InitInp%Waves2%WvDiffQTFF .OR. InitInp%Waves2%WvSumQTFF ) THEN @@ -4243,7 +4247,6 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) ! WAMIT2 InitInp%WAMIT2%WtrDens = InitInp%Waves%WtrDens InitInp%WAMIT2%WaveMod = InitInp%Waves%WaveMod - InitInp%WAMIT2%OutAll = InitInp%OutAll InitInp%WAMIT2%HasWAMIT = InitInp%PotMod == 1 ! Morison InitInp%Morison%UnSum = InitInp%UnSum @@ -4252,7 +4255,8 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) InitInp%Morison%OutAll = InitInp%OutAll ! Process the input geometry and generate the simulation mesh representation - CALL Morison_ProcessMorisonGeometry( InitInp%Morison, ErrStat2, ErrMsg2 ) + call Morison_GenerateSimulationNodes( InitInp%Morison%MSL2SWL, InitInp%Morison%NJoints, InitInp%Morison%InpJoints, InitInp%Morison%NMembers, InitInp%Morison%InpMembers, InitInp%Morison%NNodes, InitInp%Morison%Nodes, errStat2, errMsg2 ) + !CALL Morison_ProcessMorisonGeometry( InitInp%Morison, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HydroDynInput_GetInput' ) IF ( ErrStat >= AbortErrLev ) RETURN @@ -4286,9 +4290,9 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, ErrStat, ErrMsg ) RETURN END IF DO I=1,InitInp%Morison%NNodes - InitInp%Waves%WaveKinxi(I) = InitInp%Morison%Nodes(I)%JointPos(1) ! xi-coordinates for points where the incident wave kinematics will be computed; - InitInp%Waves%WaveKinyi(I) = InitInp%Morison%Nodes(I)%JointPos(2) ! yi-coordinates for points where the incident wave kinematics will be computed; - InitInp%Waves%WaveKinzi(I) = InitInp%Morison%Nodes(I)%JointPos(3) - InitInp%Morison%MSL2SWL ! zi-coordinates for points where the incident wave kinematics will be computed, adjusted to the still water level(meters) + InitInp%Waves%WaveKinxi(I) = InitInp%Morison%Nodes(I)%Position(1) ! xi-coordinates for points where the incident wave kinematics will be computed; + InitInp%Waves%WaveKinyi(I) = InitInp%Morison%Nodes(I)%Position(2) ! yi-coordinates for points where the incident wave kinematics will be computed; + InitInp%Waves%WaveKinzi(I) = InitInp%Morison%Nodes(I)%Position(3) ! zi-coordinates for points where the incident wave kinematics will be computed; InitInp%Current%MorisonNodezi(I) = InitInp%Waves%WaveKinzi(I) END DO diff --git a/modules/hydrodyn/src/HydroDyn_Output.f90 b/modules/hydrodyn/src/HydroDyn_Output.f90 index 4f9f02318f..845eddc397 100644 --- a/modules/hydrodyn/src/HydroDyn_Output.f90 +++ b/modules/hydrodyn/src/HydroDyn_Output.f90 @@ -29,155 +29,883 @@ MODULE HydroDyn_Output PRIVATE +! =================================================================================================== +! 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 05-Jan-2021 06:02:16. - ! Parameters related to output length (number of characters allowed in the output data headers): - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 1 - - - ! Time: - - INTEGER(IntKi), PARAMETER :: Time = 0 - - - ! Category: - - INTEGER(IntKi), PARAMETER :: AddFxi = 1 - INTEGER(IntKi), PARAMETER :: AddFyi = 2 - INTEGER(IntKi), PARAMETER :: AddFzi = 3 - INTEGER(IntKi), PARAMETER :: AddMxi = 4 - INTEGER(IntKi), PARAMETER :: AddMyi = 5 - INTEGER(IntKi), PARAMETER :: AddMzi = 6 - - - ! Category: + ! Parameters related to output length (number of characters allowed in the output data headers): - INTEGER(IntKi), PARAMETER :: HydroFxi = 7 - INTEGER(IntKi), PARAMETER :: HydroFyi = 8 - INTEGER(IntKi), PARAMETER :: HydroFzi = 9 - INTEGER(IntKi), PARAMETER :: HydroMxi = 10 - INTEGER(IntKi), PARAMETER :: HydroMyi = 11 - INTEGER(IntKi), PARAMETER :: HydroMzi = 12 - - - ! Category: - - INTEGER(IntKi), PARAMETER :: Wave1Elev = 13 - INTEGER(IntKi), PARAMETER :: Wave1Elv1 = 14 - INTEGER(IntKi), PARAMETER :: Wave2Elev = 15 - INTEGER(IntKi), PARAMETER :: Wave2Elv1 = 16 - INTEGER(IntKi), PARAMETER :: Wave3Elev = 17 - INTEGER(IntKi), PARAMETER :: Wave3Elv1 = 18 - INTEGER(IntKi), PARAMETER :: Wave4Elev = 19 - INTEGER(IntKi), PARAMETER :: Wave4Elv1 = 20 - INTEGER(IntKi), PARAMETER :: Wave5Elev = 21 - INTEGER(IntKi), PARAMETER :: Wave5Elv1 = 22 - INTEGER(IntKi), PARAMETER :: Wave6Elev = 23 - INTEGER(IntKi), PARAMETER :: Wave6Elv1 = 24 - INTEGER(IntKi), PARAMETER :: Wave7Elev = 25 - INTEGER(IntKi), PARAMETER :: Wave7Elv1 = 26 - INTEGER(IntKi), PARAMETER :: Wave8Elev = 27 - INTEGER(IntKi), PARAMETER :: Wave8Elv1 = 28 - INTEGER(IntKi), PARAMETER :: Wave9Elev = 29 - INTEGER(IntKi), PARAMETER :: Wave9Elv1 = 30 - - - ! Category: - - INTEGER(IntKi), PARAMETER :: WavesFxi = 31 - INTEGER(IntKi), PARAMETER :: WavesFyi = 32 - INTEGER(IntKi), PARAMETER :: WavesFzi = 33 - INTEGER(IntKi), PARAMETER :: WavesMxi = 34 - INTEGER(IntKi), PARAMETER :: WavesMyi = 35 - INTEGER(IntKi), PARAMETER :: WavesMzi = 36 - - - ! Category: + INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 1 - INTEGER(IntKi), PARAMETER :: WRPSurge = 37 - INTEGER(IntKi), PARAMETER :: WRPSway = 38 - INTEGER(IntKi), PARAMETER :: WRPHeave = 39 - INTEGER(IntKi), PARAMETER :: WRPRoll = 40 - INTEGER(IntKi), PARAMETER :: WRPPitch = 41 - INTEGER(IntKi), PARAMETER :: WRPYaw = 42 - INTEGER(IntKi), PARAMETER :: WRPTVxi = 43 - INTEGER(IntKi), PARAMETER :: WRPTVyi = 44 - INTEGER(IntKi), PARAMETER :: WRPTVzi = 45 - INTEGER(IntKi), PARAMETER :: WRPRVxi = 46 - INTEGER(IntKi), PARAMETER :: WRPRVyi = 47 - INTEGER(IntKi), PARAMETER :: WRPRVzi = 48 - INTEGER(IntKi), PARAMETER :: WRPTAxi = 49 - INTEGER(IntKi), PARAMETER :: WRPTAyi = 50 - INTEGER(IntKi), PARAMETER :: WRPTAzi = 51 - INTEGER(IntKi), PARAMETER :: WRPRAxi = 52 - INTEGER(IntKi), PARAMETER :: WRPRAyi = 53 - INTEGER(IntKi), PARAMETER :: WRPRAzi = 54 - !End of code generated by Matlab script + ! Indices for computing output channels: + ! NOTES: + ! (1) These parameters are in the order stored in "OutListParameters.xlsx" + ! (2) Array AllOuts() must be dimensioned to the value of the largest output parameter + + ! Time: + + INTEGER(IntKi), PARAMETER :: Time = 0 + + + ! Integrated Hydrodynamic Loads at (0,0,0): + + INTEGER(IntKi), PARAMETER :: HydroFxi = 1 + INTEGER(IntKi), PARAMETER :: HydroFyi = 2 + INTEGER(IntKi), PARAMETER :: HydroFzi = 3 + INTEGER(IntKi), PARAMETER :: HydroMxi = 4 + INTEGER(IntKi), PARAMETER :: HydroMyi = 5 + INTEGER(IntKi), PARAMETER :: HydroMzi = 6 + + + ! PRP Body Kinematics: + + INTEGER(IntKi), PARAMETER :: PRPSurge = 7 + INTEGER(IntKi), PARAMETER :: PRPSway = 8 + INTEGER(IntKi), PARAMETER :: PRPHeave = 9 + INTEGER(IntKi), PARAMETER :: PRPRoll = 10 + INTEGER(IntKi), PARAMETER :: PRPPitch = 11 + INTEGER(IntKi), PARAMETER :: PRPYaw = 12 + INTEGER(IntKi), PARAMETER :: PRPTVxi = 13 + INTEGER(IntKi), PARAMETER :: PRPTVyi = 14 + INTEGER(IntKi), PARAMETER :: PRPTVzi = 15 + INTEGER(IntKi), PARAMETER :: PRPRVxi = 16 + INTEGER(IntKi), PARAMETER :: PRPRVyi = 17 + INTEGER(IntKi), PARAMETER :: PRPRVzi = 18 + INTEGER(IntKi), PARAMETER :: PRPTAxi = 19 + INTEGER(IntKi), PARAMETER :: PRPTAyi = 20 + INTEGER(IntKi), PARAMETER :: PRPTAzi = 21 + INTEGER(IntKi), PARAMETER :: PRPRAxi = 22 + INTEGER(IntKi), PARAMETER :: PRPRAyi = 23 + INTEGER(IntKi), PARAMETER :: PRPRAzi = 24 + + + ! WAMIT Body Kinematics: + + INTEGER(IntKi), PARAMETER :: B1Surge = 25 + INTEGER(IntKi), PARAMETER :: B1Sway = 26 + INTEGER(IntKi), PARAMETER :: B1Heave = 27 + INTEGER(IntKi), PARAMETER :: B1Roll = 28 + INTEGER(IntKi), PARAMETER :: B1Pitch = 29 + INTEGER(IntKi), PARAMETER :: B1Yaw = 30 + INTEGER(IntKi), PARAMETER :: B1TVxi = 31 + INTEGER(IntKi), PARAMETER :: B1TVyi = 32 + INTEGER(IntKi), PARAMETER :: B1TVzi = 33 + INTEGER(IntKi), PARAMETER :: B1RVxi = 34 + INTEGER(IntKi), PARAMETER :: B1RVyi = 35 + INTEGER(IntKi), PARAMETER :: B1RVzi = 36 + INTEGER(IntKi), PARAMETER :: B1TAxi = 37 + INTEGER(IntKi), PARAMETER :: B1TAyi = 38 + INTEGER(IntKi), PARAMETER :: B1TAzi = 39 + INTEGER(IntKi), PARAMETER :: B1RAxi = 40 + INTEGER(IntKi), PARAMETER :: B1RAyi = 41 + INTEGER(IntKi), PARAMETER :: B1RAzi = 42 + INTEGER(IntKi), PARAMETER :: B2Surge = 43 + INTEGER(IntKi), PARAMETER :: B2Sway = 44 + INTEGER(IntKi), PARAMETER :: B2Heave = 45 + INTEGER(IntKi), PARAMETER :: B2Roll = 46 + INTEGER(IntKi), PARAMETER :: B2Pitch = 47 + INTEGER(IntKi), PARAMETER :: B2Yaw = 48 + INTEGER(IntKi), PARAMETER :: B2TVxi = 49 + INTEGER(IntKi), PARAMETER :: B2TVyi = 50 + INTEGER(IntKi), PARAMETER :: B2TVzi = 51 + INTEGER(IntKi), PARAMETER :: B2RVxi = 52 + INTEGER(IntKi), PARAMETER :: B2RVyi = 53 + INTEGER(IntKi), PARAMETER :: B2RVzi = 54 + INTEGER(IntKi), PARAMETER :: B2TAxi = 55 + INTEGER(IntKi), PARAMETER :: B2TAyi = 56 + INTEGER(IntKi), PARAMETER :: B2TAzi = 57 + INTEGER(IntKi), PARAMETER :: B2RAxi = 58 + INTEGER(IntKi), PARAMETER :: B2RAyi = 59 + INTEGER(IntKi), PARAMETER :: B2RAzi = 60 + INTEGER(IntKi), PARAMETER :: B3Surge = 61 + INTEGER(IntKi), PARAMETER :: B3Sway = 62 + INTEGER(IntKi), PARAMETER :: B3Heave = 63 + INTEGER(IntKi), PARAMETER :: B3Roll = 64 + INTEGER(IntKi), PARAMETER :: B3Pitch = 65 + INTEGER(IntKi), PARAMETER :: B3Yaw = 66 + INTEGER(IntKi), PARAMETER :: B3TVxi = 67 + INTEGER(IntKi), PARAMETER :: B3TVyi = 68 + INTEGER(IntKi), PARAMETER :: B3TVzi = 69 + INTEGER(IntKi), PARAMETER :: B3RVxi = 70 + INTEGER(IntKi), PARAMETER :: B3RVyi = 71 + INTEGER(IntKi), PARAMETER :: B3RVzi = 72 + INTEGER(IntKi), PARAMETER :: B3TAxi = 73 + INTEGER(IntKi), PARAMETER :: B3TAyi = 74 + INTEGER(IntKi), PARAMETER :: B3TAzi = 75 + INTEGER(IntKi), PARAMETER :: B3RAxi = 76 + INTEGER(IntKi), PARAMETER :: B3RAyi = 77 + INTEGER(IntKi), PARAMETER :: B3RAzi = 78 + INTEGER(IntKi), PARAMETER :: B4Surge = 79 + INTEGER(IntKi), PARAMETER :: B4Sway = 80 + INTEGER(IntKi), PARAMETER :: B4Heave = 81 + INTEGER(IntKi), PARAMETER :: B4Roll = 82 + INTEGER(IntKi), PARAMETER :: B4Pitch = 83 + INTEGER(IntKi), PARAMETER :: B4Yaw = 84 + INTEGER(IntKi), PARAMETER :: B4TVxi = 85 + INTEGER(IntKi), PARAMETER :: B4TVyi = 86 + INTEGER(IntKi), PARAMETER :: B4TVzi = 87 + INTEGER(IntKi), PARAMETER :: B4RVxi = 88 + INTEGER(IntKi), PARAMETER :: B4RVyi = 89 + INTEGER(IntKi), PARAMETER :: B4RVzi = 90 + INTEGER(IntKi), PARAMETER :: B4TAxi = 91 + INTEGER(IntKi), PARAMETER :: B4TAyi = 92 + INTEGER(IntKi), PARAMETER :: B4TAzi = 93 + INTEGER(IntKi), PARAMETER :: B4RAxi = 94 + INTEGER(IntKi), PARAMETER :: B4RAyi = 95 + INTEGER(IntKi), PARAMETER :: B4RAzi = 96 + INTEGER(IntKi), PARAMETER :: B5Surge = 97 + INTEGER(IntKi), PARAMETER :: B5Sway = 98 + INTEGER(IntKi), PARAMETER :: B5Heave = 99 + INTEGER(IntKi), PARAMETER :: B5Roll = 100 + INTEGER(IntKi), PARAMETER :: B5Pitch = 101 + INTEGER(IntKi), PARAMETER :: B5Yaw = 102 + INTEGER(IntKi), PARAMETER :: B5TVxi = 103 + INTEGER(IntKi), PARAMETER :: B5TVyi = 104 + INTEGER(IntKi), PARAMETER :: B5TVzi = 105 + INTEGER(IntKi), PARAMETER :: B5RVxi = 106 + INTEGER(IntKi), PARAMETER :: B5RVyi = 107 + INTEGER(IntKi), PARAMETER :: B5RVzi = 108 + INTEGER(IntKi), PARAMETER :: B5TAxi = 109 + INTEGER(IntKi), PARAMETER :: B5TAyi = 110 + INTEGER(IntKi), PARAMETER :: B5TAzi = 111 + INTEGER(IntKi), PARAMETER :: B5RAxi = 112 + INTEGER(IntKi), PARAMETER :: B5RAyi = 113 + INTEGER(IntKi), PARAMETER :: B5RAzi = 114 + INTEGER(IntKi), PARAMETER :: B6Surge = 115 + INTEGER(IntKi), PARAMETER :: B6Sway = 116 + INTEGER(IntKi), PARAMETER :: B6Heave = 117 + INTEGER(IntKi), PARAMETER :: B6Roll = 118 + INTEGER(IntKi), PARAMETER :: B6Pitch = 119 + INTEGER(IntKi), PARAMETER :: B6Yaw = 120 + INTEGER(IntKi), PARAMETER :: B6TVxi = 121 + INTEGER(IntKi), PARAMETER :: B6TVyi = 122 + INTEGER(IntKi), PARAMETER :: B6TVzi = 123 + INTEGER(IntKi), PARAMETER :: B6RVxi = 124 + INTEGER(IntKi), PARAMETER :: B6RVyi = 125 + INTEGER(IntKi), PARAMETER :: B6RVzi = 126 + INTEGER(IntKi), PARAMETER :: B6TAxi = 127 + INTEGER(IntKi), PARAMETER :: B6TAyi = 128 + INTEGER(IntKi), PARAMETER :: B6TAzi = 129 + INTEGER(IntKi), PARAMETER :: B6RAxi = 130 + INTEGER(IntKi), PARAMETER :: B6RAyi = 131 + INTEGER(IntKi), PARAMETER :: B6RAzi = 132 + INTEGER(IntKi), PARAMETER :: B7Surge = 133 + INTEGER(IntKi), PARAMETER :: B7Sway = 134 + INTEGER(IntKi), PARAMETER :: B7Heave = 135 + INTEGER(IntKi), PARAMETER :: B7Roll = 136 + INTEGER(IntKi), PARAMETER :: B7Pitch = 137 + INTEGER(IntKi), PARAMETER :: B7Yaw = 138 + INTEGER(IntKi), PARAMETER :: B7TVxi = 139 + INTEGER(IntKi), PARAMETER :: B7TVyi = 140 + INTEGER(IntKi), PARAMETER :: B7TVzi = 141 + INTEGER(IntKi), PARAMETER :: B7RVxi = 142 + INTEGER(IntKi), PARAMETER :: B7RVyi = 143 + INTEGER(IntKi), PARAMETER :: B7RVzi = 144 + INTEGER(IntKi), PARAMETER :: B7TAxi = 145 + INTEGER(IntKi), PARAMETER :: B7TAyi = 146 + INTEGER(IntKi), PARAMETER :: B7TAzi = 147 + INTEGER(IntKi), PARAMETER :: B7RAxi = 148 + INTEGER(IntKi), PARAMETER :: B7RAyi = 149 + INTEGER(IntKi), PARAMETER :: B7RAzi = 150 + INTEGER(IntKi), PARAMETER :: B8Surge = 151 + INTEGER(IntKi), PARAMETER :: B8Sway = 152 + INTEGER(IntKi), PARAMETER :: B8Heave = 153 + INTEGER(IntKi), PARAMETER :: B8Roll = 154 + INTEGER(IntKi), PARAMETER :: B8Pitch = 155 + INTEGER(IntKi), PARAMETER :: B8Yaw = 156 + INTEGER(IntKi), PARAMETER :: B8TVxi = 157 + INTEGER(IntKi), PARAMETER :: B8TVyi = 158 + INTEGER(IntKi), PARAMETER :: B8TVzi = 159 + INTEGER(IntKi), PARAMETER :: B8RVxi = 160 + INTEGER(IntKi), PARAMETER :: B8RVyi = 161 + INTEGER(IntKi), PARAMETER :: B8RVzi = 162 + INTEGER(IntKi), PARAMETER :: B8TAxi = 163 + INTEGER(IntKi), PARAMETER :: B8TAyi = 164 + INTEGER(IntKi), PARAMETER :: B8TAzi = 165 + INTEGER(IntKi), PARAMETER :: B8RAxi = 166 + INTEGER(IntKi), PARAMETER :: B8RAyi = 167 + INTEGER(IntKi), PARAMETER :: B8RAzi = 168 + INTEGER(IntKi), PARAMETER :: B9Surge = 169 + INTEGER(IntKi), PARAMETER :: B9Sway = 170 + INTEGER(IntKi), PARAMETER :: B9Heave = 171 + INTEGER(IntKi), PARAMETER :: B9Roll = 172 + INTEGER(IntKi), PARAMETER :: B9Pitch = 173 + INTEGER(IntKi), PARAMETER :: B9Yaw = 174 + INTEGER(IntKi), PARAMETER :: B9TVxi = 175 + INTEGER(IntKi), PARAMETER :: B9TVyi = 176 + INTEGER(IntKi), PARAMETER :: B9TVzi = 177 + INTEGER(IntKi), PARAMETER :: B9RVxi = 178 + INTEGER(IntKi), PARAMETER :: B9RVyi = 179 + INTEGER(IntKi), PARAMETER :: B9RVzi = 180 + INTEGER(IntKi), PARAMETER :: B9TAxi = 181 + INTEGER(IntKi), PARAMETER :: B9TAyi = 182 + INTEGER(IntKi), PARAMETER :: B9TAzi = 183 + INTEGER(IntKi), PARAMETER :: B9RAxi = 184 + INTEGER(IntKi), PARAMETER :: B9RAyi = 185 + INTEGER(IntKi), PARAMETER :: B9RAzi = 186 + + + ! WAMIT Body Forces: + + INTEGER(IntKi), PARAMETER :: B1AddFxi = 187 + INTEGER(IntKi), PARAMETER :: B1AddFyi = 188 + INTEGER(IntKi), PARAMETER :: B1AddFzi = 189 + INTEGER(IntKi), PARAMETER :: B1AddMxi = 190 + INTEGER(IntKi), PARAMETER :: B1AddMyi = 191 + INTEGER(IntKi), PARAMETER :: B1AddMzi = 192 + INTEGER(IntKi), PARAMETER :: B1WvsF1xi = 193 + INTEGER(IntKi), PARAMETER :: B1WvsF1yi = 194 + INTEGER(IntKi), PARAMETER :: B1WvsF1zi = 195 + INTEGER(IntKi), PARAMETER :: B1WvsM1xi = 196 + INTEGER(IntKi), PARAMETER :: B1WvsM1yi = 197 + INTEGER(IntKi), PARAMETER :: B1WvsM1zi = 198 + INTEGER(IntKi), PARAMETER :: B1WvsFxi = 199 + INTEGER(IntKi), PARAMETER :: B1WvsFyi = 200 + INTEGER(IntKi), PARAMETER :: B1WvsFzi = 201 + INTEGER(IntKi), PARAMETER :: B1WvsMxi = 202 + INTEGER(IntKi), PARAMETER :: B1WvsMyi = 203 + INTEGER(IntKi), PARAMETER :: B1WvsMzi = 204 + INTEGER(IntKi), PARAMETER :: B1HdSFxi = 205 + INTEGER(IntKi), PARAMETER :: B1HdSFyi = 206 + INTEGER(IntKi), PARAMETER :: B1HdSFzi = 207 + INTEGER(IntKi), PARAMETER :: B1HdSMxi = 208 + INTEGER(IntKi), PARAMETER :: B1HdSMyi = 209 + INTEGER(IntKi), PARAMETER :: B1HdSMzi = 210 + INTEGER(IntKi), PARAMETER :: B1RdtFxi = 211 + INTEGER(IntKi), PARAMETER :: B1RdtFyi = 212 + INTEGER(IntKi), PARAMETER :: B1RdtFzi = 213 + INTEGER(IntKi), PARAMETER :: B1RdtMxi = 214 + INTEGER(IntKi), PARAMETER :: B1RdtMyi = 215 + INTEGER(IntKi), PARAMETER :: B1RdtMzi = 216 + INTEGER(IntKi), PARAMETER :: B2AddFxi = 217 + INTEGER(IntKi), PARAMETER :: B2AddFyi = 218 + INTEGER(IntKi), PARAMETER :: B2AddFzi = 219 + INTEGER(IntKi), PARAMETER :: B2AddMxi = 220 + INTEGER(IntKi), PARAMETER :: B2AddMyi = 221 + INTEGER(IntKi), PARAMETER :: B2AddMzi = 222 + INTEGER(IntKi), PARAMETER :: B2WvsF1xi = 223 + INTEGER(IntKi), PARAMETER :: B2WvsF1yi = 224 + INTEGER(IntKi), PARAMETER :: B2WvsF1zi = 225 + INTEGER(IntKi), PARAMETER :: B2WvsM1xi = 226 + INTEGER(IntKi), PARAMETER :: B2WvsM1yi = 227 + INTEGER(IntKi), PARAMETER :: B2WvsM1zi = 228 + INTEGER(IntKi), PARAMETER :: B2WvsFxi = 229 + INTEGER(IntKi), PARAMETER :: B2WvsFyi = 230 + INTEGER(IntKi), PARAMETER :: B2WvsFzi = 231 + INTEGER(IntKi), PARAMETER :: B2WvsMxi = 232 + INTEGER(IntKi), PARAMETER :: B2WvsMyi = 233 + INTEGER(IntKi), PARAMETER :: B2WvsMzi = 234 + INTEGER(IntKi), PARAMETER :: B2HdSFxi = 235 + INTEGER(IntKi), PARAMETER :: B2HdSFyi = 236 + INTEGER(IntKi), PARAMETER :: B2HdSFzi = 237 + INTEGER(IntKi), PARAMETER :: B2HdSMxi = 238 + INTEGER(IntKi), PARAMETER :: B2HdSMyi = 239 + INTEGER(IntKi), PARAMETER :: B2HdSMzi = 240 + INTEGER(IntKi), PARAMETER :: B2RdtFxi = 241 + INTEGER(IntKi), PARAMETER :: B2RdtFyi = 242 + INTEGER(IntKi), PARAMETER :: B2RdtFzi = 243 + INTEGER(IntKi), PARAMETER :: B2RdtMxi = 244 + INTEGER(IntKi), PARAMETER :: B2RdtMyi = 245 + INTEGER(IntKi), PARAMETER :: B2RdtMzi = 246 + INTEGER(IntKi), PARAMETER :: B3AddFxi = 247 + INTEGER(IntKi), PARAMETER :: B3AddFyi = 248 + INTEGER(IntKi), PARAMETER :: B3AddFzi = 249 + INTEGER(IntKi), PARAMETER :: B3AddMxi = 250 + INTEGER(IntKi), PARAMETER :: B3AddMyi = 251 + INTEGER(IntKi), PARAMETER :: B3AddMzi = 252 + INTEGER(IntKi), PARAMETER :: B3WvsF1xi = 253 + INTEGER(IntKi), PARAMETER :: B3WvsF1yi = 254 + INTEGER(IntKi), PARAMETER :: B3WvsF1zi = 255 + INTEGER(IntKi), PARAMETER :: B3WvsM1xi = 256 + INTEGER(IntKi), PARAMETER :: B3WvsM1yi = 257 + INTEGER(IntKi), PARAMETER :: B3WvsM1zi = 258 + INTEGER(IntKi), PARAMETER :: B3WvsFxi = 259 + INTEGER(IntKi), PARAMETER :: B3WvsFyi = 260 + INTEGER(IntKi), PARAMETER :: B3WvsFzi = 261 + INTEGER(IntKi), PARAMETER :: B3WvsMxi = 262 + INTEGER(IntKi), PARAMETER :: B3WvsMyi = 263 + INTEGER(IntKi), PARAMETER :: B3WvsMzi = 264 + INTEGER(IntKi), PARAMETER :: B3HdSFxi = 265 + INTEGER(IntKi), PARAMETER :: B3HdSFyi = 266 + INTEGER(IntKi), PARAMETER :: B3HdSFzi = 267 + INTEGER(IntKi), PARAMETER :: B3HdSMxi = 268 + INTEGER(IntKi), PARAMETER :: B3HdSMyi = 269 + INTEGER(IntKi), PARAMETER :: B3HdSMzi = 270 + INTEGER(IntKi), PARAMETER :: B3RdtFxi = 271 + INTEGER(IntKi), PARAMETER :: B3RdtFyi = 272 + INTEGER(IntKi), PARAMETER :: B3RdtFzi = 273 + INTEGER(IntKi), PARAMETER :: B3RdtMxi = 274 + INTEGER(IntKi), PARAMETER :: B3RdtMyi = 275 + INTEGER(IntKi), PARAMETER :: B3RdtMzi = 276 + INTEGER(IntKi), PARAMETER :: B4AddFxi = 277 + INTEGER(IntKi), PARAMETER :: B4AddFyi = 278 + INTEGER(IntKi), PARAMETER :: B4AddFzi = 279 + INTEGER(IntKi), PARAMETER :: B4AddMxi = 280 + INTEGER(IntKi), PARAMETER :: B4AddMyi = 281 + INTEGER(IntKi), PARAMETER :: B4AddMzi = 282 + INTEGER(IntKi), PARAMETER :: B4WvsF1xi = 283 + INTEGER(IntKi), PARAMETER :: B4WvsF1yi = 284 + INTEGER(IntKi), PARAMETER :: B4WvsF1zi = 285 + INTEGER(IntKi), PARAMETER :: B4WvsM1xi = 286 + INTEGER(IntKi), PARAMETER :: B4WvsM1yi = 287 + INTEGER(IntKi), PARAMETER :: B4WvsM1zi = 288 + INTEGER(IntKi), PARAMETER :: B4WvsFxi = 289 + INTEGER(IntKi), PARAMETER :: B4WvsFyi = 290 + INTEGER(IntKi), PARAMETER :: B4WvsFzi = 291 + INTEGER(IntKi), PARAMETER :: B4WvsMxi = 292 + INTEGER(IntKi), PARAMETER :: B4WvsMyi = 293 + INTEGER(IntKi), PARAMETER :: B4WvsMzi = 294 + INTEGER(IntKi), PARAMETER :: B4HdSFxi = 295 + INTEGER(IntKi), PARAMETER :: B4HdSFyi = 296 + INTEGER(IntKi), PARAMETER :: B4HdSFzi = 297 + INTEGER(IntKi), PARAMETER :: B4HdSMxi = 298 + INTEGER(IntKi), PARAMETER :: B4HdSMyi = 299 + INTEGER(IntKi), PARAMETER :: B4HdSMzi = 300 + INTEGER(IntKi), PARAMETER :: B4RdtFxi = 301 + INTEGER(IntKi), PARAMETER :: B4RdtFyi = 302 + INTEGER(IntKi), PARAMETER :: B4RdtFzi = 303 + INTEGER(IntKi), PARAMETER :: B4RdtMxi = 304 + INTEGER(IntKi), PARAMETER :: B4RdtMyi = 305 + INTEGER(IntKi), PARAMETER :: B4RdtMzi = 306 + INTEGER(IntKi), PARAMETER :: B5AddFxi = 307 + INTEGER(IntKi), PARAMETER :: B5AddFyi = 308 + INTEGER(IntKi), PARAMETER :: B5AddFzi = 309 + INTEGER(IntKi), PARAMETER :: B5AddMxi = 310 + INTEGER(IntKi), PARAMETER :: B5AddMyi = 311 + INTEGER(IntKi), PARAMETER :: B5AddMzi = 312 + INTEGER(IntKi), PARAMETER :: B5WvsF1xi = 313 + INTEGER(IntKi), PARAMETER :: B5WvsF1yi = 314 + INTEGER(IntKi), PARAMETER :: B5WvsF1zi = 315 + INTEGER(IntKi), PARAMETER :: B5WvsM1xi = 316 + INTEGER(IntKi), PARAMETER :: B5WvsM1yi = 317 + INTEGER(IntKi), PARAMETER :: B5WvsM1zi = 318 + INTEGER(IntKi), PARAMETER :: B5WvsFxi = 319 + INTEGER(IntKi), PARAMETER :: B5WvsFyi = 320 + INTEGER(IntKi), PARAMETER :: B5WvsFzi = 321 + INTEGER(IntKi), PARAMETER :: B5WvsMxi = 322 + INTEGER(IntKi), PARAMETER :: B5WvsMyi = 323 + INTEGER(IntKi), PARAMETER :: B5WvsMzi = 324 + INTEGER(IntKi), PARAMETER :: B5HdSFxi = 325 + INTEGER(IntKi), PARAMETER :: B5HdSFyi = 326 + INTEGER(IntKi), PARAMETER :: B5HdSFzi = 327 + INTEGER(IntKi), PARAMETER :: B5HdSMxi = 328 + INTEGER(IntKi), PARAMETER :: B5HdSMyi = 329 + INTEGER(IntKi), PARAMETER :: B5HdSMzi = 330 + INTEGER(IntKi), PARAMETER :: B5RdtFxi = 331 + INTEGER(IntKi), PARAMETER :: B5RdtFyi = 332 + INTEGER(IntKi), PARAMETER :: B5RdtFzi = 333 + INTEGER(IntKi), PARAMETER :: B5RdtMxi = 334 + INTEGER(IntKi), PARAMETER :: B5RdtMyi = 335 + INTEGER(IntKi), PARAMETER :: B5RdtMzi = 336 + INTEGER(IntKi), PARAMETER :: B6AddFxi = 337 + INTEGER(IntKi), PARAMETER :: B6AddFyi = 338 + INTEGER(IntKi), PARAMETER :: B6AddFzi = 339 + INTEGER(IntKi), PARAMETER :: B6AddMxi = 340 + INTEGER(IntKi), PARAMETER :: B6AddMyi = 341 + INTEGER(IntKi), PARAMETER :: B6AddMzi = 342 + INTEGER(IntKi), PARAMETER :: B6WvsF1xi = 343 + INTEGER(IntKi), PARAMETER :: B6WvsF1yi = 344 + INTEGER(IntKi), PARAMETER :: B6WvsF1zi = 345 + INTEGER(IntKi), PARAMETER :: B6WvsM1xi = 346 + INTEGER(IntKi), PARAMETER :: B6WvsM1yi = 347 + INTEGER(IntKi), PARAMETER :: B6WvsM1zi = 348 + INTEGER(IntKi), PARAMETER :: B6WvsFxi = 349 + INTEGER(IntKi), PARAMETER :: B6WvsFyi = 350 + INTEGER(IntKi), PARAMETER :: B6WvsFzi = 351 + INTEGER(IntKi), PARAMETER :: B6WvsMxi = 352 + INTEGER(IntKi), PARAMETER :: B6WvsMyi = 353 + INTEGER(IntKi), PARAMETER :: B6WvsMzi = 354 + INTEGER(IntKi), PARAMETER :: B6HdSFxi = 355 + INTEGER(IntKi), PARAMETER :: B6HdSFyi = 356 + INTEGER(IntKi), PARAMETER :: B6HdSFzi = 357 + INTEGER(IntKi), PARAMETER :: B6HdSMxi = 358 + INTEGER(IntKi), PARAMETER :: B6HdSMyi = 359 + INTEGER(IntKi), PARAMETER :: B6HdSMzi = 360 + INTEGER(IntKi), PARAMETER :: B6RdtFxi = 361 + INTEGER(IntKi), PARAMETER :: B6RdtFyi = 362 + INTEGER(IntKi), PARAMETER :: B6RdtFzi = 363 + INTEGER(IntKi), PARAMETER :: B6RdtMxi = 364 + INTEGER(IntKi), PARAMETER :: B6RdtMyi = 365 + INTEGER(IntKi), PARAMETER :: B6RdtMzi = 366 + INTEGER(IntKi), PARAMETER :: B7AddFxi = 367 + INTEGER(IntKi), PARAMETER :: B7AddFyi = 368 + INTEGER(IntKi), PARAMETER :: B7AddFzi = 369 + INTEGER(IntKi), PARAMETER :: B7AddMxi = 370 + INTEGER(IntKi), PARAMETER :: B7AddMyi = 371 + INTEGER(IntKi), PARAMETER :: B7AddMzi = 372 + INTEGER(IntKi), PARAMETER :: B7WvsF1xi = 373 + INTEGER(IntKi), PARAMETER :: B7WvsF1yi = 374 + INTEGER(IntKi), PARAMETER :: B7WvsF1zi = 375 + INTEGER(IntKi), PARAMETER :: B7WvsM1xi = 376 + INTEGER(IntKi), PARAMETER :: B7WvsM1yi = 377 + INTEGER(IntKi), PARAMETER :: B7WvsM1zi = 378 + INTEGER(IntKi), PARAMETER :: B7WvsFxi = 379 + INTEGER(IntKi), PARAMETER :: B7WvsFyi = 380 + INTEGER(IntKi), PARAMETER :: B7WvsFzi = 381 + INTEGER(IntKi), PARAMETER :: B7WvsMxi = 382 + INTEGER(IntKi), PARAMETER :: B7WvsMyi = 383 + INTEGER(IntKi), PARAMETER :: B7WvsMzi = 384 + INTEGER(IntKi), PARAMETER :: B7HdSFxi = 385 + INTEGER(IntKi), PARAMETER :: B7HdSFyi = 386 + INTEGER(IntKi), PARAMETER :: B7HdSFzi = 387 + INTEGER(IntKi), PARAMETER :: B7HdSMxi = 388 + INTEGER(IntKi), PARAMETER :: B7HdSMyi = 389 + INTEGER(IntKi), PARAMETER :: B7HdSMzi = 390 + INTEGER(IntKi), PARAMETER :: B7RdtFxi = 391 + INTEGER(IntKi), PARAMETER :: B7RdtFyi = 392 + INTEGER(IntKi), PARAMETER :: B7RdtFzi = 393 + INTEGER(IntKi), PARAMETER :: B7RdtMxi = 394 + INTEGER(IntKi), PARAMETER :: B7RdtMyi = 395 + INTEGER(IntKi), PARAMETER :: B7RdtMzi = 396 + INTEGER(IntKi), PARAMETER :: B8AddFxi = 397 + INTEGER(IntKi), PARAMETER :: B8AddFyi = 398 + INTEGER(IntKi), PARAMETER :: B8AddFzi = 399 + INTEGER(IntKi), PARAMETER :: B8AddMxi = 400 + INTEGER(IntKi), PARAMETER :: B8AddMyi = 401 + INTEGER(IntKi), PARAMETER :: B8AddMzi = 402 + INTEGER(IntKi), PARAMETER :: B8WvsF1xi = 403 + INTEGER(IntKi), PARAMETER :: B8WvsF1yi = 404 + INTEGER(IntKi), PARAMETER :: B8WvsF1zi = 405 + INTEGER(IntKi), PARAMETER :: B8WvsM1xi = 406 + INTEGER(IntKi), PARAMETER :: B8WvsM1yi = 407 + INTEGER(IntKi), PARAMETER :: B8WvsM1zi = 408 + INTEGER(IntKi), PARAMETER :: B8WvsFxi = 409 + INTEGER(IntKi), PARAMETER :: B8WvsFyi = 410 + INTEGER(IntKi), PARAMETER :: B8WvsFzi = 411 + INTEGER(IntKi), PARAMETER :: B8WvsMxi = 412 + INTEGER(IntKi), PARAMETER :: B8WvsMyi = 413 + INTEGER(IntKi), PARAMETER :: B8WvsMzi = 414 + INTEGER(IntKi), PARAMETER :: B8HdSFxi = 415 + INTEGER(IntKi), PARAMETER :: B8HdSFyi = 416 + INTEGER(IntKi), PARAMETER :: B8HdSFzi = 417 + INTEGER(IntKi), PARAMETER :: B8HdSMxi = 418 + INTEGER(IntKi), PARAMETER :: B8HdSMyi = 419 + INTEGER(IntKi), PARAMETER :: B8HdSMzi = 420 + INTEGER(IntKi), PARAMETER :: B8RdtFxi = 421 + INTEGER(IntKi), PARAMETER :: B8RdtFyi = 422 + INTEGER(IntKi), PARAMETER :: B8RdtFzi = 423 + INTEGER(IntKi), PARAMETER :: B8RdtMxi = 424 + INTEGER(IntKi), PARAMETER :: B8RdtMyi = 425 + INTEGER(IntKi), PARAMETER :: B8RdtMzi = 426 + INTEGER(IntKi), PARAMETER :: B9AddFxi = 427 + INTEGER(IntKi), PARAMETER :: B9AddFyi = 428 + INTEGER(IntKi), PARAMETER :: B9AddFzi = 429 + INTEGER(IntKi), PARAMETER :: B9AddMxi = 430 + INTEGER(IntKi), PARAMETER :: B9AddMyi = 431 + INTEGER(IntKi), PARAMETER :: B9AddMzi = 432 + INTEGER(IntKi), PARAMETER :: B9WvsF1xi = 433 + INTEGER(IntKi), PARAMETER :: B9WvsF1yi = 434 + INTEGER(IntKi), PARAMETER :: B9WvsF1zi = 435 + INTEGER(IntKi), PARAMETER :: B9WvsM1xi = 436 + INTEGER(IntKi), PARAMETER :: B9WvsM1yi = 437 + INTEGER(IntKi), PARAMETER :: B9WvsM1zi = 438 + INTEGER(IntKi), PARAMETER :: B9WvsFxi = 439 + INTEGER(IntKi), PARAMETER :: B9WvsFyi = 440 + INTEGER(IntKi), PARAMETER :: B9WvsFzi = 441 + INTEGER(IntKi), PARAMETER :: B9WvsMxi = 442 + INTEGER(IntKi), PARAMETER :: B9WvsMyi = 443 + INTEGER(IntKi), PARAMETER :: B9WvsMzi = 444 + INTEGER(IntKi), PARAMETER :: B9HdSFxi = 445 + INTEGER(IntKi), PARAMETER :: B9HdSFyi = 446 + INTEGER(IntKi), PARAMETER :: B9HdSFzi = 447 + INTEGER(IntKi), PARAMETER :: B9HdSMxi = 448 + INTEGER(IntKi), PARAMETER :: B9HdSMyi = 449 + INTEGER(IntKi), PARAMETER :: B9HdSMzi = 450 + INTEGER(IntKi), PARAMETER :: B9RdtFxi = 451 + INTEGER(IntKi), PARAMETER :: B9RdtFyi = 452 + INTEGER(IntKi), PARAMETER :: B9RdtFzi = 453 + INTEGER(IntKi), PARAMETER :: B9RdtMxi = 454 + INTEGER(IntKi), PARAMETER :: B9RdtMyi = 455 + INTEGER(IntKi), PARAMETER :: B9RdtMzi = 456 + INTEGER(IntKi), PARAMETER :: B1WvsF2xi = 457 + INTEGER(IntKi), PARAMETER :: B1WvsF2yi = 458 + INTEGER(IntKi), PARAMETER :: B1WvsF2zi = 459 + INTEGER(IntKi), PARAMETER :: B1WvsM2xi = 460 + INTEGER(IntKi), PARAMETER :: B1WvsM2yi = 461 + INTEGER(IntKi), PARAMETER :: B1WvsM2zi = 462 + INTEGER(IntKi), PARAMETER :: B2WvsF2xi = 463 + INTEGER(IntKi), PARAMETER :: B2WvsF2yi = 464 + INTEGER(IntKi), PARAMETER :: B2WvsF2zi = 465 + INTEGER(IntKi), PARAMETER :: B2WvsM2xi = 466 + INTEGER(IntKi), PARAMETER :: B2WvsM2yi = 467 + INTEGER(IntKi), PARAMETER :: B2WvsM2zi = 468 + INTEGER(IntKi), PARAMETER :: B3WvsF2xi = 469 + INTEGER(IntKi), PARAMETER :: B3WvsF2yi = 470 + INTEGER(IntKi), PARAMETER :: B3WvsF2zi = 471 + INTEGER(IntKi), PARAMETER :: B3WvsM2xi = 472 + INTEGER(IntKi), PARAMETER :: B3WvsM2yi = 473 + INTEGER(IntKi), PARAMETER :: B3WvsM2zi = 474 + INTEGER(IntKi), PARAMETER :: B4WvsF2xi = 475 + INTEGER(IntKi), PARAMETER :: B4WvsF2yi = 476 + INTEGER(IntKi), PARAMETER :: B4WvsF2zi = 477 + INTEGER(IntKi), PARAMETER :: B4WvsM2xi = 478 + INTEGER(IntKi), PARAMETER :: B4WvsM2yi = 479 + INTEGER(IntKi), PARAMETER :: B4WvsM2zi = 480 + INTEGER(IntKi), PARAMETER :: B5WvsF2xi = 481 + INTEGER(IntKi), PARAMETER :: B5WvsF2yi = 482 + INTEGER(IntKi), PARAMETER :: B5WvsF2zi = 483 + INTEGER(IntKi), PARAMETER :: B5WvsM2xi = 484 + INTEGER(IntKi), PARAMETER :: B5WvsM2yi = 485 + INTEGER(IntKi), PARAMETER :: B5WvsM2zi = 486 + INTEGER(IntKi), PARAMETER :: B6WvsF2xi = 487 + INTEGER(IntKi), PARAMETER :: B6WvsF2yi = 488 + INTEGER(IntKi), PARAMETER :: B6WvsF2zi = 489 + INTEGER(IntKi), PARAMETER :: B6WvsM2xi = 490 + INTEGER(IntKi), PARAMETER :: B6WvsM2yi = 491 + INTEGER(IntKi), PARAMETER :: B6WvsM2zi = 492 + INTEGER(IntKi), PARAMETER :: B7WvsF2xi = 493 + INTEGER(IntKi), PARAMETER :: B7WvsF2yi = 494 + INTEGER(IntKi), PARAMETER :: B7WvsF2zi = 495 + INTEGER(IntKi), PARAMETER :: B7WvsM2xi = 496 + INTEGER(IntKi), PARAMETER :: B7WvsM2yi = 497 + INTEGER(IntKi), PARAMETER :: B7WvsM2zi = 498 + INTEGER(IntKi), PARAMETER :: B8WvsF2xi = 499 + INTEGER(IntKi), PARAMETER :: B8WvsF2yi = 500 + INTEGER(IntKi), PARAMETER :: B8WvsF2zi = 501 + INTEGER(IntKi), PARAMETER :: B8WvsM2xi = 502 + INTEGER(IntKi), PARAMETER :: B8WvsM2yi = 503 + INTEGER(IntKi), PARAMETER :: B8WvsM2zi = 504 + INTEGER(IntKi), PARAMETER :: B9WvsF2xi = 505 + INTEGER(IntKi), PARAMETER :: B9WvsF2yi = 506 + INTEGER(IntKi), PARAMETER :: B9WvsF2zi = 507 + INTEGER(IntKi), PARAMETER :: B9WvsM2xi = 508 + INTEGER(IntKi), PARAMETER :: B9WvsM2yi = 509 + INTEGER(IntKi), PARAMETER :: B9WvsM2zi = 510 + + + ! Wave Elevations: + + INTEGER(IntKi), PARAMETER :: Wave1Elev = 511 + INTEGER(IntKi), PARAMETER :: Wave2Elev = 512 + INTEGER(IntKi), PARAMETER :: Wave3Elev = 513 + INTEGER(IntKi), PARAMETER :: Wave4Elev = 514 + INTEGER(IntKi), PARAMETER :: Wave5Elev = 515 + INTEGER(IntKi), PARAMETER :: Wave6Elev = 516 + INTEGER(IntKi), PARAMETER :: Wave7Elev = 517 + INTEGER(IntKi), PARAMETER :: Wave8Elev = 518 + INTEGER(IntKi), PARAMETER :: Wave9Elev = 519 + INTEGER(IntKi), PARAMETER :: Wave1Elv1 = 520 + INTEGER(IntKi), PARAMETER :: Wave2Elv1 = 521 + INTEGER(IntKi), PARAMETER :: Wave3Elv1 = 522 + INTEGER(IntKi), PARAMETER :: Wave4Elv1 = 523 + INTEGER(IntKi), PARAMETER :: Wave5Elv1 = 524 + INTEGER(IntKi), PARAMETER :: Wave6Elv1 = 525 + INTEGER(IntKi), PARAMETER :: Wave7Elv1 = 526 + INTEGER(IntKi), PARAMETER :: Wave8Elv1 = 527 + INTEGER(IntKi), PARAMETER :: Wave9Elv1 = 528 + INTEGER(IntKi), PARAMETER :: Wave1Elv2 = 529 + INTEGER(IntKi), PARAMETER :: Wave2Elv2 = 530 + INTEGER(IntKi), PARAMETER :: Wave3Elv2 = 531 + INTEGER(IntKi), PARAMETER :: Wave4Elv2 = 532 + INTEGER(IntKi), PARAMETER :: Wave5Elv2 = 533 + INTEGER(IntKi), PARAMETER :: Wave6Elv2 = 534 + INTEGER(IntKi), PARAMETER :: Wave7Elv2 = 535 + INTEGER(IntKi), PARAMETER :: Wave8Elv2 = 536 + INTEGER(IntKi), PARAMETER :: Wave9Elv2 = 537 + + + ! The maximum number of output channels which can be output by the code. + INTEGER(IntKi), PARAMETER :: MaxOutPts = 537 + +!End of code generated by Matlab script +! =================================================================================================== + + REAL(ReKi) :: AllOuts(MaxHDOutputs) ! Array of all possible outputs + INTEGER, PARAMETER :: FHydro(6) = (/HydroFxi,HydroFyi,HydroFzi,HydroMxi,HydroMyi,HydroMzi/) - INTEGER, PARAMETER :: FAdd(6) = (/AddFxi,AddFyi,AddFzi,AddMxi,AddMyi,AddMzi/) - INTEGER, PARAMETER :: FWavesTot(6) = (/WavesFxi,WavesFyi,WavesFzi,WavesMxi,WavesMyi,WavesMzi/) - INTEGER, PARAMETER :: WRPMotions(6) = (/WRPSurge,WRPSway,WRPHeave,WRPRoll,WRPPitch,WRPYaw/) - INTEGER, PARAMETER :: WRPVel(6) = (/WRPTVxi,WRPTVyi,WRPTVzi,WRPRVxi,WRPRVyi,WRPRVzi/) - INTEGER, PARAMETER :: WRPAcc(6) = (/WRPTAxi,WRPTAyi,WRPTAzi,WRPRAxi,WRPRAyi,WRPRAzi/) + + INTEGER, PARAMETER :: FAdd(6,9) = transpose(reshape((/B1AddFxi,B2AddFxi,B3AddFxi,B4AddFxi,B5AddFxi,B6AddFxi,B7AddFxi,B8AddFxi,B9AddFxi, & + B1AddFyi,B2AddFyi,B3AddFyi,B4AddFyi,B5AddFyi,B6AddFyi,B7AddFyi,B8AddFyi,B9AddFyi, & + B1AddFzi,B2AddFzi,B3AddFzi,B4AddFzi,B5AddFzi,B6AddFzi,B7AddFzi,B8AddFzi,B9AddFzi, & + B1AddMxi,B2AddMxi,B3AddMxi,B4AddMxi,B5AddMxi,B6AddMxi,B7AddMxi,B8AddMxi,B9AddMxi, & + B1AddMyi,B2AddMyi,B3AddMyi,B4AddMyi,B5AddMyi,B6AddMyi,B7AddMyi,B8AddMyi,B9AddMyi, & + B1AddMzi,B2AddMzi,B3AddMzi,B4AddMzi,B5AddMzi,B6AddMzi,B7AddMzi,B8AddMzi,B9AddMzi/), & + (/9,6/))) + INTEGER, PARAMETER :: FWaves1(6,9) = transpose(reshape((/B1WvsF1xi,B2WvsF1xi,B3WvsF1xi,B4WvsF1xi,B5WvsF1xi,B6WvsF1xi,B7WvsF1xi,B8WvsF1xi,B9WvsF1xi, & + B1WvsF1yi,B2WvsF1yi,B3WvsF1yi,B4WvsF1yi,B5WvsF1yi,B6WvsF1yi,B7WvsF1yi,B8WvsF1yi,B9WvsF1yi, & + B1WvsF1zi,B2WvsF1zi,B3WvsF1zi,B4WvsF1zi,B5WvsF1zi,B6WvsF1zi,B7WvsF1zi,B8WvsF1zi,B9WvsF1zi, & + B1WvsM1xi,B2WvsM1xi,B3WvsM1xi,B4WvsM1xi,B5WvsM1xi,B6WvsM1xi,B7WvsM1xi,B8WvsM1xi,B9WvsM1xi, & + B1WvsM1yi,B2WvsM1yi,B3WvsM1yi,B4WvsM1yi,B5WvsM1yi,B6WvsM1yi,B7WvsM1yi,B8WvsM1yi,B9WvsM1yi, & + B1WvsM1zi,B2WvsM1zi,B3WvsM1zi,B4WvsM1zi,B5WvsM1zi,B6WvsM1zi,B7WvsM1zi,B8WvsM1zi,B9WvsM1zi/), & + (/9,6/))) + INTEGER, PARAMETER :: FWaves2(6,9) = transpose(reshape((/B1WvsF2xi,B2WvsF2xi,B3WvsF2xi,B4WvsF2xi,B5WvsF2xi,B6WvsF2xi,B7WvsF2xi,B8WvsF2xi,B9WvsF2xi, & + B1WvsF2yi,B2WvsF2yi,B3WvsF2yi,B4WvsF2yi,B5WvsF2yi,B6WvsF2yi,B7WvsF2yi,B8WvsF2yi,B9WvsF2yi, & + B1WvsF2zi,B2WvsF2zi,B3WvsF2zi,B4WvsF2zi,B5WvsF2zi,B6WvsF2zi,B7WvsF2zi,B8WvsF2zi,B9WvsF2zi, & + B1WvsM2xi,B2WvsM2xi,B3WvsM2xi,B4WvsM2xi,B5WvsM2xi,B6WvsM2xi,B7WvsM2xi,B8WvsM2xi,B9WvsM2xi, & + B1WvsM2yi,B2WvsM2yi,B3WvsM2yi,B4WvsM2yi,B5WvsM2yi,B6WvsM2yi,B7WvsM2yi,B8WvsM2yi,B9WvsM2yi, & + B1WvsM2zi,B2WvsM2zi,B3WvsM2zi,B4WvsM2zi,B5WvsM2zi,B6WvsM2zi,B7WvsM2zi,B8WvsM2zi,B9WvsM2zi/), & + (/9,6/))) + INTEGER, PARAMETER :: FWavesTot(6,9)= transpose(reshape((/B1WvsFxi,B2WvsFxi,B3WvsFxi,B4WvsFxi,B5WvsFxi,B6WvsFxi,B7WvsFxi,B8WvsFxi,B9WvsFxi, & + B1WvsFyi,B2WvsFyi,B3WvsFyi,B4WvsFyi,B5WvsFyi,B6WvsFyi,B7WvsFyi,B8WvsFyi,B9WvsFyi, & + B1WvsFzi,B2WvsFzi,B3WvsFzi,B4WvsFzi,B5WvsFzi,B6WvsFzi,B7WvsFzi,B8WvsFzi,B9WvsFzi, & + B1WvsMxi,B2WvsMxi,B3WvsMxi,B4WvsMxi,B5WvsMxi,B6WvsMxi,B7WvsMxi,B8WvsMxi,B9WvsMxi, & + B1WvsMyi,B2WvsMyi,B3WvsMyi,B4WvsMyi,B5WvsMyi,B6WvsMyi,B7WvsMyi,B8WvsMyi,B9WvsMyi, & + B1WvsMzi,B2WvsMzi,B3WvsMzi,B4WvsMzi,B5WvsMzi,B6WvsMzi,B7WvsMzi,B8WvsMzi,B9WvsMzi/), & + (/9,6/))) + INTEGER, PARAMETER :: FHdrSttc(6,9) = transpose(reshape((/B1HdSFxi,B2HdSFxi,B3HdSFxi,B4HdSFxi,B5HdSFxi,B6HdSFxi,B7HdSFxi,B8HdSFxi,B9HdSFxi, & + B1HdSFyi,B2HdSFyi,B3HdSFyi,B4HdSFyi,B5HdSFyi,B6HdSFyi,B7HdSFyi,B8HdSFyi,B9HdSFyi, & + B1HdSFzi,B2HdSFzi,B3HdSFzi,B4HdSFzi,B5HdSFzi,B6HdSFzi,B7HdSFzi,B8HdSFzi,B9HdSFzi, & + B1HdSMxi,B2HdSMxi,B3HdSMxi,B4HdSMxi,B5HdSMxi,B6HdSMxi,B7HdSMxi,B8HdSMxi,B9HdSMxi, & + B1HdSMyi,B2HdSMyi,B3HdSMyi,B4HdSMyi,B5HdSMyi,B6HdSMyi,B7HdSMyi,B8HdSMyi,B9HdSMyi, & + B1HdSMzi,B2HdSMzi,B3HdSMzi,B4HdSMzi,B5HdSMzi,B6HdSMzi,B7HdSMzi,B8HdSMzi,B9HdSMzi/), & + (/9,6/))) + INTEGER, PARAMETER :: FRdtn(6,9) = transpose(reshape((/B1RdtFxi,B2RdtFxi,B3RdtFxi,B4RdtFxi,B5RdtFxi,B6RdtFxi,B7RdtFxi,B8RdtFxi,B9RdtFxi, & + B1RdtFyi,B2RdtFyi,B3RdtFyi,B4RdtFyi,B5RdtFyi,B6RdtFyi,B7RdtFyi,B8RdtFyi,B9RdtFyi, & + B1RdtFzi,B2RdtFzi,B3RdtFzi,B4RdtFzi,B5RdtFzi,B6RdtFzi,B7RdtFzi,B8RdtFzi,B9RdtFzi, & + B1RdtMxi,B2RdtMxi,B3RdtMxi,B4RdtMxi,B5RdtMxi,B6RdtMxi,B7RdtMxi,B8RdtMxi,B9RdtMxi, & + B1RdtMyi,B2RdtMyi,B3RdtMyi,B4RdtMyi,B5RdtMyi,B6RdtMyi,B7RdtMyi,B8RdtMyi,B9RdtMyi, & + B1RdtMzi,B2RdtMzi,B3RdtMzi,B4RdtMzi,B5RdtMzi,B6RdtMzi,B7RdtMzi,B8RdtMzi,B9RdtMzi/), & + (/9,6/))) + + INTEGER, PARAMETER :: WBMotions(6,9) = transpose(reshape((/B1Surge,B2Surge,B3Surge,B4Surge,B5Surge,B6Surge,B7Surge,B8Surge,B9Surge, & + B1Sway ,B2Sway ,B3Sway ,B4Sway ,B5Sway ,B6Sway ,B7Sway ,B8Sway ,B9Sway , & + B1Heave,B2Heave,B3Heave,B4Heave,B5Heave,B6Heave,B7Heave,B8Heave,B9Heave, & + B1Roll ,B2Roll ,B3Roll ,B4Roll ,B5Roll ,B6Roll ,B7Roll ,B8Roll ,B9Roll , & + B1Pitch,B2Pitch,B3Pitch,B4Pitch,B5Pitch,B6Pitch,B7Pitch,B8Pitch,B9Pitch, & + B1Yaw ,B2Yaw ,B3Yaw ,B4Yaw ,B5Yaw ,B6Yaw ,B7Yaw ,B8Yaw ,B9Yaw /), & + (/9,6/))) + + INTEGER, PARAMETER :: WBVel(6,9) = transpose(reshape((/B1TVxi,B2TVxi,B3TVxi,B4TVxi,B5TVxi,B6TVxi,B7TVxi,B8TVxi,B9TVxi, & + B1TVyi,B2TVyi,B3TVyi,B4TVyi,B5TVyi,B6TVyi,B7TVyi,B8TVyi,B9TVyi, & + B1TVzi,B2TVzi,B3TVzi,B4TVzi,B5TVzi,B6TVzi,B7TVzi,B8TVzi,B9TVzi, & + B1RVxi,B2RVxi,B3RVxi,B4RVxi,B5RVxi,B6RVxi,B7RVxi,B8RVxi,B9RVxi, & + B1RVyi,B2RVyi,B3RVyi,B4RVyi,B5RVyi,B6RVyi,B7RVyi,B8RVyi,B9RVyi, & + B1RVzi,B2RVzi,B3RVzi,B4RVzi,B5RVzi,B6RVzi,B7RVzi,B8RVzi,B9RVzi/), & + (/9,6/))) + + INTEGER, PARAMETER :: WBAcc(6,9) = transpose(reshape((/B1TAxi,B2TAxi,B3TAxi,B4TAxi,B5TAxi,B6TAxi,B7TAxi,B8TAxi,B9TAxi, & + B1TAyi,B2TAyi,B3TAyi,B4TAyi,B5TAyi,B6TAyi,B7TAyi,B8TAyi,B9TAyi, & + B1TAzi,B2TAzi,B3TAzi,B4TAzi,B5TAzi,B6TAzi,B7TAzi,B8TAzi,B9TAzi, & + B1RAxi,B2RAxi,B3RAxi,B4RAxi,B5RAxi,B6RAxi,B7RAxi,B8RAxi,B9RAxi, & + B1RAyi,B2RAyi,B3RAyi,B4RAyi,B5RAyi,B6RAyi,B7RAyi,B8RAyi,B9RAyi, & + B1RAzi,B2RAzi,B3RAzi,B4RAzi,B5RAzi,B6RAzi,B7RAzi,B8RAzi,B9RAzi/), & + (/9,6/))) + INTEGER, PARAMETER :: WaveElevi(9) = (/Wave1Elev,Wave2Elev,Wave3Elev,Wave4Elev,Wave5Elev,Wave6Elev,Wave7Elev,Wave8Elev,Wave9Elev/) INTEGER, PARAMETER :: WaveElevi1(9) = (/Wave1Elv1,Wave2Elv1,Wave3Elv1,Wave4Elv1,Wave5Elv1,Wave6Elv1,Wave7Elv1,Wave8Elv1,Wave9Elv1/) + INTEGER, PARAMETER :: WaveElevi2(9) = (/Wave1Elv2,Wave2Elv2,Wave3Elv2,Wave4Elv2,Wave5Elv2,Wave6Elv2,Wave7Elv2,Wave8Elv2,Wave9Elv2/) + + INTEGER, PARAMETER :: PRPMotions(6) = (/PRPSurge,PRPSway,PRPHeave,PRPRoll,PRPPitch,PRPYaw/) + INTEGER, PARAMETER :: PRPVel(6) = (/PRPTVxi, PRPTVyi,PRPTVzi, PRPRVxi,PRPRVyi, PRPRVzi/) + INTEGER, PARAMETER :: PRPAcc(6) = (/PRPTAxi, PRPTAyi,PRPTAzi, PRPRAxi,PRPRAyi, PRPRAzi/) - CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(54) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically - "ADDFXI ","ADDFYI ","ADDFZI ","ADDMXI ","ADDMYI ","ADDMZI ", & - "HYDROFXI ","HYDROFYI ","HYDROFZI ","HYDROMXI ","HYDROMYI ","HYDROMZI ", & - "WAVE1ELEV","WAVE1ELV1", & - "WAVE2ELEV","WAVE2ELV1", & - "WAVE3ELEV","WAVE3ELV1", & - "WAVE4ELEV","WAVE4ELV1", & - "WAVE5ELEV","WAVE5ELV1", & - "WAVE6ELEV","WAVE6ELV1", & - "WAVE7ELEV","WAVE7ELV1", & - "WAVE8ELEV","WAVE8ELV1", & - "WAVE9ELEV","WAVE9ELV1", & - "WAVESFXI ","WAVESFYI ","WAVESFZI ","WAVESMXI ","WAVESMYI ","WAVESMZI ", & - "WRPHEAVE ","WRPPITCH ","WRPRAXI ","WRPRAYI ","WRPRAZI ","WRPROLL ", & - "WRPRVXI ","WRPRVYI ","WRPRVZI ","WRPSURGE ","WRPSWAY ","WRPTAXI ", & - "WRPTAYI ","WRPTAZI ","WRPTVXI ","WRPTVYI ","WRPTVZI ","WRPYAW "/) - INTEGER(IntKi), PARAMETER :: ParamIndxAry(54) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) - AddFxi , AddFyi , AddFzi , AddMxi , AddMyi , AddMzi , & - HydroFxi , HydroFyi , HydroFzi , HydroMxi , HydroMyi , HydroMzi , & - Wave1Elev , Wave1Elv1 , & - Wave2Elev , Wave2Elv1 , & - Wave3Elev , Wave3Elv1 , & - Wave4Elev , Wave4Elv1 , & - Wave5Elev , Wave5Elv1 , & - Wave6Elev , Wave6Elv1 , & - Wave7Elev , Wave7Elv1 , & - Wave8Elev , Wave8Elv1 , & - Wave9Elev , Wave9Elv1 , & - WavesFxi , WavesFyi , WavesFzi , WavesMxi , WavesMyi , WavesMzi , & - WRPHeave , WRPPitch , WRPRAxi , WRPRAyi , WRPRAzi , WRPRoll , & - WRPRVxi , WRPRVyi , WRPRVzi , WRPSurge , WRPSway , WRPTAxi , & - WRPTAyi , WRPTAzi , WRPTVxi , WRPTVyi , WRPTVzi , WRPYaw /) - CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(54) = (/ & ! This lists the units corresponding to the allowed parameters - "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & - "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & - "(m) ","(m) ", & - "(m) ","(m) ", & - "(m) ","(m) ", & - "(m) ","(m) ", & - "(m) ","(m) ", & - "(m) ","(m) ", & - "(m) ","(m) ", & - "(m) ","(m) ", & - "(m) ","(m) ", & - "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & - "(m) ","(rad) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & - "(rad/s) ","(rad/s) ","(rad/s) ","(m) ","(m) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(rad) "/) - - - REAL(ReKi) :: AllOuts(MaxHDOutputs) ! Array of all possible outputs - + + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(537) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "B1ADDFXI ","B1ADDFYI ","B1ADDFZI ","B1ADDMXI ","B1ADDMYI ","B1ADDMZI ","B1HDSFXI ","B1HDSFYI ", & + "B1HDSFZI ","B1HDSMXI ","B1HDSMYI ","B1HDSMZI ","B1HEAVE ","B1PITCH ","B1RAXI ","B1RAYI ", & + "B1RAZI ","B1RDTFXI ","B1RDTFYI ","B1RDTFZI ","B1RDTMXI ","B1RDTMYI ","B1RDTMZI ","B1ROLL ", & + "B1RVXI ","B1RVYI ","B1RVZI ","B1SURGE ","B1SWAY ","B1TAXI ","B1TAYI ","B1TAZI ", & + "B1TVXI ","B1TVYI ","B1TVZI ","B1WVSF1XI","B1WVSF1YI","B1WVSF1ZI","B1WVSF2XI","B1WVSF2YI", & + "B1WVSF2ZI","B1WVSFXI ","B1WVSFYI ","B1WVSFZI ","B1WVSM1XI","B1WVSM1YI","B1WVSM1ZI","B1WVSM2XI", & + "B1WVSM2YI","B1WVSM2ZI","B1WVSMXI ","B1WVSMYI ","B1WVSMZI ","B1YAW ","B2ADDFXI ","B2ADDFYI ", & + "B2ADDFZI ","B2ADDMXI ","B2ADDMYI ","B2ADDMZI ","B2HDSFXI ","B2HDSFYI ","B2HDSFZI ","B2HDSMXI ", & + "B2HDSMYI ","B2HDSMZI ","B2HEAVE ","B2PITCH ","B2RAXI ","B2RAYI ","B2RAZI ","B2RDTFXI ", & + "B2RDTFYI ","B2RDTFZI ","B2RDTMXI ","B2RDTMYI ","B2RDTMZI ","B2ROLL ","B2RVXI ","B2RVYI ", & + "B2RVZI ","B2SURGE ","B2SWAY ","B2TAXI ","B2TAYI ","B2TAZI ","B2TVXI ","B2TVYI ", & + "B2TVZI ","B2WVSF1XI","B2WVSF1YI","B2WVSF1ZI","B2WVSF2XI","B2WVSF2YI","B2WVSF2ZI","B2WVSFXI ", & + "B2WVSFYI ","B2WVSFZI ","B2WVSM1XI","B2WVSM1YI","B2WVSM1ZI","B2WVSM2XI","B2WVSM2YI","B2WVSM2ZI", & + "B2WVSMXI ","B2WVSMYI ","B2WVSMZI ","B2YAW ","B3ADDFXI ","B3ADDFYI ","B3ADDFZI ","B3ADDMXI ", & + "B3ADDMYI ","B3ADDMZI ","B3HDSFXI ","B3HDSFYI ","B3HDSFZI ","B3HDSMXI ","B3HDSMYI ","B3HDSMZI ", & + "B3HEAVE ","B3PITCH ","B3RAXI ","B3RAYI ","B3RAZI ","B3RDTFXI ","B3RDTFYI ","B3RDTFZI ", & + "B3RDTMXI ","B3RDTMYI ","B3RDTMZI ","B3ROLL ","B3RVXI ","B3RVYI ","B3RVZI ","B3SURGE ", & + "B3SWAY ","B3TAXI ","B3TAYI ","B3TAZI ","B3TVXI ","B3TVYI ","B3TVZI ","B3WVSF1XI", & + "B3WVSF1YI","B3WVSF1ZI","B3WVSF2XI","B3WVSF2YI","B3WVSF2ZI","B3WVSFXI ","B3WVSFYI ","B3WVSFZI ", & + "B3WVSM1XI","B3WVSM1YI","B3WVSM1ZI","B3WVSM2XI","B3WVSM2YI","B3WVSM2ZI","B3WVSMXI ","B3WVSMYI ", & + "B3WVSMZI ","B3YAW ","B4ADDFXI ","B4ADDFYI ","B4ADDFZI ","B4ADDMXI ","B4ADDMYI ","B4ADDMZI ", & + "B4HDSFXI ","B4HDSFYI ","B4HDSFZI ","B4HDSMXI ","B4HDSMYI ","B4HDSMZI ","B4HEAVE ","B4PITCH ", & + "B4RAXI ","B4RAYI ","B4RAZI ","B4RDTFXI ","B4RDTFYI ","B4RDTFZI ","B4RDTMXI ","B4RDTMYI ", & + "B4RDTMZI ","B4ROLL ","B4RVXI ","B4RVYI ","B4RVZI ","B4SURGE ","B4SWAY ","B4TAXI ", & + "B4TAYI ","B4TAZI ","B4TVXI ","B4TVYI ","B4TVZI ","B4WVSF1XI","B4WVSF1YI","B4WVSF1ZI", & + "B4WVSF2XI","B4WVSF2YI","B4WVSF2ZI","B4WVSFXI ","B4WVSFYI ","B4WVSFZI ","B4WVSM1XI","B4WVSM1YI", & + "B4WVSM1ZI","B4WVSM2XI","B4WVSM2YI","B4WVSM2ZI","B4WVSMXI ","B4WVSMYI ","B4WVSMZI ","B4YAW ", & + "B5ADDFXI ","B5ADDFYI ","B5ADDFZI ","B5ADDMXI ","B5ADDMYI ","B5ADDMZI ","B5HDSFXI ","B5HDSFYI ", & + "B5HDSFZI ","B5HDSMXI ","B5HDSMYI ","B5HDSMZI ","B5HEAVE ","B5PITCH ","B5RAXI ","B5RAYI ", & + "B5RAZI ","B5RDTFXI ","B5RDTFYI ","B5RDTFZI ","B5RDTMXI ","B5RDTMYI ","B5RDTMZI ","B5ROLL ", & + "B5RVXI ","B5RVYI ","B5RVZI ","B5SURGE ","B5SWAY ","B5TAXI ","B5TAYI ","B5TAZI ", & + "B5TVXI ","B5TVYI ","B5TVZI ","B5WVSF1XI","B5WVSF1YI","B5WVSF1ZI","B5WVSF2XI","B5WVSF2YI", & + "B5WVSF2ZI","B5WVSFXI ","B5WVSFYI ","B5WVSFZI ","B5WVSM1XI","B5WVSM1YI","B5WVSM1ZI","B5WVSM2XI", & + "B5WVSM2YI","B5WVSM2ZI","B5WVSMXI ","B5WVSMYI ","B5WVSMZI ","B5YAW ","B6ADDFXI ","B6ADDFYI ", & + "B6ADDFZI ","B6ADDMXI ","B6ADDMYI ","B6ADDMZI ","B6HDSFXI ","B6HDSFYI ","B6HDSFZI ","B6HDSMXI ", & + "B6HDSMYI ","B6HDSMZI ","B6HEAVE ","B6PITCH ","B6RAXI ","B6RAYI ","B6RAZI ","B6RDTFXI ", & + "B6RDTFYI ","B6RDTFZI ","B6RDTMXI ","B6RDTMYI ","B6RDTMZI ","B6ROLL ","B6RVXI ","B6RVYI ", & + "B6RVZI ","B6SURGE ","B6SWAY ","B6TAXI ","B6TAYI ","B6TAZI ","B6TVXI ","B6TVYI ", & + "B6TVZI ","B6WVSF1XI","B6WVSF1YI","B6WVSF1ZI","B6WVSF2XI","B6WVSF2YI","B6WVSF2ZI","B6WVSFXI ", & + "B6WVSFYI ","B6WVSFZI ","B6WVSM1XI","B6WVSM1YI","B6WVSM1ZI","B6WVSM2XI","B6WVSM2YI","B6WVSM2ZI", & + "B6WVSMXI ","B6WVSMYI ","B6WVSMZI ","B6YAW ","B7ADDFXI ","B7ADDFYI ","B7ADDFZI ","B7ADDMXI ", & + "B7ADDMYI ","B7ADDMZI ","B7HDSFXI ","B7HDSFYI ","B7HDSFZI ","B7HDSMXI ","B7HDSMYI ","B7HDSMZI ", & + "B7HEAVE ","B7PITCH ","B7RAXI ","B7RAYI ","B7RAZI ","B7RDTFXI ","B7RDTFYI ","B7RDTFZI ", & + "B7RDTMXI ","B7RDTMYI ","B7RDTMZI ","B7ROLL ","B7RVXI ","B7RVYI ","B7RVZI ","B7SURGE ", & + "B7SWAY ","B7TAXI ","B7TAYI ","B7TAZI ","B7TVXI ","B7TVYI ","B7TVZI ","B7WVSF1XI", & + "B7WVSF1YI","B7WVSF1ZI","B7WVSF2XI","B7WVSF2YI","B7WVSF2ZI","B7WVSFXI ","B7WVSFYI ","B7WVSFZI ", & + "B7WVSM1XI","B7WVSM1YI","B7WVSM1ZI","B7WVSM2XI","B7WVSM2YI","B7WVSM2ZI","B7WVSMXI ","B7WVSMYI ", & + "B7WVSMZI ","B7YAW ","B8ADDFXI ","B8ADDFYI ","B8ADDFZI ","B8ADDMXI ","B8ADDMYI ","B8ADDMZI ", & + "B8HDSFXI ","B8HDSFYI ","B8HDSFZI ","B8HDSMXI ","B8HDSMYI ","B8HDSMZI ","B8HEAVE ","B8PITCH ", & + "B8RAXI ","B8RAYI ","B8RAZI ","B8RDTFXI ","B8RDTFYI ","B8RDTFZI ","B8RDTMXI ","B8RDTMYI ", & + "B8RDTMZI ","B8ROLL ","B8RVXI ","B8RVYI ","B8RVZI ","B8SURGE ","B8SWAY ","B8TAXI ", & + "B8TAYI ","B8TAZI ","B8TVXI ","B8TVYI ","B8TVZI ","B8WVSF1XI","B8WVSF1YI","B8WVSF1ZI", & + "B8WVSF2XI","B8WVSF2YI","B8WVSF2ZI","B8WVSFXI ","B8WVSFYI ","B8WVSFZI ","B8WVSM1XI","B8WVSM1YI", & + "B8WVSM1ZI","B8WVSM2XI","B8WVSM2YI","B8WVSM2ZI","B8WVSMXI ","B8WVSMYI ","B8WVSMZI ","B8YAW ", & + "B9ADDFXI ","B9ADDFYI ","B9ADDFZI ","B9ADDMXI ","B9ADDMYI ","B9ADDMZI ","B9HDSFXI ","B9HDSFYI ", & + "B9HDSFZI ","B9HDSMXI ","B9HDSMYI ","B9HDSMZI ","B9HEAVE ","B9PITCH ","B9RAXI ","B9RAYI ", & + "B9RAZI ","B9RDTFXI ","B9RDTFYI ","B9RDTFZI ","B9RDTMXI ","B9RDTMYI ","B9RDTMZI ","B9ROLL ", & + "B9RVXI ","B9RVYI ","B9RVZI ","B9SURGE ","B9SWAY ","B9TAXI ","B9TAYI ","B9TAZI ", & + "B9TVXI ","B9TVYI ","B9TVZI ","B9WVSF1XI","B9WVSF1YI","B9WVSF1ZI","B9WVSF2XI","B9WVSF2YI", & + "B9WVSF2ZI","B9WVSFXI ","B9WVSFYI ","B9WVSFZI ","B9WVSM1XI","B9WVSM1YI","B9WVSM1ZI","B9WVSM2XI", & + "B9WVSM2YI","B9WVSM2ZI","B9WVSMXI ","B9WVSMYI ","B9WVSMZI ","B9YAW ","HYDROFXI ","HYDROFYI ", & + "HYDROFZI ","HYDROMXI ","HYDROMYI ","HYDROMZI ","PRPHEAVE ","PRPPITCH ","PRPRAXI ","PRPRAYI ", & + "PRPRAZI ","PRPROLL ","PRPRVXI ","PRPRVYI ","PRPRVZI ","PRPSURGE ","PRPSWAY ","PRPTAXI ", & + "PRPTAYI ","PRPTAZI ","PRPTVXI ","PRPTVYI ","PRPTVZI ","PRPYAW ","WAVE1ELEV","WAVE1ELV1", & + "WAVE1ELV2","WAVE2ELEV","WAVE2ELV1","WAVE2ELV2","WAVE3ELEV","WAVE3ELV1","WAVE3ELV2","WAVE4ELEV", & + "WAVE4ELV1","WAVE4ELV2","WAVE5ELEV","WAVE5ELV1","WAVE5ELV2","WAVE6ELEV","WAVE6ELV1","WAVE6ELV2", & + "WAVE7ELEV","WAVE7ELV1","WAVE7ELV2","WAVE8ELEV","WAVE8ELV1","WAVE8ELV2","WAVE9ELEV","WAVE9ELV1", & + "WAVE9ELV2"/) + INTEGER(IntKi), PARAMETER :: ParamIndxAry(537) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + B1AddFxi , B1AddFyi , B1AddFzi , B1AddMxi , B1AddMyi , B1AddMzi , B1HdSFxi , B1HdSFyi , & + B1HdSFzi , B1HdSMxi , B1HdSMyi , B1HdSMzi , B1Heave , B1Pitch , B1RAxi , B1RAyi , & + B1RAzi , B1RdtFxi , B1RdtFyi , B1RdtFzi , B1RdtMxi , B1RdtMyi , B1RdtMzi , B1Roll , & + B1RVxi , B1RVyi , B1RVzi , B1Surge , B1Sway , B1TAxi , B1TAyi , B1TAzi , & + B1TVxi , B1TVyi , B1TVzi , B1WvsF1xi , B1WvsF1yi , B1WvsF1zi , B1WvsF2xi , B1WvsF2yi , & + B1WvsF2zi , B1WvsFxi , B1WvsFyi , B1WvsFzi , B1WvsM1xi , B1WvsM1yi , B1WvsM1zi , B1WvsM2xi , & + B1WvsM2yi , B1WvsM2zi , B1WvsMxi , B1WvsMyi , B1WvsMzi , B1Yaw , B2AddFxi , B2AddFyi , & + B2AddFzi , B2AddMxi , B2AddMyi , B2AddMzi , B2HdSFxi , B2HdSFyi , B2HdSFzi , B2HdSMxi , & + B2HdSMyi , B2HdSMzi , B2Heave , B2Pitch , B2RAxi , B2RAyi , B2RAzi , B2RdtFxi , & + B2RdtFyi , B2RdtFzi , B2RdtMxi , B2RdtMyi , B2RdtMzi , B2Roll , B2RVxi , B2RVyi , & + B2RVzi , B2Surge , B2Sway , B2TAxi , B2TAyi , B2TAzi , B2TVxi , B2TVyi , & + B2TVzi , B2WvsF1xi , B2WvsF1yi , B2WvsF1zi , B2WvsF2xi , B2WvsF2yi , B2WvsF2zi , B2WvsFxi , & + B2WvsFyi , B2WvsFzi , B2WvsM1xi , B2WvsM1yi , B2WvsM1zi , B2WvsM2xi , B2WvsM2yi , B2WvsM2zi , & + B2WvsMxi , B2WvsMyi , B2WvsMzi , B2Yaw , B3AddFxi , B3AddFyi , B3AddFzi , B3AddMxi , & + B3AddMyi , B3AddMzi , B3HdSFxi , B3HdSFyi , B3HdSFzi , B3HdSMxi , B3HdSMyi , B3HdSMzi , & + B3Heave , B3Pitch , B3RAxi , B3RAyi , B3RAzi , B3RdtFxi , B3RdtFyi , B3RdtFzi , & + B3RdtMxi , B3RdtMyi , B3RdtMzi , B3Roll , B3RVxi , B3RVyi , B3RVzi , B3Surge , & + B3Sway , B3TAxi , B3TAyi , B3TAzi , B3TVxi , B3TVyi , B3TVzi , B3WvsF1xi , & + B3WvsF1yi , B3WvsF1zi , B3WvsF2xi , B3WvsF2yi , B3WvsF2zi , B3WvsFxi , B3WvsFyi , B3WvsFzi , & + B3WvsM1xi , B3WvsM1yi , B3WvsM1zi , B3WvsM2xi , B3WvsM2yi , B3WvsM2zi , B3WvsMxi , B3WvsMyi , & + B3WvsMzi , B3Yaw , B4AddFxi , B4AddFyi , B4AddFzi , B4AddMxi , B4AddMyi , B4AddMzi , & + B4HdSFxi , B4HdSFyi , B4HdSFzi , B4HdSMxi , B4HdSMyi , B4HdSMzi , B4Heave , B4Pitch , & + B4RAxi , B4RAyi , B4RAzi , B4RdtFxi , B4RdtFyi , B4RdtFzi , B4RdtMxi , B4RdtMyi , & + B4RdtMzi , B4Roll , B4RVxi , B4RVyi , B4RVzi , B4Surge , B4Sway , B4TAxi , & + B4TAyi , B4TAzi , B4TVxi , B4TVyi , B4TVzi , B4WvsF1xi , B4WvsF1yi , B4WvsF1zi , & + B4WvsF2xi , B4WvsF2yi , B4WvsF2zi , B4WvsFxi , B4WvsFyi , B4WvsFzi , B4WvsM1xi , B4WvsM1yi , & + B4WvsM1zi , B4WvsM2xi , B4WvsM2yi , B4WvsM2zi , B4WvsMxi , B4WvsMyi , B4WvsMzi , B4Yaw , & + B5AddFxi , B5AddFyi , B5AddFzi , B5AddMxi , B5AddMyi , B5AddMzi , B5HdSFxi , B5HdSFyi , & + B5HdSFzi , B5HdSMxi , B5HdSMyi , B5HdSMzi , B5Heave , B5Pitch , B5RAxi , B5RAyi , & + B5RAzi , B5RdtFxi , B5RdtFyi , B5RdtFzi , B5RdtMxi , B5RdtMyi , B5RdtMzi , B5Roll , & + B5RVxi , B5RVyi , B5RVzi , B5Surge , B5Sway , B5TAxi , B5TAyi , B5TAzi , & + B5TVxi , B5TVyi , B5TVzi , B5WvsF1xi , B5WvsF1yi , B5WvsF1zi , B5WvsF2xi , B5WvsF2yi , & + B5WvsF2zi , B5WvsFxi , B5WvsFyi , B5WvsFzi , B5WvsM1xi , B5WvsM1yi , B5WvsM1zi , B5WvsM2xi , & + B5WvsM2yi , B5WvsM2zi , B5WvsMxi , B5WvsMyi , B5WvsMzi , B5Yaw , B6AddFxi , B6AddFyi , & + B6AddFzi , B6AddMxi , B6AddMyi , B6AddMzi , B6HdSFxi , B6HdSFyi , B6HdSFzi , B6HdSMxi , & + B6HdSMyi , B6HdSMzi , B6Heave , B6Pitch , B6RAxi , B6RAyi , B6RAzi , B6RdtFxi , & + B6RdtFyi , B6RdtFzi , B6RdtMxi , B6RdtMyi , B6RdtMzi , B6Roll , B6RVxi , B6RVyi , & + B6RVzi , B6Surge , B6Sway , B6TAxi , B6TAyi , B6TAzi , B6TVxi , B6TVyi , & + B6TVzi , B6WvsF1xi , B6WvsF1yi , B6WvsF1zi , B6WvsF2xi , B6WvsF2yi , B6WvsF2zi , B6WvsFxi , & + B6WvsFyi , B6WvsFzi , B6WvsM1xi , B6WvsM1yi , B6WvsM1zi , B6WvsM2xi , B6WvsM2yi , B6WvsM2zi , & + B6WvsMxi , B6WvsMyi , B6WvsMzi , B6Yaw , B7AddFxi , B7AddFyi , B7AddFzi , B7AddMxi , & + B7AddMyi , B7AddMzi , B7HdSFxi , B7HdSFyi , B7HdSFzi , B7HdSMxi , B7HdSMyi , B7HdSMzi , & + B7Heave , B7Pitch , B7RAxi , B7RAyi , B7RAzi , B7RdtFxi , B7RdtFyi , B7RdtFzi , & + B7RdtMxi , B7RdtMyi , B7RdtMzi , B7Roll , B7RVxi , B7RVyi , B7RVzi , B7Surge , & + B7Sway , B7TAxi , B7TAyi , B7TAzi , B7TVxi , B7TVyi , B7TVzi , B7WvsF1xi , & + B7WvsF1yi , B7WvsF1zi , B7WvsF2xi , B7WvsF2yi , B7WvsF2zi , B7WvsFxi , B7WvsFyi , B7WvsFzi , & + B7WvsM1xi , B7WvsM1yi , B7WvsM1zi , B7WvsM2xi , B7WvsM2yi , B7WvsM2zi , B7WvsMxi , B7WvsMyi , & + B7WvsMzi , B7Yaw , B8AddFxi , B8AddFyi , B8AddFzi , B8AddMxi , B8AddMyi , B8AddMzi , & + B8HdSFxi , B8HdSFyi , B8HdSFzi , B8HdSMxi , B8HdSMyi , B8HdSMzi , B8Heave , B8Pitch , & + B8RAxi , B8RAyi , B8RAzi , B8RdtFxi , B8RdtFyi , B8RdtFzi , B8RdtMxi , B8RdtMyi , & + B8RdtMzi , B8Roll , B8RVxi , B8RVyi , B8RVzi , B8Surge , B8Sway , B8TAxi , & + B8TAyi , B8TAzi , B8TVxi , B8TVyi , B8TVzi , B8WvsF1xi , B8WvsF1yi , B8WvsF1zi , & + B8WvsF2xi , B8WvsF2yi , B8WvsF2zi , B8WvsFxi , B8WvsFyi , B8WvsFzi , B8WvsM1xi , B8WvsM1yi , & + B8WvsM1zi , B8WvsM2xi , B8WvsM2yi , B8WvsM2zi , B8WvsMxi , B8WvsMyi , B8WvsMzi , B8Yaw , & + B9AddFxi , B9AddFyi , B9AddFzi , B9AddMxi , B9AddMyi , B9AddMzi , B9HdSFxi , B9HdSFyi , & + B9HdSFzi , B9HdSMxi , B9HdSMyi , B9HdSMzi , B9Heave , B9Pitch , B9RAxi , B9RAyi , & + B9RAzi , B9RdtFxi , B9RdtFyi , B9RdtFzi , B9RdtMxi , B9RdtMyi , B9RdtMzi , B9Roll , & + B9RVxi , B9RVyi , B9RVzi , B9Surge , B9Sway , B9TAxi , B9TAyi , B9TAzi , & + B9TVxi , B9TVyi , B9TVzi , B9WvsF1xi , B9WvsF1yi , B9WvsF1zi , B9WvsF2xi , B9WvsF2yi , & + B9WvsF2zi , B9WvsFxi , B9WvsFyi , B9WvsFzi , B9WvsM1xi , B9WvsM1yi , B9WvsM1zi , B9WvsM2xi , & + B9WvsM2yi , B9WvsM2zi , B9WvsMxi , B9WvsMyi , B9WvsMzi , B9Yaw , HydroFxi , HydroFyi , & + HydroFzi , HydroMxi , HydroMyi , HydroMzi , PRPHeave , PRPPitch , PRPRAxi , PRPRAyi , & + PRPRAzi , PRPRoll , PRPRVxi , PRPRVyi , PRPRVzi , PRPSurge , PRPSway , PRPTAxi , & + PRPTAyi , PRPTAzi , PRPTVxi , PRPTVyi , PRPTVzi , PRPYaw , Wave1Elev , Wave1Elv1 , & + Wave1Elv2 , Wave2Elev , Wave2Elv1 , Wave2Elv2 , Wave3Elev , Wave3Elv1 , Wave3Elv2 , Wave4Elev , & + Wave4Elv1 , Wave4Elv2 , Wave5Elev , Wave5Elv1 , Wave5Elv2 , Wave6Elev , Wave6Elv1 , Wave6Elv2 , & + Wave7Elev , Wave7Elv1 , Wave7Elv2 , Wave8Elev , Wave8Elv1 , Wave8Elv2 , Wave9Elev , Wave9Elv1 , & + Wave9Elv2 /) + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(537) = (/ & ! This lists the units corresponding to the allowed parameters + "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N) ","(N) ", & + "(N) ","(N-m) ","(N-m) ","(N-m) ","(m) ","(rad) ","(rad/s^2)","(rad/s^2)", & + "(rad/s^2)","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(rad) ", & + "(rad/s) ","(rad/s) ","(rad/s) ","(m) ","(m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m/s) ","(m/s) ","(m/s) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(rad) ","(N) ","(N) ", & + "(N) ","(N-m) ","(N-m) ","(N-m) ","(N) ","(N) ","(N) ","(N-m) ", & + "(N-m) ","(N-m) ","(m) ","(rad) ","(rad/s^2)","(rad/s^2)","(rad/s^2)","(N) ", & + "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(rad) ","(rad/s) ","(rad/s) ", & + "(rad/s) ","(m) ","(m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & + "(m/s) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(rad) ","(N) ","(N) ","(N) ","(N-m) ", & + "(N-m) ","(N-m) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & + "(m) ","(rad) ","(rad/s^2)","(rad/s^2)","(rad/s^2)","(N) ","(N) ","(N) ", & + "(N-m) ","(N-m) ","(N-m) ","(rad) ","(rad/s) ","(rad/s) ","(rad/s) ","(m) ", & + "(m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(rad) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & + "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(m) ","(rad) ", & + "(rad/s^2)","(rad/s^2)","(rad/s^2)","(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & + "(N-m) ","(rad) ","(rad/s) ","(rad/s) ","(rad/s) ","(m) ","(m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(rad) ", & + "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N) ","(N) ", & + "(N) ","(N-m) ","(N-m) ","(N-m) ","(m) ","(rad) ","(rad/s^2)","(rad/s^2)", & + "(rad/s^2)","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(rad) ", & + "(rad/s) ","(rad/s) ","(rad/s) ","(m) ","(m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m/s) ","(m/s) ","(m/s) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(rad) ","(N) ","(N) ", & + "(N) ","(N-m) ","(N-m) ","(N-m) ","(N) ","(N) ","(N) ","(N-m) ", & + "(N-m) ","(N-m) ","(m) ","(rad) ","(rad/s^2)","(rad/s^2)","(rad/s^2)","(N) ", & + "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(rad) ","(rad/s) ","(rad/s) ", & + "(rad/s) ","(m) ","(m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & + "(m/s) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(rad) ","(N) ","(N) ","(N) ","(N-m) ", & + "(N-m) ","(N-m) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & + "(m) ","(rad) ","(rad/s^2)","(rad/s^2)","(rad/s^2)","(N) ","(N) ","(N) ", & + "(N-m) ","(N-m) ","(N-m) ","(rad) ","(rad/s) ","(rad/s) ","(rad/s) ","(m) ", & + "(m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(rad) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & + "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(m) ","(rad) ", & + "(rad/s^2)","(rad/s^2)","(rad/s^2)","(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & + "(N-m) ","(rad) ","(rad/s) ","(rad/s) ","(rad/s) ","(m) ","(m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(rad) ", & + "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N) ","(N) ", & + "(N) ","(N-m) ","(N-m) ","(N-m) ","(m) ","(rad) ","(rad/s^2)","(rad/s^2)", & + "(rad/s^2)","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(rad) ", & + "(rad/s) ","(rad/s) ","(rad/s) ","(m) ","(m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m/s) ","(m/s) ","(m/s) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(rad) ","(N) ","(N) ", & + "(N) ","(N-m) ","(N-m) ","(N-m) ","(m) ","(rad) ","(rad/s^2)","(rad/s^2)", & + "(rad/s^2)","(rad) ","(rad/s) ","(rad/s) ","(rad/s) ","(m) ","(m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(rad) ","(m) ","(m) ", & + "(m) ","(m) ","(m) ","(m) ","(m) ","(m) ","(m) ","(m) ", & + "(m) ","(m) ","(m) ","(m) ","(m) ","(m) ","(m) ","(m) ", & + "(m) ","(m) ","(m) ","(m) ","(m) ","(m) ","(m) ","(m) ", & + "(m) "/) + ! ..... Public Subroutines ................................................................................................... PUBLIC :: HDOut_CloseSum @@ -190,7 +918,9 @@ MODULE HydroDyn_Output PUBLIC :: HDOUT_Init PUBLIC :: HDOut_WriteWvKinFiles -CONTAINS + CONTAINS + + !==================================================================================================== SUBROUTINE HDOut_CloseSum( UnSum, ErrStat, ErrMsg ) @@ -393,45 +1123,91 @@ SUBROUTINE HDOut_WriteWvKinFiles( Rootname, HD_Prog, NStepWave, NNodes, NWaveEle END SUBROUTINE HDOut_WriteWvKinFiles !==================================================================================================== -SUBROUTINE HDOut_MapOutputs( CurrentTime, y, NWaveElev, WaveElev, WaveElev1, F_Add, F_Waves, F_Hydro, q, qdot, qdotdot, AllOuts, ErrStat, ErrMsg ) +SUBROUTINE HDOut_MapOutputs( CurrentTime, p, y, m_WAMIT, m_WAMIT2, NWaveElev, WaveElev, WaveElev1, WaveElev2, F_Add, F_Waves, F_Hydro, PRPmesh, q, qdot, qdotdot, AllOuts, ErrStat, ErrMsg ) ! This subroutine writes the data stored in the y variable to the correct indexed postions in WriteOutput ! This is called by HydroDyn_CalcOutput() at each time step. !---------------------------------------------------------------------------------------------------- REAL(DbKi), INTENT( IN ) :: CurrentTime ! Current simulation time in seconds + TYPE(HydroDyn_ParameterType), INTENT( IN ) :: p ! HydroDyn's parameter data TYPE(HydroDyn_OutputType), INTENT( INOUT ) :: y ! HydroDyn's output data + type(WAMIT_MiscVarType), intent( in ) :: m_WAMIT(:) ! WAMIT object's MiscVar data + type(WAMIT2_MiscVarType), intent( in ) :: m_WAMIT2(:) ! WAMIT2 object's MiscVar data INTEGER, INTENT( IN ) :: NWaveElev ! Number of wave elevation locations to output REAL(ReKi), INTENT( IN ) :: WaveElev(:) ! Instantaneous total elevation of incident waves at each of the NWaveElev points where the incident wave elevations can be output (meters) REAL(ReKi), INTENT( IN ) :: WaveElev1(:) ! Instantaneous first order elevation of incident waves at each of the NWaveElev points where the incident wave elevations can be output (meters) - REAL(ReKi), INTENT( IN ) :: F_Add(6) - REAL(ReKi), INTENT( IN ) :: F_Waves(6) - REAL(ReKi), INTENT( IN ) :: F_Hydro(6) - REAL(ReKi), INTENT( IN ) :: q(6) ! WRP translations and rotations - REAL(ReKi), INTENT( IN ) :: qdot(6) ! WRP translational and rotational velocities - REAL(ReKi), INTENT( IN ) :: qdotdot(6) ! WRP translational and rotational accelerations + REAL(ReKi), INTENT( IN ) :: WaveElev2(:) ! Instantaneous second order elevation of incident waves at each of the NWaveElev points where the incident wave elevations can be output (meters) + REAL(ReKi), INTENT( IN ) :: F_Add(:) + REAL(ReKi), INTENT( IN ) :: F_Waves(:) + REAL(ReKi), INTENT( IN ) :: F_Hydro(:) ! All hydrodynamic loads integrated at (0,0,0) in the global coordinate system + type(MeshType), INTENT( IN ) :: PRPmesh ! the PRP mesh -- for motions output + REAL(ReKi), INTENT( IN ) :: q(:) ! WAMIT body translations and rotations + REAL(ReKi), INTENT( IN ) :: qdot(:) ! WAMIT body translational and rotational velocities + REAL(ReKi), INTENT( IN ) :: qdotdot(:) ! WAMIT body translational and rotational accelerations REAL(ReKi), INTENT( OUT ) :: AllOuts(MaxHDOutputs) INTEGER(IntKi), INTENT( OUT ) :: ErrStat ! Error status of the operation CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - INTEGER :: I - + INTEGER :: I, iBody, startIndx, endIndx + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + real(ReKi) :: rotdisp(3) + ErrStat = ErrID_None ErrMsg = "" - - ! TODO: use y%mesh for the forces instead of individual parameters - - !AllOuts(Time) = REAL(CurrentTime,ReKi) - - AllOuts(FAdd) = F_Add - AllOuts(FWavesTot) = F_Waves - AllOuts(FHydro) = F_Hydro - AllOuts(WRPMotions) = q - AllOuts(WRPVel) = qdot - AllOuts(WRPAcc) = qdotdot + ! Initialize all unused channels to zero (in case they don't get set, but are still requested) + AllOuts = 0.0_ReKi + + rotdisp = GetSmllRotAngs ( PRPMesh%Orientation(:,:,1), ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'HDOut_MapOutputs' ) + AllOuts(PRPMotions) = reshape((/real(PRPMesh%TranslationDisp(:,1),ReKi),rotdisp(:)/),(/6/)) + AllOuts(PRPVel) = reshape((/PRPMesh%TranslationVel(:,1),PRPMesh%RotationVel(:,1)/),(/6/)) + AllOuts(PRPAcc) = reshape((/PRPMesh%TranslationAcc(:,1),PRPMesh%RotationAcc(:,1)/),(/6/)) + + ! Need to use individual components of force for output reporting, the y%mesh data has total forces from all contributions + if ( p%potMod == 1 ) then + if ( p%NBodyMod == 1 .or. p%NBody == 1 ) then + do iBody = 1,p%NBody + startIndx = 6*(iBody-1) + 1 + endIndx = startIndx + 5 + AllOuts(FWaves1 (:,iBody)) = m_WAMIT(1)%F_Waves1(startIndx:endIndx) + AllOuts(FHdrSttc (:,iBody)) = m_WAMIT(1)%F_HS(startIndx:endIndx) + AllOuts(FRdtn (:,iBody)) = m_WAMIT(1)%F_Rdtn(startIndx:endIndx) + m_WAMIT(1)%F_PtfmAM(startIndx:endIndx) + if (p%WAMIT2used) AllOuts(FWaves2 (:,iBody)) = m_WAMIT2(1)%F_Waves2(startIndx:endIndx) ! These are reported by the WAMIT2 module + AllOuts(FAdd (:,iBody)) = F_Add(startIndx:endIndx) + AllOuts(FWavesTot(:,iBody)) = F_Waves(startIndx:endIndx) + AllOuts(WBMotions(:,iBody)) = q(startIndx:endIndx) + AllOuts(WBVel (:,iBody)) = qdot(startIndx:endIndx) + AllOuts(WBAcc (:,iBody)) = qdotdot(startIndx:endIndx) + end do + else + + ! This happens when NBodyMod > 1, in which case, each WAMIT object is for a single body, but there may be multiple bodies in the HydroDyn model, + ! so we need to use BodyID to determine the index into the complete HydroDyn list of WAMIT bodies + + do iBody = 1,p%NBody + startIndx = 6*(iBody-1) + 1 + endIndx = startIndx + 5 + AllOuts(FWaves1 (:,iBody)) = m_WAMIT(iBody)%F_Waves1 + AllOuts(FHdrSttc (:,iBody)) = m_WAMIT(iBody)%F_HS + AllOuts(FRdtn (:,iBody)) = m_WAMIT(iBody)%F_Rdtn + m_WAMIT(iBody)%F_PtfmAM + if (p%WAMIT2used) AllOuts(FWaves2 (:,iBody)) = m_WAMIT2(iBody)%F_Waves2 + AllOuts(FAdd (:,iBody)) = F_Add(startIndx:endIndx) + AllOuts(FWavesTot(:,iBody)) = F_Waves(startIndx:endIndx) + AllOuts(WBMotions(:,iBody)) = q(startIndx:endIndx) + AllOuts(WBVel (:,iBody)) = qdot(startIndx:endIndx) + AllOuts(WBAcc (:,iBody)) = qdotdot(startIndx:endIndx) + end do + end if + end if + + + AllOuts(FHydro ) = F_Hydro DO I=1,NWaveElev AllOuts(WaveElevi(I)) = WaveElev(I) AllOuts(WaveElevi1(I))= WaveElev1(I) + AllOuts(WaveElevi2(I))= WaveElev2(I) END DO @@ -461,7 +1237,7 @@ SUBROUTINE HDOut_WriteOutputs( Time, y, p, Decimate, ErrStat, ErrMsg ) ! Initialize ErrStat and determine if it makes any sense to write output !TODO: We should not have this check here, once per timestep! This should be resolved during initialization. GJH 7/7/2014 - IF ( ( (.NOT. ALLOCATED( p%OutParam )) .AND. (.NOT. ALLOCATED( p%WAMIT%OutParam ) ) .AND. (.NOT. ALLOCATED( p%WAMIT2%OutParam ) )& + IF ( ( (.NOT. ALLOCATED( p%OutParam )) .AND. (.NOT. ALLOCATED( p%WAMIT ) ) .AND. (.NOT. ALLOCATED( p%WAMIT2 ) )& .AND. (.NOT. ALLOCATED( p%Waves2%OutParam ) ) .AND. ( .NOT. ALLOCATED( p%Morison%OutParam ) ) ) ) THEN ErrStat = ErrID_Warn ErrMsg = ' Cannot write output to file because there are not a valid output list.' @@ -491,27 +1267,6 @@ SUBROUTINE HDOut_WriteOutputs( Time, y, p, Decimate, ErrStat, ErrMsg ) Frmt = '('//TRIM(Int2LStr(p%NumTotalOuts))//'(:,A,'//TRIM( p%OutFmt )//'))' WRITE(p%UnOutFile,Frmt,ADVANCE='no') ( p%Delim, y%WriteOutput(I) , I=1,p%NumTotalOuts ) END IF - - ! ! HydroDyn Outputs - !IF (ALLOCATED( p%OutParam ) .AND. p%NumOuts > 0) THEN - !!IF (p%DoOutput) THEN - ! Frmt = '('//TRIM(Int2LStr(p%NumOuts))//'(:,A,'//TRIM( p%OutFmt )//'))' - ! WRITE(p%UnOutFile,Frmt,ADVANCE='no') ( p%Delim, y%WriteOutput(I) , I=1,p%NumOuts ) - !END IF - ! - ! ! WAMIT Outputs - !IF (ALLOCATED( p%WAMIT%OutParam ) .AND. p%WAMIT%NumOuts > 0) THEN - !!IF (p%WAMIT%DoOutput) THEN - ! Frmt = '('//TRIM(Int2LStr(p%WAMIT%NumOuts))//'(:,A,'//TRIM( p%OutFmt )//'))' - ! WRITE(p%UnOutFile,Frmt,ADVANCE='no') ( p%Delim, y%WAMIT%WriteOutput(I) , I=1,p%WAMIT%NumOuts ) - !END IF - ! - ! ! Morison Outputs - !IF (ALLOCATED( p%Morison%OutParam ) .AND. p%Morison%NumOuts > 0) THEN - !!IF (p%Morison%DoOutput) THEN - ! Frmt = '('//TRIM(Int2LStr(p%Morison%NumOuts))//'(:,A,'//TRIM( p%OutFmt )//'))' - ! WRITE(p%UnOutFile,Frmt,ADVANCE='no') ( p%Delim, y%Morison%WriteOutput(I), I=1,p%Morison%NumOuts ) - !END IF WRITE (p%UnOutFile,'()', IOSTAT=ErrStat) ! write the line return @@ -546,6 +1301,7 @@ SUBROUTINE HDOUT_Init( HydroDyn_ProgDesc, InitInp, y, p, m, InitOut, ErrStat, E ! Local variables INTEGER :: I ! Generic loop counter INTEGER :: J ! Generic loop counter + INTEGER :: iWAMIT ! loop counter over WAMIT objects ! INTEGER :: Indx ! Counts the current index into the WaveKinNd array ! CHARACTER(1024) :: OutFileName ! The name of the output file including the full path. ! CHARACTER(200) :: Frmt ! a string to hold a format statement @@ -566,7 +1322,16 @@ SUBROUTINE HDOUT_Init( HydroDyn_ProgDesc, InitInp, y, p, m, InitOut, ErrStat, E ErrStat = ErrID_None ErrMsg = "" - + ! Sanity check that we didn't have an issue during the programing of this module. The auto + ! generated outlist at the top of this file sets the MaxOutPts value, but HD does not use + ! that value, but rather has the maximum outputs hard coded in the HD registry file. This + ! next test will hopefully help the developer catch any issues. + if ( MaxOutPts /= MaxHDOutputs ) then + call SetErrStat(ErrID_Fatal, ' HD outputs: the number of outputs given by the Write_ChckOutList.m '// & + 'script using the xlsx file does not match the number of outputs given by the HydroDyn.txt registry '// & + 'file.', ErrStat, ErrMsg, 'HDOUT_Init') + return + endif !------------------------------------------------------------------------------------------------- @@ -576,47 +1341,9 @@ SUBROUTINE HDOUT_Init( HydroDyn_ProgDesc, InitInp, y, p, m, InitOut, ErrStat, E CALL HDOUT_ChkOutLst( InitInp%OutList(1:p%NumOuts), y, p, ErrStat, ErrMsg ) IF ( ErrStat /= 0 ) RETURN - - - !IF ( ALLOCATED( p%OutParam ) .AND. p%NumOuts > 0 ) THEN ! Output has been requested so let's open an output file - ! - ! ALLOCATE( y%WriteOutput( p%NumOuts ), STAT = ErrStat ) - ! IF ( ErrStat /= ErrID_None ) THEN - ! ErrMsg = ' Error allocating space for WriteOutput array.' - ! ErrStat = ErrID_Fatal - ! RETURN - ! END IF - ! y%WriteOutput = 0.0_ReKi - ! - ! ALLOCATE ( InitOut%WriteOutputHdr(p%NumOuts), STAT = ErrStat ) - ! IF ( ErrStat /= ErrID_None ) THEN - ! ErrMsg = ' Error allocating space for WriteOutputHdr array.' - ! ErrStat = ErrID_Fatal - ! RETURN - ! END IF - ! - ! ALLOCATE ( InitOut%WriteOutputUnt(p%NumOuts), STAT = ErrStat ) - ! IF ( ErrStat /= ErrID_None ) THEN - ! ErrMsg = ' Error allocating space for WriteOutputHdr array.' - ! ErrStat = ErrID_Fatal - ! RETURN - ! END IF - ! - ! DO I = 1,p%NumOuts - ! - ! InitOut%WriteOutputHdr(I) = TRIM( p%OutParam(I)%Name ) - ! InitOut%WriteOutputUnt(I) = TRIM( p%OutParam(I)%Units ) - ! - ! END DO - ! - ! END IF ! there are any requested outputs - - ! Aggregate the sub-module initialization outputs for the glue code - !IF ( p%OutSwtch == 2 .OR. p%OutSwtch == 3 ) THEN - - hasWAMITOuts = .FALSE. + hasWAMIT2Outs = .FALSE. hasWaves2Outs = .FALSE. hasMorisonOuts = .FALSE. @@ -624,15 +1351,7 @@ SUBROUTINE HDOUT_Init( HydroDyn_ProgDesc, InitInp, y, p, m, InitOut, ErrStat, E m%LastOutTime = 0.0_DbKi m%Decimate = 0 p%OutDec = 1 !TODO: Remove this once the parameter has been added to the HD input file GJH 7/8/2014 - - IF (ALLOCATED( p%WAMIT%OutParam ) .AND. p%WAMIT%NumOuts > 0) THEN - hasWAMITOuts = .TRUE. - p%NumTotalOuts = p%NumTotalOuts + p%WAMIT%NumOuts - END IF - IF (ALLOCATED( p%WAMIT2%OutParam ) .AND. p%WAMIT2%NumOuts > 0) THEN - hasWAMIT2Outs = .TRUE. - p%NumTotalOuts = p%NumTotalOuts + p%WAMIT2%NumOuts - END IF + IF (ALLOCATED( p%Waves2%OutParam ) .AND. p%Waves2%NumOuts > 0) THEN hasWaves2Outs = .TRUE. p%NumTotalOuts = p%NumTotalOuts + p%Waves2%NumOuts @@ -678,14 +1397,6 @@ SUBROUTINE HDOUT_Init( HydroDyn_ProgDesc, InitInp, y, p, m, InitOut, ErrStat, E J = p%NumOuts + 1 - IF ( hasWAMITOuts ) THEN - DO I=1, p%WAMIT%NumOuts - InitOut%WriteOutputHdr(J) = InitOut%WAMIT%WriteOutputHdr(I) - InitOut%WriteOutputUnt(J) = InitOut%WAMIT%WriteOutputUnt(I) - J = J + 1 - END DO - END IF - IF ( hasWaves2Outs ) THEN DO I=1, p%Waves2%NumOuts InitOut%WriteOutputHdr(J) = InitOut%Waves2%WriteOutputHdr(I) @@ -694,14 +1405,6 @@ SUBROUTINE HDOUT_Init( HydroDyn_ProgDesc, InitInp, y, p, m, InitOut, ErrStat, E END DO END IF - IF ( hasWAMIT2Outs ) THEN - DO I=1, p%WAMIT2%NumOuts - InitOut%WriteOutputHdr(J) = InitOut%WAMIT2%WriteOutputHdr(I) - InitOut%WriteOutputUnt(J) = InitOut%WAMIT2%WriteOutputUnt(I) - J = J + 1 - END DO - END IF - IF ( hasMorisonOuts ) THEN DO I=1, p%Morison%NumOuts InitOut%WriteOutputHdr(J) = InitOut%Morison%WriteOutputHdr(I) @@ -709,9 +1412,7 @@ SUBROUTINE HDOUT_Init( HydroDyn_ProgDesc, InitInp, y, p, m, InitOut, ErrStat, E J = J + 1 END DO END IF - - !END IF - + IF ( p%OutSwtch == 1 .OR. p%OutSwtch == 3 ) THEN CALL HDOut_OpenOutput( HydroDyn_ProgDesc, InitInp%OutRootName, p, InitOut, ErrStat, ErrMsg ) IF (ErrStat >= AbortErrLev ) RETURN @@ -742,7 +1443,7 @@ SUBROUTINE HDOut_OpenOutput( HydroDyn_ProgDesc, OutRootName, p, InitOut, ErrSta ! Local variables INTEGER :: I ! Generic loop counter -! INTEGER :: J ! Generic loop counter + INTEGER :: iWAMIT ! loop counter for WAMIT Objects ! INTEGER :: Indx ! Counts the current index into the WaveKinNd array CHARACTER(1024) :: OutFileName ! The name of the output file including the full path. CHARACTER(200) :: Frmt ! a string to hold a format statement @@ -760,8 +1461,6 @@ SUBROUTINE HDOut_OpenOutput( HydroDyn_ProgDesc, OutRootName, p, InitOut, ErrSta !------------------------------------------------------------------------------------------------- p%UnOutFile = -1 IF ( (ALLOCATED( p%OutParam ) .AND. p%NumOuts > 0 ) .OR. & - (ALLOCATED( p%WAMIT%OutParam ) .AND. p%WAMIT%NumOuts > 0 ) .OR. & - (ALLOCATED( p%WAMIT2%OutParam ) .AND. p%WAMIT2%NumOuts > 0 ) .OR. & (ALLOCATED( p%Waves2%OutParam ) .AND. p%Waves2%NumOuts > 0 ) .OR. & (ALLOCATED( p%Morison%OutParam ) .AND. p%Morison%NumOuts > 0 ) ) THEN ! Output has been requested so let's open an output file @@ -792,16 +1491,6 @@ SUBROUTINE HDOut_OpenOutput( HydroDyn_ProgDesc, OutRootName, p, InitOut, ErrSta WRITE(p%UnOutFile,Frmt,ADVANCE='no') ( p%Delim, TRIM( InitOut%WriteOutputHdr(I) ), I=1,p%NumOuts ) END IF - IF (ALLOCATED( p%WAMIT%OutParam ) .AND. p%WAMIT%NumOuts > 0) THEN - Frmt = '('//TRIM(Int2LStr(p%WAMIT%NumOuts))//'(:,A,'//TRIM( p%OutSFmt )//'))' - WRITE(p%UnOutFile,Frmt,ADVANCE='no') ( p%Delim, TRIM( InitOut%WAMIT%WriteOutputHdr(I) ), I=1,p%WAMIT%NumOuts ) - END IF - - IF (ALLOCATED( p%WAMIT2%OutParam ) .AND. p%WAMIT2%NumOuts > 0) THEN - Frmt = '('//TRIM(Int2LStr(p%WAMIT2%NumOuts))//'(:,A,'//TRIM( p%OutSFmt )//'))' - WRITE(p%UnOutFile,Frmt,ADVANCE='no') ( p%Delim, TRIM( InitOut%WAMIT2%WriteOutputHdr(I) ), I=1,p%WAMIT2%NumOuts ) - END IF - IF (ALLOCATED( p%Waves2%OutParam ) .AND. p%Waves2%NumOuts > 0) THEN Frmt = '('//TRIM(Int2LStr(p%Waves2%NumOuts))//'(:,A,'//TRIM( p%OutSFmt )//'))' WRITE(p%UnOutFile,Frmt,ADVANCE='no') ( p%Delim, TRIM( InitOut%Waves2%WriteOutputHdr(I) ), I=1,p%Waves2%NumOuts ) @@ -826,17 +1515,7 @@ SUBROUTINE HDOut_OpenOutput( HydroDyn_ProgDesc, OutRootName, p, InitOut, ErrSta Frmt = '('//TRIM(Int2LStr(p%NumOuts))//'(:,A,'//TRIM( p%OutSFmt )//'))' WRITE(p%UnOutFile,Frmt,ADVANCE='no') ( p%Delim, TRIM( InitOut%WriteOutputUnt(I) ), I=1,p%NumOuts ) END IF - - IF (ALLOCATED( p%WAMIT%OutParam ) .AND. p%WAMIT%NumOuts > 0) THEN - Frmt = '('//TRIM(Int2LStr(p%WAMIT%NumOuts))//'(:,A,'//TRIM( p%OutSFmt )//'))' - WRITE(p%UnOutFile,Frmt,ADVANCE='no') ( p%Delim, TRIM( InitOut%WAMIT%WriteOutputUnt(I) ), I=1,p%WAMIT%NumOuts ) - END IF - - IF (ALLOCATED( p%WAMIT2%OutParam ) .AND. p%WAMIT2%NumOuts > 0) THEN - Frmt = '('//TRIM(Int2LStr(p%WAMIT2%NumOuts))//'(:,A,'//TRIM( p%OutSFmt )//'))' - WRITE(p%UnOutFile,Frmt,ADVANCE='no') ( p%Delim, TRIM( InitOut%WAMIT2%WriteOutputUnt(I) ), I=1,p%WAMIT2%NumOuts ) - END IF - + IF (ALLOCATED( p%Waves2%OutParam ) .AND. p%Waves2%NumOuts > 0) THEN Frmt = '('//TRIM(Int2LStr(p%Waves2%NumOuts))//'(:,A,'//TRIM( p%OutSFmt )//'))' WRITE(p%UnOutFile,Frmt,ADVANCE='no') ( p%Delim, TRIM( InitOut%Waves2%WriteOutputUnt(I) ), I=1,p%Waves2%NumOuts ) @@ -938,8 +1617,7 @@ FUNCTION HDOut_GetChannels ( NUserOutputs, UserOutputs, OutList, foundMask, IF ( HDOut_GetChannels > 0 ) THEN count = 1 - ! Test that num channels does not exceed max possible channels due to size of OutList - !ALLOCATE ( OutList(GetWAMITChannels) , STAT=ErrStat ) + IF ( ErrStat /= 0 ) THEN ErrMsg = ' Error allocating memory for the OutList array in the GetHydroDynChannels function.' ErrStat = ErrID_Fatal @@ -948,6 +1626,7 @@ FUNCTION HDOut_GetChannels ( NUserOutputs, UserOutputs, OutList, foundMask, DO I = 1,NUserOutputs IF ( newFoundMask(I) ) THEN + OutList(count) = UserOutputs(I) count = count + 1 END IF @@ -989,7 +1668,7 @@ SUBROUTINE HDOut_ChkOutLst( OutList, y, p, ErrStat, ErrMsg ) LOGICAL :: InvalidOutput(MaxHDOutputs) ! This array determines if the output channel is valid for this configuration LOGICAL :: CheckOutListAgain - !------------------------------------------------------------------------------------------------- + !------------------------------------------------------------------------------------------------- ! Allocate and set index, name, and units for the output channels ! If a selected output channel is not available in this module, set error flag. !------------------------------------------------------------------------------------------------- diff --git a/modules/hydrodyn/src/HydroDyn_Types.f90 b/modules/hydrodyn/src/HydroDyn_Types.f90 index 1b6b52b75c..0397484eac 100644 --- a/modules/hydrodyn/src/HydroDyn_Types.f90 +++ b/modules/hydrodyn/src/HydroDyn_Types.f90 @@ -42,7 +42,7 @@ MODULE HydroDyn_Types USE Morison_Types USE NWTC_Library IMPLICIT NONE - INTEGER(IntKi), PUBLIC, PARAMETER :: MaxHDOutputs = 54 ! The maximum number of output channels supported by this module [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: MaxHDOutputs = 537 ! The maximum number of output channels supported by this module [-] ! ========= HydroDyn_InitInputType ======= TYPE, PUBLIC :: HydroDyn_InitInputType CHARACTER(1024) :: InputFile !< Supplied by Driver: full path and filename for the HydroDyn module [-] @@ -56,26 +56,27 @@ MODULE HydroDyn_Types REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: WaveElevXY !< Supplied by Driver: X-Y locations for WaveElevation output (for visualization). First dimension is the X (1) and Y (2) coordinate. Second dimension is the point number. [m,-] REAL(ReKi) :: PtfmLocationX !< Supplied by Driver: X coordinate of platform location in the wave field [m] REAL(ReKi) :: PtfmLocationY !< Supplied by Driver: Y coordinate of platform location in the wave field [m] - CHARACTER(80) :: PtfmSgFChr !< Platform horizontal surge translation force (flag) or DEFAULT [-] - LOGICAL :: PtfmSgF !< Optionally Supplied by Driver: Platform horizontal surge translation force (flag) [-] - CHARACTER(80) :: PtfmSwFChr !< Platform horizontal sway translation force (flag) or DEFAULT [-] - LOGICAL :: PtfmSwF !< Optionally Supplied by Driver: Platform horizontal sway translation force (flag) [-] - CHARACTER(80) :: PtfmHvFChr !< Platform vertical heave translation force (flag) or DEFAULT [-] - LOGICAL :: PtfmHvF !< Optionally Supplied by Driver: Platform vertical heave translation force (flag) [-] - CHARACTER(80) :: PtfmRFChr !< Platform roll tilt rotation force (flag) or DEFAULT [-] - LOGICAL :: PtfmRF !< Optionally Supplied by Driver: Platform roll tilt rotation force (flag) [-] - CHARACTER(80) :: PtfmPFChr !< Platform pitch tilt rotation force (flag) or DEFAULT [-] - LOGICAL :: PtfmPF !< Optionally Supplied by Driver: Platform pitch tilt rotation force (flag) [-] - CHARACTER(80) :: PtfmYFChr !< Platform yaw rotation force (flag) or DEFAULT [-] - LOGICAL :: PtfmYF !< Optionally Supplied by Driver: Platform yaw rotation force (flag) [-] - REAL(ReKi) , DIMENSION(1:6) :: AddF0 !< Additional pre-load forces and moments (N,N,N,N-m,N-m,N-m) [-] - REAL(ReKi) , DIMENSION(1:6,1:6) :: AddCLin !< Additional stiffness matrix [-] - REAL(ReKi) , DIMENSION(1:6,1:6) :: AddBLin !< Additional linear damping matrix [-] - REAL(ReKi) , DIMENSION(1:6,1:6) :: AddBQuad !< Additional quadratic damping (drag) matrix [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: AddF0 !< Additional pre-load forces and moments (N,N,N,N-m,N-m,N-m) [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: AddCLin !< Additional stiffness matrix [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: AddBLin !< Additional linear damping matrix [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: AddBQuad !< Additional quadratic damping (drag) matrix [-] TYPE(Waves_InitInputType) :: Waves !< Initialization data for Waves module [-] TYPE(Waves2_InitInputType) :: Waves2 !< Initialization data for Waves module [-] TYPE(Current_InitInputType) :: Current !< Initialization data for Current module [-] - CHARACTER(1024) :: PotFile !< The name of the root potential flow file (without extension for WAMIT, complete name for FIT) [-] + CHARACTER(1024) , DIMENSION(:), ALLOCATABLE :: PotFile !< The name of the root potential flow file (without extension for WAMIT, complete name for FIT) [-] + INTEGER(IntKi) :: nWAMITObj !< number of WAMIT input files. If NBodyMod = 1 then nPotFiles will be 1 even if NBody > 1 [-] + INTEGER(IntKi) :: vecMultiplier !< multiplier for the WAMIT vectors and matrices. If NBodyMod=1 then this = NBody, else 1 [-] + INTEGER(IntKi) :: NBody !< [>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6] [-] + INTEGER(IntKi) :: NBodyMod !< Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1] [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PtfmVol0 !< [-] + LOGICAL :: HasWAMIT !< .TRUE. if using WAMIT model, .FALSE. otherwise [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WAMITULEN !< [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PtfmRefxt !< The xt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1; must be 0.0 if NBodyMod=2 ] [(m)] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PtfmRefyt !< The yt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1; must be 0.0 if NBodyMod=2 ] [(m)] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PtfmRefzt !< The zt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1; must be 0.0 if NBodyMod=2 ] [(m)] + REAL(R8Ki) , DIMENSION(:), ALLOCATABLE :: PtfmRefztRot !< The rotation about zt of the body reference frame(s) from xt/yt [radians] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PtfmCOBxt !< [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PtfmCOByt !< [-] TYPE(WAMIT_InitInputType) :: WAMIT !< Initialization data for WAMIT module [-] TYPE(WAMIT2_InitInputType) :: WAMIT2 !< Initialization data for WAMIT2 module [-] TYPE(Morison_InitInputType) :: Morison !< Initialization data for Morison module [-] @@ -86,7 +87,7 @@ MODULE HydroDyn_Types INTEGER(IntKi) :: OutSwtch !< Output requested channels to: [1=Hydrodyn.out 2=GlueCode.out 3=both files] [-] LOGICAL :: OutAll !< Output all user-specified member and joint loads (only at each member end, not interior locations) [T/F] [-] INTEGER(IntKi) :: NumOuts !< The number of outputs for this module as requested in the input file [-] - CHARACTER(ChanLen) , DIMENSION(1:54) :: OutList !< The user-requested output channel labels for this modules. This should really be dimensioned with MaxOutPts [-] + CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: OutList !< The user-requested output channel labels for this modules. This should really be dimensioned with MaxOutPts [-] LOGICAL :: HDSum !< Generate a HydroDyn summary file [T/F] [-] INTEGER(IntKi) :: UnSum !< File unit for the HydroDyn summary file [-1 = no summary file] [-] CHARACTER(20) :: OutFmt !< Output format for numerical results [-] @@ -95,8 +96,8 @@ MODULE HydroDyn_Types ! ======================= ! ========= HydroDyn_InitOutputType ======= TYPE, PUBLIC :: HydroDyn_InitOutputType - TYPE(WAMIT_InitOutputType) :: WAMIT !< Initialization output from the WAMIT module [-] - TYPE(WAMIT2_InitOutputType) :: WAMIT2 !< Initialization output from the WAMIT2 module [-] + TYPE(WAMIT_InitOutputType) , DIMENSION(:), ALLOCATABLE :: WAMIT !< Initialization output from the WAMIT module [-] + TYPE(WAMIT2_InitOutputType) , DIMENSION(:), ALLOCATABLE :: WAMIT2 !< Initialization output from the WAMIT2 module [-] TYPE(Waves2_InitOutputType) :: Waves2 !< Initialization output from the Waves2 module [-] TYPE(Morison_InitOutputType) :: Morison !< Initialization output from the Morison module [-] CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< The is the list of all HD-related output channel header strings (includes all sub-module channels) [-] @@ -115,23 +116,23 @@ MODULE HydroDyn_Types ! ======================= ! ========= HD_ModuleMapType ======= TYPE, PUBLIC :: HD_ModuleMapType - TYPE(MeshMapType) :: HD_P_2_WRP_P - TYPE(MeshMapType) :: M_P_2_WRP_P - TYPE(MeshMapType) :: M_L_2_WRP_P + TYPE(MeshMapType) :: uW_P_2_PRP_P !< Mesh mapping data: WAMIT body kinematics to PRP node at (0,0,0) [-] + TYPE(MeshMapType) :: W_P_2_PRP_P !< Mesh mapping data: WAMIT loads to PRP node at (0,0,0) [-] + TYPE(MeshMapType) :: M_P_2_PRP_P !< Mesh mapping data: lumped Morison loads to PRP node at (0,0,0) [-] END TYPE HD_ModuleMapType ! ======================= ! ========= HydroDyn_ContinuousStateType ======= TYPE, PUBLIC :: HydroDyn_ContinuousStateType - TYPE(WAMIT_ContinuousStateType) :: WAMIT !< continuous states from the wamit module [-] - TYPE(WAMIT2_ContinuousStateType) :: WAMIT2 !< continuous states from the wamit2 module [-] + TYPE(WAMIT_ContinuousStateType) , DIMENSION(:), ALLOCATABLE :: WAMIT !< continuous states from the wamit module [-] + TYPE(WAMIT2_ContinuousStateType) , DIMENSION(:), ALLOCATABLE :: WAMIT2 !< continuous states from the wamit2 module [-] TYPE(Waves2_ContinuousStateType) :: Waves2 !< continuous states from the waves2 module [-] TYPE(Morison_ContinuousStateType) :: Morison !< continuous states from the Morison module [-] END TYPE HydroDyn_ContinuousStateType ! ======================= ! ========= HydroDyn_DiscreteStateType ======= TYPE, PUBLIC :: HydroDyn_DiscreteStateType - TYPE(WAMIT_DiscreteStateType) :: WAMIT !< discrete states from the wamit module [-] - TYPE(WAMIT2_DiscreteStateType) :: WAMIT2 !< discrete states from the wamit2 module [-] + TYPE(WAMIT_DiscreteStateType) , DIMENSION(:), ALLOCATABLE :: WAMIT !< discrete states from the wamit module [-] + TYPE(WAMIT2_DiscreteStateType) , DIMENSION(:), ALLOCATABLE :: WAMIT2 !< discrete states from the wamit2 module [-] TYPE(Waves2_DiscreteStateType) :: Waves2 !< discrete states from the waves2 module [-] TYPE(Morison_DiscreteStateType) :: Morison !< discrete states from the Morison module [-] END TYPE HydroDyn_DiscreteStateType @@ -146,51 +147,58 @@ MODULE HydroDyn_Types ! ======================= ! ========= HydroDyn_OtherStateType ======= TYPE, PUBLIC :: HydroDyn_OtherStateType - TYPE(WAMIT_OtherStateType) :: WAMIT !< OtherState information from the WAMIT module [-] - TYPE(WAMIT2_OtherStateType) :: WAMIT2 !< OtherState information from the WAMIT2 module [-] + TYPE(WAMIT_OtherStateType) , DIMENSION(:), ALLOCATABLE :: WAMIT !< OtherState information from the WAMIT module [-] + TYPE(WAMIT2_OtherStateType) , DIMENSION(:), ALLOCATABLE :: WAMIT2 !< OtherState information from the WAMIT2 module [-] TYPE(Waves2_OtherStateType) :: Waves2 !< OtherState information from the Waves2 module [-] TYPE(Morison_OtherStateType) :: Morison !< OtherState information from the Morison module [-] END TYPE HydroDyn_OtherStateType ! ======================= ! ========= HydroDyn_MiscVarType ======= TYPE, PUBLIC :: HydroDyn_MiscVarType - TYPE(MeshType) :: y_mapped !< An intermediate mesh used to transfer hydrodynamic loads from the various HD-related meshes to the AllHdroOrigin mesh [-] - TYPE(MeshType) :: AllHdroOrigin_position !< A motions mesh which has all translational displacements set to zero. Used in the transfer of hydrodynamic loads from the various HD-related meshes to the AllHdroOrigin mesh [-] - TYPE(MeshType) :: MrsnLumpedMesh_position !< A motions mesh which has all translational displacements set to zero. Used in the transfer of hydrodynamic loads from the various HD-related meshes to the AllHdroOrigin mesh [-] - TYPE(MeshType) :: MrsnDistribMesh_position !< A motions mesh which has all translational displacements set to zero. Used in the transfer of hydrodynamic loads from the various HD-related meshes to the AllHdroOrigin mesh [-] + TYPE(MeshType) :: AllHdroOrigin !< An intermediate mesh used to transfer hydrodynamic loads from the various HD-related meshes to the AllHdroOrigin mesh [-] + TYPE(MeshType) :: MrsnMesh_position !< A motions mesh which has all translational displacements set to zero. Used in the transfer of hydrodynamic loads from the various HD-related meshes to the AllHdroOrigin mesh [-] TYPE(HD_ModuleMapType) :: HD_MeshMap INTEGER(IntKi) :: Decimate !< The output decimation counter [-] REAL(DbKi) :: LastOutTime !< Last time step which was written to the output file (sec) [-] INTEGER(IntKi) :: LastIndWave !< The last index used in the wave kinematics arrays, used to optimize interpolation [-] - REAL(ReKi) , DIMENSION(1:6) :: F_PtfmAdd !< The total forces and moments due to additional pre-load, stiffness, and damping [-] - REAL(ReKi) , DIMENSION(1:6) :: F_Hydro !< The total hydrodynamic forces and moments integrated about the WAMIT reference point [-] - REAL(ReKi) , DIMENSION(1:6) :: F_Waves !< The total waves forces on a WAMIT body calculated by first and second order methods (WAMIT and WAMIT2 modules) [-] - TYPE(WAMIT_MiscVarType) :: WAMIT !< misc var information from the WAMIT module [-] - TYPE(WAMIT2_MiscVarType) :: WAMIT2 !< misc var information from the WAMIT2 module [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: F_PtfmAdd !< The total forces and moments due to additional pre-load, stiffness, and damping [-] + REAL(ReKi) , DIMENSION(1:6) :: F_Hydro !< The total hydrodynamic forces and moments integrated about the (0,0,0) platform reference point [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: F_Waves !< The total waves forces on a WAMIT body calculated by first and second order methods (WAMIT and WAMIT2 modules) [-] + TYPE(WAMIT_MiscVarType) , DIMENSION(:), ALLOCATABLE :: WAMIT !< misc var information from the WAMIT module [-] + TYPE(WAMIT2_MiscVarType) , DIMENSION(:), ALLOCATABLE :: WAMIT2 !< misc var information from the WAMIT2 module [-] TYPE(Waves2_MiscVarType) :: Waves2 !< misc var information from the Waves2 module [-] TYPE(Morison_MiscVarType) :: Morison !< misc var information from the Morison module [-] - TYPE(WAMIT_InputType) :: u_WAMIT !< WAMIT module inputs [-] - TYPE(WAMIT2_InputType) :: u_WAMIT2 !< WAMIT2 module inputs [-] + TYPE(WAMIT_InputType) , DIMENSION(:), ALLOCATABLE :: u_WAMIT !< WAMIT module inputs [-] + TYPE(WAMIT2_InputType) , DIMENSION(:), ALLOCATABLE :: u_WAMIT2 !< WAMIT2 module inputs [-] TYPE(Waves2_InputType) :: u_Waves2 !< Waves2 module inputs [-] END TYPE HydroDyn_MiscVarType ! ======================= ! ========= HydroDyn_ParameterType ======= TYPE, PUBLIC :: HydroDyn_ParameterType - TYPE(WAMIT_ParameterType) :: WAMIT !< Parameter data for the WAMIT module [-] - TYPE(WAMIT2_ParameterType) :: WAMIT2 !< Parameter data for the WAMIT2 module [-] + INTEGER(IntKi) :: nWAMITObj !< number of WAMIT input files and matrices. If NBodyMod = 1 then nPotFiles will be 1 even if NBody > 1 [-] + INTEGER(IntKi) :: vecMultiplier !< multiplier for the WAMIT vectors and matrices. If NBodyMod=1 then this = NBody, else 1 [-] + TYPE(WAMIT_ParameterType) , DIMENSION(:), ALLOCATABLE :: WAMIT !< Parameter data for the WAMIT module [-] + TYPE(WAMIT2_ParameterType) , DIMENSION(:), ALLOCATABLE :: WAMIT2 !< Parameter data for the WAMIT2 module [-] + LOGICAL :: WAMIT2used = .FALSE. !< Indicates when WAMIT2 is used. Shortcuts some calculations [-] TYPE(Waves2_ParameterType) :: Waves2 !< Parameter data for the Waves2 module [-] TYPE(Morison_ParameterType) :: Morison !< Parameter data for the Morison module [-] INTEGER(IntKi) :: PotMod !< 1 if using WAMIT model, 0 if no potential flow model, or 2 if FIT model [-] + INTEGER(IntKi) :: NBody !< [>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6] [-] + INTEGER(IntKi) :: NBodyMod !< Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1] [-] + INTEGER(IntKi) :: totalStates !< Number of excitation and radiation states for all WAMIT bodies [-] + INTEGER(IntKi) :: totalExctnStates !< Number of excitation states for all WAMIT bodies [-] + INTEGER(IntKi) :: totalRdtnStates !< Number of radiation states for all WAMIT bodies [-] REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveTime !< Array of time samples, (sec) [-] INTEGER(IntKi) :: NStepWave !< Number of data points in the wave kinematics arrays [-] INTEGER(IntKi) :: NWaveElev !< Number of wave elevation outputs [-] REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: WaveElev !< Total wave elevation [-] REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: WaveElev1 !< First order wave elevation [-] + REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: WaveElev2 !< Second order wave elevation [-] REAL(ReKi) :: WtrDpth !< Water depth [(m)] - REAL(ReKi) , DIMENSION(1:6) :: AddF0 !< Additional pre-load forces and moments (N,N,N,N-m,N-m,N-m) [-] - REAL(ReKi) , DIMENSION(1:6,1:6) :: AddCLin !< Additional stiffness matrix [-] - REAL(ReKi) , DIMENSION(1:6,1:6) :: AddBLin !< Additional linear damping matrix [-] - REAL(ReKi) , DIMENSION(1:6,1:6) :: AddBQuad !< Additional quadratic damping (drag) matrix [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: AddF0 !< Additional pre-load forces and moments (N,N,N,N-m,N-m,N-m) [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: AddCLin !< Additional stiffness matrix [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: AddBLin !< Additional linear damping matrix [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: AddBQuad !< Additional quadratic damping (drag) matrix [-] REAL(DbKi) :: DT !< Time step in seconds for integration of continuous states (if a fixed-step integrator is used) and update of discrete states [-] TYPE(OutParmType) , DIMENSION(:), ALLOCATABLE :: OutParam !< [-] INTEGER(IntKi) :: NumOuts !< Number of HydroDyn module-level outputs (not the total number including sub-modules [-] @@ -210,18 +218,18 @@ MODULE HydroDyn_Types ! ========= HydroDyn_InputType ======= TYPE, PUBLIC :: HydroDyn_InputType TYPE(Morison_InputType) :: Morison !< Morison module inputs [-] - TYPE(MeshType) :: Mesh !< Displacements at the WAMIT reference point in the inertial frame [-] + TYPE(MeshType) :: WAMITMesh !< Motions at the WAMIT reference point(s) in the inertial frame [-] + TYPE(MeshType) :: PRPMesh !< Motions at the Platform reference point in the inertial frame [-] END TYPE HydroDyn_InputType ! ======================= ! ========= HydroDyn_OutputType ======= TYPE, PUBLIC :: HydroDyn_OutputType - TYPE(WAMIT_OutputType) :: WAMIT !< WAMIT module outputs [-] - TYPE(WAMIT2_OutputType) :: WAMIT2 !< WAMIT2 module outputs [-] + TYPE(WAMIT_OutputType) , DIMENSION(:), ALLOCATABLE :: WAMIT !< WAMIT module outputs [-] + TYPE(WAMIT2_OutputType) , DIMENSION(:), ALLOCATABLE :: WAMIT2 !< WAMIT2 module outputs [-] TYPE(Waves2_OutputType) :: Waves2 !< Waves2 module outputs [-] TYPE(Morison_OutputType) :: Morison !< Morison module outputs [-] - TYPE(MeshType) :: Mesh !< Point Loads at the WAMIT reference point in the inertial frame [-] - TYPE(MeshType) :: AllHdroOrigin !< All HD-related loads integrated to the origin, (0,0,0) in the inertial frame [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WriteOutput !< [-] + TYPE(MeshType) :: WAMITMesh !< Point Loads at the WAMIT reference point(s) in the inertial frame [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WriteOutput !< Outputs to be written to the output file(s) [-] END TYPE HydroDyn_OutputType ! ======================= CONTAINS @@ -235,6 +243,7 @@ SUBROUTINE HydroDyn_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_CopyInitInput' @@ -265,22 +274,68 @@ SUBROUTINE HydroDyn_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ENDIF DstInitInputData%PtfmLocationX = SrcInitInputData%PtfmLocationX DstInitInputData%PtfmLocationY = SrcInitInputData%PtfmLocationY - DstInitInputData%PtfmSgFChr = SrcInitInputData%PtfmSgFChr - DstInitInputData%PtfmSgF = SrcInitInputData%PtfmSgF - DstInitInputData%PtfmSwFChr = SrcInitInputData%PtfmSwFChr - DstInitInputData%PtfmSwF = SrcInitInputData%PtfmSwF - DstInitInputData%PtfmHvFChr = SrcInitInputData%PtfmHvFChr - DstInitInputData%PtfmHvF = SrcInitInputData%PtfmHvF - DstInitInputData%PtfmRFChr = SrcInitInputData%PtfmRFChr - DstInitInputData%PtfmRF = SrcInitInputData%PtfmRF - DstInitInputData%PtfmPFChr = SrcInitInputData%PtfmPFChr - DstInitInputData%PtfmPF = SrcInitInputData%PtfmPF - DstInitInputData%PtfmYFChr = SrcInitInputData%PtfmYFChr - DstInitInputData%PtfmYF = SrcInitInputData%PtfmYF +IF (ALLOCATED(SrcInitInputData%AddF0)) THEN + i1_l = LBOUND(SrcInitInputData%AddF0,1) + i1_u = UBOUND(SrcInitInputData%AddF0,1) + i2_l = LBOUND(SrcInitInputData%AddF0,2) + i2_u = UBOUND(SrcInitInputData%AddF0,2) + IF (.NOT. ALLOCATED(DstInitInputData%AddF0)) THEN + ALLOCATE(DstInitInputData%AddF0(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%AddF0.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInitInputData%AddF0 = SrcInitInputData%AddF0 +ENDIF +IF (ALLOCATED(SrcInitInputData%AddCLin)) THEN + i1_l = LBOUND(SrcInitInputData%AddCLin,1) + i1_u = UBOUND(SrcInitInputData%AddCLin,1) + i2_l = LBOUND(SrcInitInputData%AddCLin,2) + i2_u = UBOUND(SrcInitInputData%AddCLin,2) + i3_l = LBOUND(SrcInitInputData%AddCLin,3) + i3_u = UBOUND(SrcInitInputData%AddCLin,3) + IF (.NOT. ALLOCATED(DstInitInputData%AddCLin)) THEN + ALLOCATE(DstInitInputData%AddCLin(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%AddCLin.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInitInputData%AddCLin = SrcInitInputData%AddCLin +ENDIF +IF (ALLOCATED(SrcInitInputData%AddBLin)) THEN + i1_l = LBOUND(SrcInitInputData%AddBLin,1) + i1_u = UBOUND(SrcInitInputData%AddBLin,1) + i2_l = LBOUND(SrcInitInputData%AddBLin,2) + i2_u = UBOUND(SrcInitInputData%AddBLin,2) + i3_l = LBOUND(SrcInitInputData%AddBLin,3) + i3_u = UBOUND(SrcInitInputData%AddBLin,3) + IF (.NOT. ALLOCATED(DstInitInputData%AddBLin)) THEN + ALLOCATE(DstInitInputData%AddBLin(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%AddBLin.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInitInputData%AddBLin = SrcInitInputData%AddBLin +ENDIF +IF (ALLOCATED(SrcInitInputData%AddBQuad)) THEN + i1_l = LBOUND(SrcInitInputData%AddBQuad,1) + i1_u = UBOUND(SrcInitInputData%AddBQuad,1) + i2_l = LBOUND(SrcInitInputData%AddBQuad,2) + i2_u = UBOUND(SrcInitInputData%AddBQuad,2) + i3_l = LBOUND(SrcInitInputData%AddBQuad,3) + i3_u = UBOUND(SrcInitInputData%AddBQuad,3) + IF (.NOT. ALLOCATED(DstInitInputData%AddBQuad)) THEN + ALLOCATE(DstInitInputData%AddBQuad(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%AddBQuad.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInitInputData%AddBQuad = SrcInitInputData%AddBQuad +ENDIF CALL Waves_CopyInitInput( SrcInitInputData%Waves, DstInitInputData%Waves, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -290,7 +345,119 @@ SUBROUTINE HydroDyn_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, CALL Current_CopyInitInput( SrcInitInputData%Current, DstInitInputData%Current, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcInitInputData%PotFile)) THEN + i1_l = LBOUND(SrcInitInputData%PotFile,1) + i1_u = UBOUND(SrcInitInputData%PotFile,1) + IF (.NOT. ALLOCATED(DstInitInputData%PotFile)) THEN + ALLOCATE(DstInitInputData%PotFile(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PotFile.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInitInputData%PotFile = SrcInitInputData%PotFile +ENDIF + DstInitInputData%nWAMITObj = SrcInitInputData%nWAMITObj + DstInitInputData%vecMultiplier = SrcInitInputData%vecMultiplier + DstInitInputData%NBody = SrcInitInputData%NBody + DstInitInputData%NBodyMod = SrcInitInputData%NBodyMod +IF (ALLOCATED(SrcInitInputData%PtfmVol0)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmVol0,1) + i1_u = UBOUND(SrcInitInputData%PtfmVol0,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmVol0)) THEN + ALLOCATE(DstInitInputData%PtfmVol0(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmVol0.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmVol0 = SrcInitInputData%PtfmVol0 +ENDIF + DstInitInputData%HasWAMIT = SrcInitInputData%HasWAMIT +IF (ALLOCATED(SrcInitInputData%WAMITULEN)) THEN + i1_l = LBOUND(SrcInitInputData%WAMITULEN,1) + i1_u = UBOUND(SrcInitInputData%WAMITULEN,1) + IF (.NOT. ALLOCATED(DstInitInputData%WAMITULEN)) THEN + ALLOCATE(DstInitInputData%WAMITULEN(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%WAMITULEN.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%WAMITULEN = SrcInitInputData%WAMITULEN +ENDIF +IF (ALLOCATED(SrcInitInputData%PtfmRefxt)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmRefxt,1) + i1_u = UBOUND(SrcInitInputData%PtfmRefxt,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmRefxt)) THEN + ALLOCATE(DstInitInputData%PtfmRefxt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmRefxt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmRefxt = SrcInitInputData%PtfmRefxt +ENDIF +IF (ALLOCATED(SrcInitInputData%PtfmRefyt)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmRefyt,1) + i1_u = UBOUND(SrcInitInputData%PtfmRefyt,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmRefyt)) THEN + ALLOCATE(DstInitInputData%PtfmRefyt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmRefyt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmRefyt = SrcInitInputData%PtfmRefyt +ENDIF +IF (ALLOCATED(SrcInitInputData%PtfmRefzt)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmRefzt,1) + i1_u = UBOUND(SrcInitInputData%PtfmRefzt,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmRefzt)) THEN + ALLOCATE(DstInitInputData%PtfmRefzt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmRefzt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmRefzt = SrcInitInputData%PtfmRefzt +ENDIF +IF (ALLOCATED(SrcInitInputData%PtfmRefztRot)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmRefztRot,1) + i1_u = UBOUND(SrcInitInputData%PtfmRefztRot,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmRefztRot)) THEN + ALLOCATE(DstInitInputData%PtfmRefztRot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmRefztRot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmRefztRot = SrcInitInputData%PtfmRefztRot +ENDIF +IF (ALLOCATED(SrcInitInputData%PtfmCOBxt)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmCOBxt,1) + i1_u = UBOUND(SrcInitInputData%PtfmCOBxt,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmCOBxt)) THEN + ALLOCATE(DstInitInputData%PtfmCOBxt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmCOBxt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmCOBxt = SrcInitInputData%PtfmCOBxt +ENDIF +IF (ALLOCATED(SrcInitInputData%PtfmCOByt)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmCOByt,1) + i1_u = UBOUND(SrcInitInputData%PtfmCOByt,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmCOByt)) THEN + ALLOCATE(DstInitInputData%PtfmCOByt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmCOByt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmCOByt = SrcInitInputData%PtfmCOByt +ENDIF CALL WAMIT_CopyInitInput( SrcInitInputData%WAMIT, DstInitInputData%WAMIT, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -318,7 +485,18 @@ SUBROUTINE HydroDyn_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, DstInitInputData%OutSwtch = SrcInitInputData%OutSwtch DstInitInputData%OutAll = SrcInitInputData%OutAll DstInitInputData%NumOuts = SrcInitInputData%NumOuts +IF (ALLOCATED(SrcInitInputData%OutList)) THEN + i1_l = LBOUND(SrcInitInputData%OutList,1) + i1_u = UBOUND(SrcInitInputData%OutList,1) + IF (.NOT. ALLOCATED(DstInitInputData%OutList)) THEN + ALLOCATE(DstInitInputData%OutList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%OutList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInitInputData%OutList = SrcInitInputData%OutList +ENDIF DstInitInputData%HDSum = SrcInitInputData%HDSum DstInitInputData%UnSum = SrcInitInputData%UnSum DstInitInputData%OutFmt = SrcInitInputData%OutFmt @@ -336,15 +514,57 @@ SUBROUTINE HydroDyn_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) ErrMsg = "" IF (ALLOCATED(InitInputData%WaveElevXY)) THEN DEALLOCATE(InitInputData%WaveElevXY) +ENDIF +IF (ALLOCATED(InitInputData%AddF0)) THEN + DEALLOCATE(InitInputData%AddF0) +ENDIF +IF (ALLOCATED(InitInputData%AddCLin)) THEN + DEALLOCATE(InitInputData%AddCLin) +ENDIF +IF (ALLOCATED(InitInputData%AddBLin)) THEN + DEALLOCATE(InitInputData%AddBLin) +ENDIF +IF (ALLOCATED(InitInputData%AddBQuad)) THEN + DEALLOCATE(InitInputData%AddBQuad) ENDIF CALL Waves_DestroyInitInput( InitInputData%Waves, ErrStat, ErrMsg ) CALL Waves2_DestroyInitInput( InitInputData%Waves2, ErrStat, ErrMsg ) CALL Current_DestroyInitInput( InitInputData%Current, ErrStat, ErrMsg ) +IF (ALLOCATED(InitInputData%PotFile)) THEN + DEALLOCATE(InitInputData%PotFile) +ENDIF +IF (ALLOCATED(InitInputData%PtfmVol0)) THEN + DEALLOCATE(InitInputData%PtfmVol0) +ENDIF +IF (ALLOCATED(InitInputData%WAMITULEN)) THEN + DEALLOCATE(InitInputData%WAMITULEN) +ENDIF +IF (ALLOCATED(InitInputData%PtfmRefxt)) THEN + DEALLOCATE(InitInputData%PtfmRefxt) +ENDIF +IF (ALLOCATED(InitInputData%PtfmRefyt)) THEN + DEALLOCATE(InitInputData%PtfmRefyt) +ENDIF +IF (ALLOCATED(InitInputData%PtfmRefzt)) THEN + DEALLOCATE(InitInputData%PtfmRefzt) +ENDIF +IF (ALLOCATED(InitInputData%PtfmRefztRot)) THEN + DEALLOCATE(InitInputData%PtfmRefztRot) +ENDIF +IF (ALLOCATED(InitInputData%PtfmCOBxt)) THEN + DEALLOCATE(InitInputData%PtfmCOBxt) +ENDIF +IF (ALLOCATED(InitInputData%PtfmCOByt)) THEN + DEALLOCATE(InitInputData%PtfmCOByt) +ENDIF CALL WAMIT_DestroyInitInput( InitInputData%WAMIT, ErrStat, ErrMsg ) CALL WAMIT2_DestroyInitInput( InitInputData%WAMIT2, ErrStat, ErrMsg ) CALL Morison_DestroyInitInput( InitInputData%Morison, ErrStat, ErrMsg ) IF (ALLOCATED(InitInputData%UserOutputs)) THEN DEALLOCATE(InitInputData%UserOutputs) +ENDIF +IF (ALLOCATED(InitInputData%OutList)) THEN + DEALLOCATE(InitInputData%OutList) ENDIF END SUBROUTINE HydroDyn_DestroyInitInput @@ -398,22 +618,26 @@ SUBROUTINE HydroDyn_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF Re_BufSz = Re_BufSz + 1 ! PtfmLocationX Re_BufSz = Re_BufSz + 1 ! PtfmLocationY - Int_BufSz = Int_BufSz + 1*LEN(InData%PtfmSgFChr) ! PtfmSgFChr - Int_BufSz = Int_BufSz + 1 ! PtfmSgF - Int_BufSz = Int_BufSz + 1*LEN(InData%PtfmSwFChr) ! PtfmSwFChr - Int_BufSz = Int_BufSz + 1 ! PtfmSwF - Int_BufSz = Int_BufSz + 1*LEN(InData%PtfmHvFChr) ! PtfmHvFChr - Int_BufSz = Int_BufSz + 1 ! PtfmHvF - Int_BufSz = Int_BufSz + 1*LEN(InData%PtfmRFChr) ! PtfmRFChr - Int_BufSz = Int_BufSz + 1 ! PtfmRF - Int_BufSz = Int_BufSz + 1*LEN(InData%PtfmPFChr) ! PtfmPFChr - Int_BufSz = Int_BufSz + 1 ! PtfmPF - Int_BufSz = Int_BufSz + 1*LEN(InData%PtfmYFChr) ! PtfmYFChr - Int_BufSz = Int_BufSz + 1 ! PtfmYF + Int_BufSz = Int_BufSz + 1 ! AddF0 allocated yes/no + IF ( ALLOCATED(InData%AddF0) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! AddF0 upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%AddF0) ! AddF0 + END IF + Int_BufSz = Int_BufSz + 1 ! AddCLin allocated yes/no + IF ( ALLOCATED(InData%AddCLin) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! AddCLin upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%AddCLin) ! AddCLin + END IF + Int_BufSz = Int_BufSz + 1 ! AddBLin allocated yes/no + IF ( ALLOCATED(InData%AddBLin) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! AddBLin upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%AddBLin) ! AddBLin + END IF + Int_BufSz = Int_BufSz + 1 ! AddBQuad allocated yes/no + IF ( ALLOCATED(InData%AddBQuad) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! AddBQuad upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%AddBQuad) ! AddBQuad + END IF ! Allocate buffers for subtypes, if any (we'll get sizes from these) Int_BufSz = Int_BufSz + 3 ! Waves: size of buffers for each call to pack subtype CALL Waves_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%Waves, ErrStat2, ErrMsg2, .TRUE. ) ! Waves @@ -466,7 +690,56 @@ SUBROUTINE HydroDyn_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 1*LEN(InData%PotFile) ! PotFile + Int_BufSz = Int_BufSz + 1 ! PotFile allocated yes/no + IF ( ALLOCATED(InData%PotFile) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PotFile upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%PotFile)*LEN(InData%PotFile) ! PotFile + END IF + Int_BufSz = Int_BufSz + 1 ! nWAMITObj + Int_BufSz = Int_BufSz + 1 ! vecMultiplier + Int_BufSz = Int_BufSz + 1 ! NBody + Int_BufSz = Int_BufSz + 1 ! NBodyMod + Int_BufSz = Int_BufSz + 1 ! PtfmVol0 allocated yes/no + IF ( ALLOCATED(InData%PtfmVol0) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmVol0 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PtfmVol0) ! PtfmVol0 + END IF + Int_BufSz = Int_BufSz + 1 ! HasWAMIT + Int_BufSz = Int_BufSz + 1 ! WAMITULEN allocated yes/no + IF ( ALLOCATED(InData%WAMITULEN) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WAMITULEN upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WAMITULEN) ! WAMITULEN + END IF + Int_BufSz = Int_BufSz + 1 ! PtfmRefxt allocated yes/no + IF ( ALLOCATED(InData%PtfmRefxt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmRefxt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PtfmRefxt) ! PtfmRefxt + END IF + Int_BufSz = Int_BufSz + 1 ! PtfmRefyt allocated yes/no + IF ( ALLOCATED(InData%PtfmRefyt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmRefyt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PtfmRefyt) ! PtfmRefyt + END IF + Int_BufSz = Int_BufSz + 1 ! PtfmRefzt allocated yes/no + IF ( ALLOCATED(InData%PtfmRefzt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmRefzt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PtfmRefzt) ! PtfmRefzt + END IF + Int_BufSz = Int_BufSz + 1 ! PtfmRefztRot allocated yes/no + IF ( ALLOCATED(InData%PtfmRefztRot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmRefztRot upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%PtfmRefztRot) ! PtfmRefztRot + END IF + Int_BufSz = Int_BufSz + 1 ! PtfmCOBxt allocated yes/no + IF ( ALLOCATED(InData%PtfmCOBxt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmCOBxt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PtfmCOBxt) ! PtfmCOBxt + END IF + Int_BufSz = Int_BufSz + 1 ! PtfmCOByt allocated yes/no + IF ( ALLOCATED(InData%PtfmCOByt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmCOByt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PtfmCOByt) ! PtfmCOByt + END IF Int_BufSz = Int_BufSz + 3 ! WAMIT: size of buffers for each call to pack subtype CALL WAMIT_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -529,7 +802,11 @@ SUBROUTINE HydroDyn_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + 1 ! OutSwtch Int_BufSz = Int_BufSz + 1 ! OutAll Int_BufSz = Int_BufSz + 1 ! NumOuts + Int_BufSz = Int_BufSz + 1 ! OutList allocated yes/no + IF ( ALLOCATED(InData%OutList) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! OutList upper/lower bounds for each dimension Int_BufSz = Int_BufSz + SIZE(InData%OutList)*LEN(InData%OutList) ! OutList + END IF Int_BufSz = Int_BufSz + 1 ! HDSum Int_BufSz = Int_BufSz + 1 ! UnSum Int_BufSz = Int_BufSz + 1*LEN(InData%OutFmt) ! OutFmt @@ -605,64 +882,101 @@ SUBROUTINE HydroDyn_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%PtfmLocationY Re_Xferred = Re_Xferred + 1 - DO I = 1, LEN(InData%PtfmSgFChr) - IntKiBuf(Int_Xferred) = ICHAR(InData%PtfmSgFChr(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmSgF, IntKiBuf(1)) + IF ( .NOT. ALLOCATED(InData%AddF0) ) THEN + IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(InData%PtfmSwFChr) - IntKiBuf(Int_Xferred) = ICHAR(InData%PtfmSwFChr(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmSwF, IntKiBuf(1)) + ELSE + IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(InData%PtfmHvFChr) - IntKiBuf(Int_Xferred) = ICHAR(InData%PtfmHvFChr(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmHvF, IntKiBuf(1)) + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddF0,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddF0,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddF0,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddF0,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%AddF0,2), UBOUND(InData%AddF0,2) + DO i1 = LBOUND(InData%AddF0,1), UBOUND(InData%AddF0,1) + ReKiBuf(Re_Xferred) = InData%AddF0(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AddCLin) ) THEN + IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(InData%PtfmRFChr) - IntKiBuf(Int_Xferred) = ICHAR(InData%PtfmRFChr(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmRF, IntKiBuf(1)) + ELSE + IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(InData%PtfmPFChr) - IntKiBuf(Int_Xferred) = ICHAR(InData%PtfmPFChr(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmPF, IntKiBuf(1)) + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddCLin,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddCLin,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddCLin,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddCLin,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddCLin,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddCLin,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%AddCLin,3), UBOUND(InData%AddCLin,3) + DO i2 = LBOUND(InData%AddCLin,2), UBOUND(InData%AddCLin,2) + DO i1 = LBOUND(InData%AddCLin,1), UBOUND(InData%AddCLin,1) + ReKiBuf(Re_Xferred) = InData%AddCLin(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AddBLin) ) THEN + IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(InData%PtfmYFChr) - IntKiBuf(Int_Xferred) = ICHAR(InData%PtfmYFChr(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmYF, IntKiBuf(1)) + ELSE + IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%AddF0,1), UBOUND(InData%AddF0,1) - ReKiBuf(Re_Xferred) = InData%AddF0(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i2 = LBOUND(InData%AddCLin,2), UBOUND(InData%AddCLin,2) - DO i1 = LBOUND(InData%AddCLin,1), UBOUND(InData%AddCLin,1) - ReKiBuf(Re_Xferred) = InData%AddCLin(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - DO i2 = LBOUND(InData%AddBLin,2), UBOUND(InData%AddBLin,2) - DO i1 = LBOUND(InData%AddBLin,1), UBOUND(InData%AddBLin,1) - ReKiBuf(Re_Xferred) = InData%AddBLin(i1,i2) - Re_Xferred = Re_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddBLin,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddBLin,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddBLin,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddBLin,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddBLin,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddBLin,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%AddBLin,3), UBOUND(InData%AddBLin,3) + DO i2 = LBOUND(InData%AddBLin,2), UBOUND(InData%AddBLin,2) + DO i1 = LBOUND(InData%AddBLin,1), UBOUND(InData%AddBLin,1) + ReKiBuf(Re_Xferred) = InData%AddBLin(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END DO - END DO - DO i2 = LBOUND(InData%AddBQuad,2), UBOUND(InData%AddBQuad,2) - DO i1 = LBOUND(InData%AddBQuad,1), UBOUND(InData%AddBQuad,1) - ReKiBuf(Re_Xferred) = InData%AddBQuad(i1,i2) - Re_Xferred = Re_Xferred + 1 + END IF + IF ( .NOT. ALLOCATED(InData%AddBQuad) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddBQuad,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddBQuad,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddBQuad,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddBQuad,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddBQuad,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddBQuad,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%AddBQuad,3), UBOUND(InData%AddBQuad,3) + DO i2 = LBOUND(InData%AddBQuad,2), UBOUND(InData%AddBQuad,2) + DO i1 = LBOUND(InData%AddBQuad,1), UBOUND(InData%AddBQuad,1) + ReKiBuf(Re_Xferred) = InData%AddBQuad(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END DO - END DO + END IF CALL Waves_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%Waves, ErrStat2, ErrMsg2, OnlySize ) ! Waves CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -747,10 +1061,153 @@ SUBROUTINE HydroDyn_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - DO I = 1, LEN(InData%PotFile) - IntKiBuf(Int_Xferred) = ICHAR(InData%PotFile(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I + IF ( .NOT. ALLOCATED(InData%PotFile) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PotFile,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PotFile,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PotFile,1), UBOUND(InData%PotFile,1) + DO I = 1, LEN(InData%PotFile) + IntKiBuf(Int_Xferred) = ICHAR(InData%PotFile(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IntKiBuf(Int_Xferred) = InData%nWAMITObj + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%vecMultiplier + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NBody + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NBodyMod + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%PtfmVol0) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmVol0,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmVol0,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmVol0,1), UBOUND(InData%PtfmVol0,1) + ReKiBuf(Re_Xferred) = InData%PtfmVol0(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IntKiBuf(Int_Xferred) = TRANSFER(InData%HasWAMIT, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%WAMITULEN) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAMITULEN,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAMITULEN,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WAMITULEN,1), UBOUND(InData%WAMITULEN,1) + ReKiBuf(Re_Xferred) = InData%WAMITULEN(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PtfmRefxt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmRefxt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmRefxt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmRefxt,1), UBOUND(InData%PtfmRefxt,1) + ReKiBuf(Re_Xferred) = InData%PtfmRefxt(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PtfmRefyt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmRefyt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmRefyt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmRefyt,1), UBOUND(InData%PtfmRefyt,1) + ReKiBuf(Re_Xferred) = InData%PtfmRefyt(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PtfmRefzt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmRefzt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmRefzt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmRefzt,1), UBOUND(InData%PtfmRefzt,1) + ReKiBuf(Re_Xferred) = InData%PtfmRefzt(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PtfmRefztRot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmRefztRot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmRefztRot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmRefztRot,1), UBOUND(InData%PtfmRefztRot,1) + DbKiBuf(Db_Xferred) = InData%PtfmRefztRot(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PtfmCOBxt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmCOBxt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmCOBxt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmCOBxt,1), UBOUND(InData%PtfmCOBxt,1) + ReKiBuf(Re_Xferred) = InData%PtfmCOBxt(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PtfmCOByt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmCOByt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmCOByt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmCOByt,1), UBOUND(InData%PtfmCOByt,1) + ReKiBuf(Re_Xferred) = InData%PtfmCOByt(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF CALL WAMIT_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, OnlySize ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -864,12 +1321,23 @@ SUBROUTINE HydroDyn_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NumOuts Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%OutList,1), UBOUND(InData%OutList,1) - DO I = 1, LEN(InData%OutList) - IntKiBuf(Int_Xferred) = ICHAR(InData%OutList(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO + IF ( .NOT. ALLOCATED(InData%OutList) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%OutList,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%OutList,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%OutList,1), UBOUND(InData%OutList,1) + DO I = 1, LEN(InData%OutList) + IntKiBuf(Int_Xferred) = ICHAR(InData%OutList(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF IntKiBuf(Int_Xferred) = TRANSFER(InData%HDSum, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%UnSum @@ -899,6 +1367,7 @@ SUBROUTINE HydroDyn_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_UnPackInitInput' @@ -959,78 +1428,113 @@ SUBROUTINE HydroDyn_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Re_Xferred = Re_Xferred + 1 OutData%PtfmLocationY = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - DO I = 1, LEN(OutData%PtfmSgFChr) - OutData%PtfmSgFChr(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%PtfmSgF = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmSgF) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AddF0 not allocated Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(OutData%PtfmSwFChr) - OutData%PtfmSwFChr(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%PtfmSwF = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmSwF) + ELSE Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(OutData%PtfmHvFChr) - OutData%PtfmHvFChr(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%PtfmHvF = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmHvF) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AddF0)) DEALLOCATE(OutData%AddF0) + ALLOCATE(OutData%AddF0(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AddF0.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%AddF0,2), UBOUND(OutData%AddF0,2) + DO i1 = LBOUND(OutData%AddF0,1), UBOUND(OutData%AddF0,1) + OutData%AddF0(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AddCLin not allocated Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(OutData%PtfmRFChr) - OutData%PtfmRFChr(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%PtfmRF = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmRF) + ELSE Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(OutData%PtfmPFChr) - OutData%PtfmPFChr(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%PtfmPF = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmPF) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AddCLin)) DEALLOCATE(OutData%AddCLin) + ALLOCATE(OutData%AddCLin(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AddCLin.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%AddCLin,3), UBOUND(OutData%AddCLin,3) + DO i2 = LBOUND(OutData%AddCLin,2), UBOUND(OutData%AddCLin,2) + DO i1 = LBOUND(OutData%AddCLin,1), UBOUND(OutData%AddCLin,1) + OutData%AddCLin(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AddBLin not allocated Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(OutData%PtfmYFChr) - OutData%PtfmYFChr(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%PtfmYF = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmYF) + ELSE Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%AddF0,1) - i1_u = UBOUND(OutData%AddF0,1) - DO i1 = LBOUND(OutData%AddF0,1), UBOUND(OutData%AddF0,1) - OutData%AddF0(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%AddCLin,1) - i1_u = UBOUND(OutData%AddCLin,1) - i2_l = LBOUND(OutData%AddCLin,2) - i2_u = UBOUND(OutData%AddCLin,2) - DO i2 = LBOUND(OutData%AddCLin,2), UBOUND(OutData%AddCLin,2) - DO i1 = LBOUND(OutData%AddCLin,1), UBOUND(OutData%AddCLin,1) - OutData%AddCLin(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - i1_l = LBOUND(OutData%AddBLin,1) - i1_u = UBOUND(OutData%AddBLin,1) - i2_l = LBOUND(OutData%AddBLin,2) - i2_u = UBOUND(OutData%AddBLin,2) - DO i2 = LBOUND(OutData%AddBLin,2), UBOUND(OutData%AddBLin,2) - DO i1 = LBOUND(OutData%AddBLin,1), UBOUND(OutData%AddBLin,1) - OutData%AddBLin(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AddBLin)) DEALLOCATE(OutData%AddBLin) + ALLOCATE(OutData%AddBLin(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AddBLin.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%AddBLin,3), UBOUND(OutData%AddBLin,3) + DO i2 = LBOUND(OutData%AddBLin,2), UBOUND(OutData%AddBLin,2) + DO i1 = LBOUND(OutData%AddBLin,1), UBOUND(OutData%AddBLin,1) + OutData%AddBLin(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END DO - END DO - i1_l = LBOUND(OutData%AddBQuad,1) - i1_u = UBOUND(OutData%AddBQuad,1) - i2_l = LBOUND(OutData%AddBQuad,2) - i2_u = UBOUND(OutData%AddBQuad,2) - DO i2 = LBOUND(OutData%AddBQuad,2), UBOUND(OutData%AddBQuad,2) - DO i1 = LBOUND(OutData%AddBQuad,1), UBOUND(OutData%AddBQuad,1) - OutData%AddBQuad(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AddBQuad not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AddBQuad)) DEALLOCATE(OutData%AddBQuad) + ALLOCATE(OutData%AddBQuad(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AddBQuad.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%AddBQuad,3), UBOUND(OutData%AddBQuad,3) + DO i2 = LBOUND(OutData%AddBQuad,2), UBOUND(OutData%AddBQuad,2) + DO i1 = LBOUND(OutData%AddBQuad,1), UBOUND(OutData%AddBQuad,1) + OutData%AddBQuad(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END DO - END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -1151,10 +1655,180 @@ SUBROUTINE HydroDyn_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - DO I = 1, LEN(OutData%PotFile) - OutData%PotFile(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PotFile not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PotFile)) DEALLOCATE(OutData%PotFile) + ALLOCATE(OutData%PotFile(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PotFile.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PotFile,1), UBOUND(OutData%PotFile,1) + DO I = 1, LEN(OutData%PotFile) + OutData%PotFile(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + OutData%nWAMITObj = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%vecMultiplier = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NBody = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NBodyMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmVol0 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmVol0)) DEALLOCATE(OutData%PtfmVol0) + ALLOCATE(OutData%PtfmVol0(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmVol0.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmVol0,1), UBOUND(OutData%PtfmVol0,1) + OutData%PtfmVol0(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + OutData%HasWAMIT = TRANSFER(IntKiBuf(Int_Xferred), OutData%HasWAMIT) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAMITULEN not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WAMITULEN)) DEALLOCATE(OutData%WAMITULEN) + ALLOCATE(OutData%WAMITULEN(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WAMITULEN.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WAMITULEN,1), UBOUND(OutData%WAMITULEN,1) + OutData%WAMITULEN(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmRefxt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmRefxt)) DEALLOCATE(OutData%PtfmRefxt) + ALLOCATE(OutData%PtfmRefxt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmRefxt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmRefxt,1), UBOUND(OutData%PtfmRefxt,1) + OutData%PtfmRefxt(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmRefyt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmRefyt)) DEALLOCATE(OutData%PtfmRefyt) + ALLOCATE(OutData%PtfmRefyt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmRefyt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmRefyt,1), UBOUND(OutData%PtfmRefyt,1) + OutData%PtfmRefyt(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmRefzt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmRefzt)) DEALLOCATE(OutData%PtfmRefzt) + ALLOCATE(OutData%PtfmRefzt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmRefzt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmRefzt,1), UBOUND(OutData%PtfmRefzt,1) + OutData%PtfmRefzt(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmRefztRot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmRefztRot)) DEALLOCATE(OutData%PtfmRefztRot) + ALLOCATE(OutData%PtfmRefztRot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmRefztRot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmRefztRot,1), UBOUND(OutData%PtfmRefztRot,1) + OutData%PtfmRefztRot(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmCOBxt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmCOBxt)) DEALLOCATE(OutData%PtfmCOBxt) + ALLOCATE(OutData%PtfmCOBxt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmCOBxt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmCOBxt,1), UBOUND(OutData%PtfmCOBxt,1) + OutData%PtfmCOBxt(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmCOByt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmCOByt)) DEALLOCATE(OutData%PtfmCOByt) + ALLOCATE(OutData%PtfmCOByt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmCOByt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmCOByt,1), UBOUND(OutData%PtfmCOByt,1) + OutData%PtfmCOByt(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -1307,14 +1981,26 @@ SUBROUTINE HydroDyn_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Xferred = Int_Xferred + 1 OutData%NumOuts = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%OutList,1) - i1_u = UBOUND(OutData%OutList,1) - DO i1 = LBOUND(OutData%OutList,1), UBOUND(OutData%OutList,1) - DO I = 1, LEN(OutData%OutList) - OutData%OutList(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OutList not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%OutList)) DEALLOCATE(OutData%OutList) + ALLOCATE(OutData%OutList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%OutList,1), UBOUND(OutData%OutList,1) + DO I = 1, LEN(OutData%OutList) + OutData%OutList(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF OutData%HDSum = TRANSFER(IntKiBuf(Int_Xferred), OutData%HDSum) Int_Xferred = Int_Xferred + 1 OutData%UnSum = IntKiBuf(Int_Xferred) @@ -1330,7 +2016,7 @@ SUBROUTINE HydroDyn_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta END SUBROUTINE HydroDyn_UnPackInitInput SUBROUTINE HydroDyn_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(HydroDyn_InitOutputType), INTENT(INOUT) :: SrcInitOutputData + TYPE(HydroDyn_InitOutputType), INTENT(IN) :: SrcInitOutputData TYPE(HydroDyn_InitOutputType), INTENT(INOUT) :: DstInitOutputData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat @@ -1345,12 +2031,38 @@ SUBROUTINE HydroDyn_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCo ! ErrStat = ErrID_None ErrMsg = "" - CALL WAMIT_CopyInitOutput( SrcInitOutputData%WAMIT, DstInitOutputData%WAMIT, CtrlCode, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(SrcInitOutputData%WAMIT)) THEN + i1_l = LBOUND(SrcInitOutputData%WAMIT,1) + i1_u = UBOUND(SrcInitOutputData%WAMIT,1) + IF (.NOT. ALLOCATED(DstInitOutputData%WAMIT)) THEN + ALLOCATE(DstInitOutputData%WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcInitOutputData%WAMIT,1), UBOUND(SrcInitOutputData%WAMIT,1) + CALL WAMIT_CopyInitOutput( SrcInitOutputData%WAMIT(i1), DstInitOutputData%WAMIT(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL WAMIT2_CopyInitOutput( SrcInitOutputData%WAMIT2, DstInitOutputData%WAMIT2, CtrlCode, ErrStat2, ErrMsg2 ) + ENDDO +ENDIF +IF (ALLOCATED(SrcInitOutputData%WAMIT2)) THEN + i1_l = LBOUND(SrcInitOutputData%WAMIT2,1) + i1_u = UBOUND(SrcInitOutputData%WAMIT2,1) + IF (.NOT. ALLOCATED(DstInitOutputData%WAMIT2)) THEN + ALLOCATE(DstInitOutputData%WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcInitOutputData%WAMIT2,1), UBOUND(SrcInitOutputData%WAMIT2,1) + CALL WAMIT2_CopyInitOutput( SrcInitOutputData%WAMIT2(i1), DstInitOutputData%WAMIT2(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF CALL Waves2_CopyInitOutput( SrcInitOutputData%Waves2, DstInitOutputData%Waves2, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -1472,8 +2184,18 @@ SUBROUTINE HydroDyn_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" - CALL WAMIT_DestroyInitOutput( InitOutputData%WAMIT, ErrStat, ErrMsg ) - CALL WAMIT2_DestroyInitOutput( InitOutputData%WAMIT2, ErrStat, ErrMsg ) +IF (ALLOCATED(InitOutputData%WAMIT)) THEN +DO i1 = LBOUND(InitOutputData%WAMIT,1), UBOUND(InitOutputData%WAMIT,1) + CALL WAMIT_DestroyInitOutput( InitOutputData%WAMIT(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(InitOutputData%WAMIT) +ENDIF +IF (ALLOCATED(InitOutputData%WAMIT2)) THEN +DO i1 = LBOUND(InitOutputData%WAMIT2,1), UBOUND(InitOutputData%WAMIT2,1) + CALL WAMIT2_DestroyInitOutput( InitOutputData%WAMIT2(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(InitOutputData%WAMIT2) +ENDIF CALL Waves2_DestroyInitOutput( InitOutputData%Waves2, ErrStat, ErrMsg ) CALL Morison_DestroyInitOutput( InitOutputData%Morison, ErrStat, ErrMsg ) IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN @@ -1538,9 +2260,13 @@ SUBROUTINE HydroDyn_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! WAMIT allocated yes/no + IF ( ALLOCATED(InData%WAMIT) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WAMIT upper/lower bounds for each dimension ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%WAMIT,1), UBOUND(InData%WAMIT,1) Int_BufSz = Int_BufSz + 3 ! WAMIT: size of buffers for each call to pack subtype - CALL WAMIT_PackInitOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT + CALL WAMIT_PackInitOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT(i1), ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1556,8 +2282,14 @@ SUBROUTINE HydroDyn_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! WAMIT2 allocated yes/no + IF ( ALLOCATED(InData%WAMIT2) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WAMIT2 upper/lower bounds for each dimension + DO i1 = LBOUND(InData%WAMIT2,1), UBOUND(InData%WAMIT2,1) Int_BufSz = Int_BufSz + 3 ! WAMIT2: size of buffers for each call to pack subtype - CALL WAMIT2_PackInitOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2, ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT2 + CALL WAMIT2_PackInitOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2(i1), ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1573,6 +2305,8 @@ SUBROUTINE HydroDyn_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF Int_BufSz = Int_BufSz + 3 ! Waves2: size of buffers for each call to pack subtype CALL Waves2_PackInitOutput( Re_Buf, Db_Buf, Int_Buf, InData%Waves2, ErrStat2, ErrMsg2, .TRUE. ) ! Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -1694,7 +2428,18 @@ SUBROUTINE HydroDyn_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = 1 Int_Xferred = 1 - CALL WAMIT_PackInitOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, OnlySize ) ! WAMIT + IF ( .NOT. ALLOCATED(InData%WAMIT) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAMIT,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAMIT,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WAMIT,1), UBOUND(InData%WAMIT,1) + CALL WAMIT_PackInitOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT(i1), ErrStat2, ErrMsg2, OnlySize ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1722,7 +2467,20 @@ SUBROUTINE HydroDyn_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WAMIT2_PackInitOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2, ErrStat2, ErrMsg2, OnlySize ) ! WAMIT2 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WAMIT2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAMIT2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAMIT2,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WAMIT2,1), UBOUND(InData%WAMIT2,1) + CALL WAMIT2_PackInitOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2(i1), ErrStat2, ErrMsg2, OnlySize ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1750,6 +2508,8 @@ SUBROUTINE HydroDyn_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + END DO + END IF CALL Waves2_PackInitOutput( Re_Buf, Db_Buf, Int_Buf, InData%Waves2, ErrStat2, ErrMsg2, OnlySize ) ! Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2005,6 +2765,20 @@ SUBROUTINE HydroDyn_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAMIT not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WAMIT)) DEALLOCATE(OutData%WAMIT) + ALLOCATE(OutData%WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WAMIT,1), UBOUND(OutData%WAMIT,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -2038,13 +2812,29 @@ SUBROUTINE HydroDyn_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT_UnpackInitOutput( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT, ErrStat2, ErrMsg2 ) ! WAMIT + CALL WAMIT_UnpackInitOutput( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT(i1), ErrStat2, ErrMsg2 ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAMIT2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WAMIT2)) DEALLOCATE(OutData%WAMIT2) + ALLOCATE(OutData%WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WAMIT2,1), UBOUND(OutData%WAMIT2,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -2078,13 +2868,15 @@ SUBROUTINE HydroDyn_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT2_UnpackInitOutput( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT2, ErrStat2, ErrMsg2 ) ! WAMIT2 + CALL WAMIT2_UnpackInitOutput( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT2(i1), ErrStat2, ErrMsg2 ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -2386,13 +3178,13 @@ SUBROUTINE HydroDyn_CopyHD_ModuleMapType( SrcHD_ModuleMapTypeData, DstHD_ModuleM ! ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Copymeshmaptype( SrcHD_ModuleMapTypeData%HD_P_2_WRP_P, DstHD_ModuleMapTypeData%HD_P_2_WRP_P, CtrlCode, ErrStat2, ErrMsg2 ) + CALL NWTC_Library_Copymeshmaptype( SrcHD_ModuleMapTypeData%uW_P_2_PRP_P, DstHD_ModuleMapTypeData%uW_P_2_PRP_P, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL NWTC_Library_Copymeshmaptype( SrcHD_ModuleMapTypeData%M_P_2_WRP_P, DstHD_ModuleMapTypeData%M_P_2_WRP_P, CtrlCode, ErrStat2, ErrMsg2 ) + CALL NWTC_Library_Copymeshmaptype( SrcHD_ModuleMapTypeData%W_P_2_PRP_P, DstHD_ModuleMapTypeData%W_P_2_PRP_P, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL NWTC_Library_Copymeshmaptype( SrcHD_ModuleMapTypeData%M_L_2_WRP_P, DstHD_ModuleMapTypeData%M_L_2_WRP_P, CtrlCode, ErrStat2, ErrMsg2 ) + CALL NWTC_Library_Copymeshmaptype( SrcHD_ModuleMapTypeData%M_P_2_PRP_P, DstHD_ModuleMapTypeData%M_P_2_PRP_P, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE HydroDyn_CopyHD_ModuleMapType @@ -2406,9 +3198,9 @@ SUBROUTINE HydroDyn_DestroyHD_ModuleMapType( HD_ModuleMapTypeData, ErrStat, ErrM ! ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Destroymeshmaptype( HD_ModuleMapTypeData%HD_P_2_WRP_P, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( HD_ModuleMapTypeData%M_P_2_WRP_P, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( HD_ModuleMapTypeData%M_L_2_WRP_P, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( HD_ModuleMapTypeData%uW_P_2_PRP_P, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( HD_ModuleMapTypeData%W_P_2_PRP_P, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( HD_ModuleMapTypeData%M_P_2_PRP_P, ErrStat, ErrMsg ) END SUBROUTINE HydroDyn_DestroyHD_ModuleMapType SUBROUTINE HydroDyn_PackHD_ModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2447,54 +3239,54 @@ SUBROUTINE HydroDyn_PackHD_ModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er Db_BufSz = 0 Int_BufSz = 0 ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! HD_P_2_WRP_P: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%HD_P_2_WRP_P, ErrStat2, ErrMsg2, .TRUE. ) ! HD_P_2_WRP_P + Int_BufSz = Int_BufSz + 3 ! uW_P_2_PRP_P: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%uW_P_2_PRP_P, ErrStat2, ErrMsg2, .TRUE. ) ! uW_P_2_PRP_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! HD_P_2_WRP_P + IF(ALLOCATED(Re_Buf)) THEN ! uW_P_2_PRP_P Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! HD_P_2_WRP_P + IF(ALLOCATED(Db_Buf)) THEN ! uW_P_2_PRP_P Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! HD_P_2_WRP_P + IF(ALLOCATED(Int_Buf)) THEN ! uW_P_2_PRP_P Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! M_P_2_WRP_P: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%M_P_2_WRP_P, ErrStat2, ErrMsg2, .TRUE. ) ! M_P_2_WRP_P + Int_BufSz = Int_BufSz + 3 ! W_P_2_PRP_P: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%W_P_2_PRP_P, ErrStat2, ErrMsg2, .TRUE. ) ! W_P_2_PRP_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! M_P_2_WRP_P + IF(ALLOCATED(Re_Buf)) THEN ! W_P_2_PRP_P Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! M_P_2_WRP_P + IF(ALLOCATED(Db_Buf)) THEN ! W_P_2_PRP_P Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! M_P_2_WRP_P + IF(ALLOCATED(Int_Buf)) THEN ! W_P_2_PRP_P Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! M_L_2_WRP_P: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%M_L_2_WRP_P, ErrStat2, ErrMsg2, .TRUE. ) ! M_L_2_WRP_P + Int_BufSz = Int_BufSz + 3 ! M_P_2_PRP_P: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%M_P_2_PRP_P, ErrStat2, ErrMsg2, .TRUE. ) ! M_P_2_PRP_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! M_L_2_WRP_P + IF(ALLOCATED(Re_Buf)) THEN ! M_P_2_PRP_P Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! M_L_2_WRP_P + IF(ALLOCATED(Db_Buf)) THEN ! M_P_2_PRP_P Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! M_L_2_WRP_P + IF(ALLOCATED(Int_Buf)) THEN ! M_P_2_PRP_P Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -2525,7 +3317,7 @@ SUBROUTINE HydroDyn_PackHD_ModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er Db_Xferred = 1 Int_Xferred = 1 - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%HD_P_2_WRP_P, ErrStat2, ErrMsg2, OnlySize ) ! HD_P_2_WRP_P + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%uW_P_2_PRP_P, ErrStat2, ErrMsg2, OnlySize ) ! uW_P_2_PRP_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2553,7 +3345,7 @@ SUBROUTINE HydroDyn_PackHD_ModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%M_P_2_WRP_P, ErrStat2, ErrMsg2, OnlySize ) ! M_P_2_WRP_P + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%W_P_2_PRP_P, ErrStat2, ErrMsg2, OnlySize ) ! W_P_2_PRP_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2581,7 +3373,7 @@ SUBROUTINE HydroDyn_PackHD_ModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%M_L_2_WRP_P, ErrStat2, ErrMsg2, OnlySize ) ! M_L_2_WRP_P + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%M_P_2_PRP_P, ErrStat2, ErrMsg2, OnlySize ) ! M_P_2_PRP_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2670,7 +3462,7 @@ SUBROUTINE HydroDyn_UnPackHD_ModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%HD_P_2_WRP_P, ErrStat2, ErrMsg2 ) ! HD_P_2_WRP_P + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%uW_P_2_PRP_P, ErrStat2, ErrMsg2 ) ! uW_P_2_PRP_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2710,7 +3502,7 @@ SUBROUTINE HydroDyn_UnPackHD_ModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%M_P_2_WRP_P, ErrStat2, ErrMsg2 ) ! M_P_2_WRP_P + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%W_P_2_PRP_P, ErrStat2, ErrMsg2 ) ! W_P_2_PRP_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2750,7 +3542,7 @@ SUBROUTINE HydroDyn_UnPackHD_ModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%M_L_2_WRP_P, ErrStat2, ErrMsg2 ) ! M_L_2_WRP_P + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%M_P_2_PRP_P, ErrStat2, ErrMsg2 ) ! M_P_2_PRP_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2767,18 +3559,45 @@ SUBROUTINE HydroDyn_CopyContState( SrcContStateData, DstContStateData, CtrlCode, CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_CopyContState' ! ErrStat = ErrID_None ErrMsg = "" - CALL WAMIT_CopyContState( SrcContStateData%WAMIT, DstContStateData%WAMIT, CtrlCode, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(SrcContStateData%WAMIT)) THEN + i1_l = LBOUND(SrcContStateData%WAMIT,1) + i1_u = UBOUND(SrcContStateData%WAMIT,1) + IF (.NOT. ALLOCATED(DstContStateData%WAMIT)) THEN + ALLOCATE(DstContStateData%WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstContStateData%WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcContStateData%WAMIT,1), UBOUND(SrcContStateData%WAMIT,1) + CALL WAMIT_CopyContState( SrcContStateData%WAMIT(i1), DstContStateData%WAMIT(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL WAMIT2_CopyContState( SrcContStateData%WAMIT2, DstContStateData%WAMIT2, CtrlCode, ErrStat2, ErrMsg2 ) + ENDDO +ENDIF +IF (ALLOCATED(SrcContStateData%WAMIT2)) THEN + i1_l = LBOUND(SrcContStateData%WAMIT2,1) + i1_u = UBOUND(SrcContStateData%WAMIT2,1) + IF (.NOT. ALLOCATED(DstContStateData%WAMIT2)) THEN + ALLOCATE(DstContStateData%WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstContStateData%WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcContStateData%WAMIT2,1), UBOUND(SrcContStateData%WAMIT2,1) + CALL WAMIT2_CopyContState( SrcContStateData%WAMIT2(i1), DstContStateData%WAMIT2(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF CALL Waves2_CopyContState( SrcContStateData%Waves2, DstContStateData%Waves2, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -2796,8 +3615,18 @@ SUBROUTINE HydroDyn_DestroyContState( ContStateData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" - CALL WAMIT_DestroyContState( ContStateData%WAMIT, ErrStat, ErrMsg ) - CALL WAMIT2_DestroyContState( ContStateData%WAMIT2, ErrStat, ErrMsg ) +IF (ALLOCATED(ContStateData%WAMIT)) THEN +DO i1 = LBOUND(ContStateData%WAMIT,1), UBOUND(ContStateData%WAMIT,1) + CALL WAMIT_DestroyContState( ContStateData%WAMIT(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(ContStateData%WAMIT) +ENDIF +IF (ALLOCATED(ContStateData%WAMIT2)) THEN +DO i1 = LBOUND(ContStateData%WAMIT2,1), UBOUND(ContStateData%WAMIT2,1) + CALL WAMIT2_DestroyContState( ContStateData%WAMIT2(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(ContStateData%WAMIT2) +ENDIF CALL Waves2_DestroyContState( ContStateData%Waves2, ErrStat, ErrMsg ) CALL Morison_DestroyContState( ContStateData%Morison, ErrStat, ErrMsg ) END SUBROUTINE HydroDyn_DestroyContState @@ -2837,9 +3666,13 @@ SUBROUTINE HydroDyn_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! WAMIT allocated yes/no + IF ( ALLOCATED(InData%WAMIT) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WAMIT upper/lower bounds for each dimension ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%WAMIT,1), UBOUND(InData%WAMIT,1) Int_BufSz = Int_BufSz + 3 ! WAMIT: size of buffers for each call to pack subtype - CALL WAMIT_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT + CALL WAMIT_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT(i1), ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2855,8 +3688,14 @@ SUBROUTINE HydroDyn_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! WAMIT2 allocated yes/no + IF ( ALLOCATED(InData%WAMIT2) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WAMIT2 upper/lower bounds for each dimension + DO i1 = LBOUND(InData%WAMIT2,1), UBOUND(InData%WAMIT2,1) Int_BufSz = Int_BufSz + 3 ! WAMIT2: size of buffers for each call to pack subtype - CALL WAMIT2_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2, ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT2 + CALL WAMIT2_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2(i1), ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2872,6 +3711,8 @@ SUBROUTINE HydroDyn_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF Int_BufSz = Int_BufSz + 3 ! Waves2: size of buffers for each call to pack subtype CALL Waves2_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%Waves2, ErrStat2, ErrMsg2, .TRUE. ) ! Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -2933,7 +3774,18 @@ SUBROUTINE HydroDyn_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = 1 Int_Xferred = 1 - CALL WAMIT_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, OnlySize ) ! WAMIT + IF ( .NOT. ALLOCATED(InData%WAMIT) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAMIT,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAMIT,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WAMIT,1), UBOUND(InData%WAMIT,1) + CALL WAMIT_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT(i1), ErrStat2, ErrMsg2, OnlySize ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2961,7 +3813,20 @@ SUBROUTINE HydroDyn_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WAMIT2_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2, ErrStat2, ErrMsg2, OnlySize ) ! WAMIT2 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WAMIT2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAMIT2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAMIT2,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WAMIT2,1), UBOUND(InData%WAMIT2,1) + CALL WAMIT2_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2(i1), ErrStat2, ErrMsg2, OnlySize ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2989,6 +3854,8 @@ SUBROUTINE HydroDyn_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + END DO + END IF CALL Waves2_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%Waves2, ErrStat2, ErrMsg2, OnlySize ) ! Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3060,6 +3927,7 @@ SUBROUTINE HydroDyn_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta INTEGER(IntKi) :: Db_Xferred INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_UnPackContState' @@ -3073,6 +3941,20 @@ SUBROUTINE HydroDyn_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAMIT not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WAMIT)) DEALLOCATE(OutData%WAMIT) + ALLOCATE(OutData%WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WAMIT,1), UBOUND(OutData%WAMIT,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -3106,13 +3988,29 @@ SUBROUTINE HydroDyn_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT, ErrStat2, ErrMsg2 ) ! WAMIT + CALL WAMIT_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT(i1), ErrStat2, ErrMsg2 ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAMIT2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WAMIT2)) DEALLOCATE(OutData%WAMIT2) + ALLOCATE(OutData%WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WAMIT2,1), UBOUND(OutData%WAMIT2,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -3146,13 +4044,15 @@ SUBROUTINE HydroDyn_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT2_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT2, ErrStat2, ErrMsg2 ) ! WAMIT2 + CALL WAMIT2_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT2(i1), ErrStat2, ErrMsg2 ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -3243,18 +4143,45 @@ SUBROUTINE HydroDyn_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_CopyDiscState' ! ErrStat = ErrID_None ErrMsg = "" - CALL WAMIT_CopyDiscState( SrcDiscStateData%WAMIT, DstDiscStateData%WAMIT, CtrlCode, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(SrcDiscStateData%WAMIT)) THEN + i1_l = LBOUND(SrcDiscStateData%WAMIT,1) + i1_u = UBOUND(SrcDiscStateData%WAMIT,1) + IF (.NOT. ALLOCATED(DstDiscStateData%WAMIT)) THEN + ALLOCATE(DstDiscStateData%WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDiscStateData%WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcDiscStateData%WAMIT,1), UBOUND(SrcDiscStateData%WAMIT,1) + CALL WAMIT_CopyDiscState( SrcDiscStateData%WAMIT(i1), DstDiscStateData%WAMIT(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL WAMIT2_CopyDiscState( SrcDiscStateData%WAMIT2, DstDiscStateData%WAMIT2, CtrlCode, ErrStat2, ErrMsg2 ) + ENDDO +ENDIF +IF (ALLOCATED(SrcDiscStateData%WAMIT2)) THEN + i1_l = LBOUND(SrcDiscStateData%WAMIT2,1) + i1_u = UBOUND(SrcDiscStateData%WAMIT2,1) + IF (.NOT. ALLOCATED(DstDiscStateData%WAMIT2)) THEN + ALLOCATE(DstDiscStateData%WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDiscStateData%WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcDiscStateData%WAMIT2,1), UBOUND(SrcDiscStateData%WAMIT2,1) + CALL WAMIT2_CopyDiscState( SrcDiscStateData%WAMIT2(i1), DstDiscStateData%WAMIT2(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF CALL Waves2_CopyDiscState( SrcDiscStateData%Waves2, DstDiscStateData%Waves2, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -3272,8 +4199,18 @@ SUBROUTINE HydroDyn_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" - CALL WAMIT_DestroyDiscState( DiscStateData%WAMIT, ErrStat, ErrMsg ) - CALL WAMIT2_DestroyDiscState( DiscStateData%WAMIT2, ErrStat, ErrMsg ) +IF (ALLOCATED(DiscStateData%WAMIT)) THEN +DO i1 = LBOUND(DiscStateData%WAMIT,1), UBOUND(DiscStateData%WAMIT,1) + CALL WAMIT_DestroyDiscState( DiscStateData%WAMIT(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(DiscStateData%WAMIT) +ENDIF +IF (ALLOCATED(DiscStateData%WAMIT2)) THEN +DO i1 = LBOUND(DiscStateData%WAMIT2,1), UBOUND(DiscStateData%WAMIT2,1) + CALL WAMIT2_DestroyDiscState( DiscStateData%WAMIT2(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(DiscStateData%WAMIT2) +ENDIF CALL Waves2_DestroyDiscState( DiscStateData%Waves2, ErrStat, ErrMsg ) CALL Morison_DestroyDiscState( DiscStateData%Morison, ErrStat, ErrMsg ) END SUBROUTINE HydroDyn_DestroyDiscState @@ -3313,9 +4250,13 @@ SUBROUTINE HydroDyn_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! WAMIT allocated yes/no + IF ( ALLOCATED(InData%WAMIT) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WAMIT upper/lower bounds for each dimension ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%WAMIT,1), UBOUND(InData%WAMIT,1) Int_BufSz = Int_BufSz + 3 ! WAMIT: size of buffers for each call to pack subtype - CALL WAMIT_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT + CALL WAMIT_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT(i1), ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3331,8 +4272,14 @@ SUBROUTINE HydroDyn_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! WAMIT2 allocated yes/no + IF ( ALLOCATED(InData%WAMIT2) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WAMIT2 upper/lower bounds for each dimension + DO i1 = LBOUND(InData%WAMIT2,1), UBOUND(InData%WAMIT2,1) Int_BufSz = Int_BufSz + 3 ! WAMIT2: size of buffers for each call to pack subtype - CALL WAMIT2_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2, ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT2 + CALL WAMIT2_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2(i1), ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3348,6 +4295,8 @@ SUBROUTINE HydroDyn_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF Int_BufSz = Int_BufSz + 3 ! Waves2: size of buffers for each call to pack subtype CALL Waves2_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%Waves2, ErrStat2, ErrMsg2, .TRUE. ) ! Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -3409,7 +4358,18 @@ SUBROUTINE HydroDyn_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = 1 Int_Xferred = 1 - CALL WAMIT_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, OnlySize ) ! WAMIT + IF ( .NOT. ALLOCATED(InData%WAMIT) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAMIT,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAMIT,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WAMIT,1), UBOUND(InData%WAMIT,1) + CALL WAMIT_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT(i1), ErrStat2, ErrMsg2, OnlySize ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3437,7 +4397,20 @@ SUBROUTINE HydroDyn_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WAMIT2_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2, ErrStat2, ErrMsg2, OnlySize ) ! WAMIT2 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WAMIT2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAMIT2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAMIT2,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WAMIT2,1), UBOUND(InData%WAMIT2,1) + CALL WAMIT2_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2(i1), ErrStat2, ErrMsg2, OnlySize ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3465,6 +4438,8 @@ SUBROUTINE HydroDyn_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + END DO + END IF CALL Waves2_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%Waves2, ErrStat2, ErrMsg2, OnlySize ) ! Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3536,6 +4511,7 @@ SUBROUTINE HydroDyn_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta INTEGER(IntKi) :: Db_Xferred INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_UnPackDiscState' @@ -3549,6 +4525,20 @@ SUBROUTINE HydroDyn_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAMIT not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WAMIT)) DEALLOCATE(OutData%WAMIT) + ALLOCATE(OutData%WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WAMIT,1), UBOUND(OutData%WAMIT,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -3582,13 +4572,29 @@ SUBROUTINE HydroDyn_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT, ErrStat2, ErrMsg2 ) ! WAMIT + CALL WAMIT_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT(i1), ErrStat2, ErrMsg2 ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAMIT2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WAMIT2)) DEALLOCATE(OutData%WAMIT2) + ALLOCATE(OutData%WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WAMIT2,1), UBOUND(OutData%WAMIT2,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -3622,13 +4628,15 @@ SUBROUTINE HydroDyn_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT2_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT2, ErrStat2, ErrMsg2 ) ! WAMIT2 + CALL WAMIT2_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT2(i1), ErrStat2, ErrMsg2 ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -4195,18 +5203,45 @@ SUBROUTINE HydroDyn_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCo CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_CopyOtherState' ! ErrStat = ErrID_None ErrMsg = "" - CALL WAMIT_CopyOtherState( SrcOtherStateData%WAMIT, DstOtherStateData%WAMIT, CtrlCode, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(SrcOtherStateData%WAMIT)) THEN + i1_l = LBOUND(SrcOtherStateData%WAMIT,1) + i1_u = UBOUND(SrcOtherStateData%WAMIT,1) + IF (.NOT. ALLOCATED(DstOtherStateData%WAMIT)) THEN + ALLOCATE(DstOtherStateData%WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOtherStateData%WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcOtherStateData%WAMIT,1), UBOUND(SrcOtherStateData%WAMIT,1) + CALL WAMIT_CopyOtherState( SrcOtherStateData%WAMIT(i1), DstOtherStateData%WAMIT(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL WAMIT2_CopyOtherState( SrcOtherStateData%WAMIT2, DstOtherStateData%WAMIT2, CtrlCode, ErrStat2, ErrMsg2 ) + ENDDO +ENDIF +IF (ALLOCATED(SrcOtherStateData%WAMIT2)) THEN + i1_l = LBOUND(SrcOtherStateData%WAMIT2,1) + i1_u = UBOUND(SrcOtherStateData%WAMIT2,1) + IF (.NOT. ALLOCATED(DstOtherStateData%WAMIT2)) THEN + ALLOCATE(DstOtherStateData%WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOtherStateData%WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcOtherStateData%WAMIT2,1), UBOUND(SrcOtherStateData%WAMIT2,1) + CALL WAMIT2_CopyOtherState( SrcOtherStateData%WAMIT2(i1), DstOtherStateData%WAMIT2(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF CALL Waves2_CopyOtherState( SrcOtherStateData%Waves2, DstOtherStateData%Waves2, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -4224,8 +5259,18 @@ SUBROUTINE HydroDyn_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" - CALL WAMIT_DestroyOtherState( OtherStateData%WAMIT, ErrStat, ErrMsg ) - CALL WAMIT2_DestroyOtherState( OtherStateData%WAMIT2, ErrStat, ErrMsg ) +IF (ALLOCATED(OtherStateData%WAMIT)) THEN +DO i1 = LBOUND(OtherStateData%WAMIT,1), UBOUND(OtherStateData%WAMIT,1) + CALL WAMIT_DestroyOtherState( OtherStateData%WAMIT(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(OtherStateData%WAMIT) +ENDIF +IF (ALLOCATED(OtherStateData%WAMIT2)) THEN +DO i1 = LBOUND(OtherStateData%WAMIT2,1), UBOUND(OtherStateData%WAMIT2,1) + CALL WAMIT2_DestroyOtherState( OtherStateData%WAMIT2(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(OtherStateData%WAMIT2) +ENDIF CALL Waves2_DestroyOtherState( OtherStateData%Waves2, ErrStat, ErrMsg ) CALL Morison_DestroyOtherState( OtherStateData%Morison, ErrStat, ErrMsg ) END SUBROUTINE HydroDyn_DestroyOtherState @@ -4265,9 +5310,13 @@ SUBROUTINE HydroDyn_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! WAMIT allocated yes/no + IF ( ALLOCATED(InData%WAMIT) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WAMIT upper/lower bounds for each dimension ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%WAMIT,1), UBOUND(InData%WAMIT,1) Int_BufSz = Int_BufSz + 3 ! WAMIT: size of buffers for each call to pack subtype - CALL WAMIT_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT + CALL WAMIT_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT(i1), ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4283,8 +5332,14 @@ SUBROUTINE HydroDyn_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! WAMIT2 allocated yes/no + IF ( ALLOCATED(InData%WAMIT2) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WAMIT2 upper/lower bounds for each dimension + DO i1 = LBOUND(InData%WAMIT2,1), UBOUND(InData%WAMIT2,1) Int_BufSz = Int_BufSz + 3 ! WAMIT2: size of buffers for each call to pack subtype - CALL WAMIT2_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2, ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT2 + CALL WAMIT2_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2(i1), ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4300,6 +5355,8 @@ SUBROUTINE HydroDyn_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF Int_BufSz = Int_BufSz + 3 ! Waves2: size of buffers for each call to pack subtype CALL Waves2_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%Waves2, ErrStat2, ErrMsg2, .TRUE. ) ! Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -4361,7 +5418,18 @@ SUBROUTINE HydroDyn_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = 1 Int_Xferred = 1 - CALL WAMIT_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, OnlySize ) ! WAMIT + IF ( .NOT. ALLOCATED(InData%WAMIT) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAMIT,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAMIT,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WAMIT,1), UBOUND(InData%WAMIT,1) + CALL WAMIT_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT(i1), ErrStat2, ErrMsg2, OnlySize ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4389,7 +5457,20 @@ SUBROUTINE HydroDyn_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WAMIT2_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2, ErrStat2, ErrMsg2, OnlySize ) ! WAMIT2 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WAMIT2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAMIT2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAMIT2,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WAMIT2,1), UBOUND(InData%WAMIT2,1) + CALL WAMIT2_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2(i1), ErrStat2, ErrMsg2, OnlySize ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4417,6 +5498,8 @@ SUBROUTINE HydroDyn_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + END DO + END IF CALL Waves2_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%Waves2, ErrStat2, ErrMsg2, OnlySize ) ! Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4488,6 +5571,7 @@ SUBROUTINE HydroDyn_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt INTEGER(IntKi) :: Db_Xferred INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_UnPackOtherState' @@ -4501,6 +5585,20 @@ SUBROUTINE HydroDyn_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAMIT not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WAMIT)) DEALLOCATE(OutData%WAMIT) + ALLOCATE(OutData%WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WAMIT,1), UBOUND(OutData%WAMIT,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -4534,13 +5632,29 @@ SUBROUTINE HydroDyn_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT, ErrStat2, ErrMsg2 ) ! WAMIT + CALL WAMIT_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT(i1), ErrStat2, ErrMsg2 ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAMIT2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WAMIT2)) DEALLOCATE(OutData%WAMIT2) + ALLOCATE(OutData%WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WAMIT2,1), UBOUND(OutData%WAMIT2,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -4574,13 +5688,15 @@ SUBROUTINE HydroDyn_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT2_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT2, ErrStat2, ErrMsg2 ) ! WAMIT2 + CALL WAMIT2_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT2(i1), ErrStat2, ErrMsg2 ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -4678,16 +5794,10 @@ SUBROUTINE HydroDyn_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMs ! ErrStat = ErrID_None ErrMsg = "" - CALL MeshCopy( SrcMiscData%y_mapped, DstMiscData%y_mapped, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL MeshCopy( SrcMiscData%AllHdroOrigin_position, DstMiscData%AllHdroOrigin_position, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL MeshCopy( SrcMiscData%MrsnLumpedMesh_position, DstMiscData%MrsnLumpedMesh_position, CtrlCode, ErrStat2, ErrMsg2 ) + CALL MeshCopy( SrcMiscData%AllHdroOrigin, DstMiscData%AllHdroOrigin, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL MeshCopy( SrcMiscData%MrsnDistribMesh_position, DstMiscData%MrsnDistribMesh_position, CtrlCode, ErrStat2, ErrMsg2 ) + CALL MeshCopy( SrcMiscData%MrsnMesh_position, DstMiscData%MrsnMesh_position, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN CALL HydroDyn_Copyhd_modulemaptype( SrcMiscData%HD_MeshMap, DstMiscData%HD_MeshMap, CtrlCode, ErrStat2, ErrMsg2 ) @@ -4696,27 +5806,101 @@ SUBROUTINE HydroDyn_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMs DstMiscData%Decimate = SrcMiscData%Decimate DstMiscData%LastOutTime = SrcMiscData%LastOutTime DstMiscData%LastIndWave = SrcMiscData%LastIndWave +IF (ALLOCATED(SrcMiscData%F_PtfmAdd)) THEN + i1_l = LBOUND(SrcMiscData%F_PtfmAdd,1) + i1_u = UBOUND(SrcMiscData%F_PtfmAdd,1) + IF (.NOT. ALLOCATED(DstMiscData%F_PtfmAdd)) THEN + ALLOCATE(DstMiscData%F_PtfmAdd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%F_PtfmAdd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstMiscData%F_PtfmAdd = SrcMiscData%F_PtfmAdd +ENDIF DstMiscData%F_Hydro = SrcMiscData%F_Hydro +IF (ALLOCATED(SrcMiscData%F_Waves)) THEN + i1_l = LBOUND(SrcMiscData%F_Waves,1) + i1_u = UBOUND(SrcMiscData%F_Waves,1) + IF (.NOT. ALLOCATED(DstMiscData%F_Waves)) THEN + ALLOCATE(DstMiscData%F_Waves(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%F_Waves.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstMiscData%F_Waves = SrcMiscData%F_Waves - CALL WAMIT_CopyMisc( SrcMiscData%WAMIT, DstMiscData%WAMIT, CtrlCode, ErrStat2, ErrMsg2 ) +ENDIF +IF (ALLOCATED(SrcMiscData%WAMIT)) THEN + i1_l = LBOUND(SrcMiscData%WAMIT,1) + i1_u = UBOUND(SrcMiscData%WAMIT,1) + IF (.NOT. ALLOCATED(DstMiscData%WAMIT)) THEN + ALLOCATE(DstMiscData%WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMiscData%WAMIT,1), UBOUND(SrcMiscData%WAMIT,1) + CALL WAMIT_CopyMisc( SrcMiscData%WAMIT(i1), DstMiscData%WAMIT(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL WAMIT2_CopyMisc( SrcMiscData%WAMIT2, DstMiscData%WAMIT2, CtrlCode, ErrStat2, ErrMsg2 ) + ENDDO +ENDIF +IF (ALLOCATED(SrcMiscData%WAMIT2)) THEN + i1_l = LBOUND(SrcMiscData%WAMIT2,1) + i1_u = UBOUND(SrcMiscData%WAMIT2,1) + IF (.NOT. ALLOCATED(DstMiscData%WAMIT2)) THEN + ALLOCATE(DstMiscData%WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMiscData%WAMIT2,1), UBOUND(SrcMiscData%WAMIT2,1) + CALL WAMIT2_CopyMisc( SrcMiscData%WAMIT2(i1), DstMiscData%WAMIT2(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF CALL Waves2_CopyMisc( SrcMiscData%Waves2, DstMiscData%Waves2, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN CALL Morison_CopyMisc( SrcMiscData%Morison, DstMiscData%Morison, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL WAMIT_CopyInput( SrcMiscData%u_WAMIT, DstMiscData%u_WAMIT, CtrlCode, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(SrcMiscData%u_WAMIT)) THEN + i1_l = LBOUND(SrcMiscData%u_WAMIT,1) + i1_u = UBOUND(SrcMiscData%u_WAMIT,1) + IF (.NOT. ALLOCATED(DstMiscData%u_WAMIT)) THEN + ALLOCATE(DstMiscData%u_WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%u_WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMiscData%u_WAMIT,1), UBOUND(SrcMiscData%u_WAMIT,1) + CALL WAMIT_CopyInput( SrcMiscData%u_WAMIT(i1), DstMiscData%u_WAMIT(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL WAMIT2_CopyInput( SrcMiscData%u_WAMIT2, DstMiscData%u_WAMIT2, CtrlCode, ErrStat2, ErrMsg2 ) + ENDDO +ENDIF +IF (ALLOCATED(SrcMiscData%u_WAMIT2)) THEN + i1_l = LBOUND(SrcMiscData%u_WAMIT2,1) + i1_u = UBOUND(SrcMiscData%u_WAMIT2,1) + IF (.NOT. ALLOCATED(DstMiscData%u_WAMIT2)) THEN + ALLOCATE(DstMiscData%u_WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%u_WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMiscData%u_WAMIT2,1), UBOUND(SrcMiscData%u_WAMIT2,1) + CALL WAMIT2_CopyInput( SrcMiscData%u_WAMIT2(i1), DstMiscData%u_WAMIT2(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF CALL Waves2_CopyInput( SrcMiscData%u_Waves2, DstMiscData%u_Waves2, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -4731,17 +5915,41 @@ SUBROUTINE HydroDyn_DestroyMisc( MiscData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( MiscData%y_mapped, ErrStat, ErrMsg ) - CALL MeshDestroy( MiscData%AllHdroOrigin_position, ErrStat, ErrMsg ) - CALL MeshDestroy( MiscData%MrsnLumpedMesh_position, ErrStat, ErrMsg ) - CALL MeshDestroy( MiscData%MrsnDistribMesh_position, ErrStat, ErrMsg ) + CALL MeshDestroy( MiscData%AllHdroOrigin, ErrStat, ErrMsg ) + CALL MeshDestroy( MiscData%MrsnMesh_position, ErrStat, ErrMsg ) CALL HydroDyn_Destroyhd_modulemaptype( MiscData%HD_MeshMap, ErrStat, ErrMsg ) - CALL WAMIT_DestroyMisc( MiscData%WAMIT, ErrStat, ErrMsg ) - CALL WAMIT2_DestroyMisc( MiscData%WAMIT2, ErrStat, ErrMsg ) +IF (ALLOCATED(MiscData%F_PtfmAdd)) THEN + DEALLOCATE(MiscData%F_PtfmAdd) +ENDIF +IF (ALLOCATED(MiscData%F_Waves)) THEN + DEALLOCATE(MiscData%F_Waves) +ENDIF +IF (ALLOCATED(MiscData%WAMIT)) THEN +DO i1 = LBOUND(MiscData%WAMIT,1), UBOUND(MiscData%WAMIT,1) + CALL WAMIT_DestroyMisc( MiscData%WAMIT(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(MiscData%WAMIT) +ENDIF +IF (ALLOCATED(MiscData%WAMIT2)) THEN +DO i1 = LBOUND(MiscData%WAMIT2,1), UBOUND(MiscData%WAMIT2,1) + CALL WAMIT2_DestroyMisc( MiscData%WAMIT2(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(MiscData%WAMIT2) +ENDIF CALL Waves2_DestroyMisc( MiscData%Waves2, ErrStat, ErrMsg ) CALL Morison_DestroyMisc( MiscData%Morison, ErrStat, ErrMsg ) - CALL WAMIT_DestroyInput( MiscData%u_WAMIT, ErrStat, ErrMsg ) - CALL WAMIT2_DestroyInput( MiscData%u_WAMIT2, ErrStat, ErrMsg ) +IF (ALLOCATED(MiscData%u_WAMIT)) THEN +DO i1 = LBOUND(MiscData%u_WAMIT,1), UBOUND(MiscData%u_WAMIT,1) + CALL WAMIT_DestroyInput( MiscData%u_WAMIT(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(MiscData%u_WAMIT) +ENDIF +IF (ALLOCATED(MiscData%u_WAMIT2)) THEN +DO i1 = LBOUND(MiscData%u_WAMIT2,1), UBOUND(MiscData%u_WAMIT2,1) + CALL WAMIT2_DestroyInput( MiscData%u_WAMIT2(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(MiscData%u_WAMIT2) +ENDIF CALL Waves2_DestroyInput( MiscData%u_Waves2, ErrStat, ErrMsg ) END SUBROUTINE HydroDyn_DestroyMisc @@ -4781,71 +5989,37 @@ SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_BufSz = 0 Int_BufSz = 0 ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! y_mapped: size of buffers for each call to pack subtype - CALL MeshPack( InData%y_mapped, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! y_mapped - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! y_mapped - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! y_mapped - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! y_mapped - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! AllHdroOrigin_position: size of buffers for each call to pack subtype - CALL MeshPack( InData%AllHdroOrigin_position, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! AllHdroOrigin_position - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! AllHdroOrigin_position - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! AllHdroOrigin_position - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! AllHdroOrigin_position - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! MrsnLumpedMesh_position: size of buffers for each call to pack subtype - CALL MeshPack( InData%MrsnLumpedMesh_position, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! MrsnLumpedMesh_position + Int_BufSz = Int_BufSz + 3 ! AllHdroOrigin: size of buffers for each call to pack subtype + CALL MeshPack( InData%AllHdroOrigin, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! AllHdroOrigin CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! MrsnLumpedMesh_position + IF(ALLOCATED(Re_Buf)) THEN ! AllHdroOrigin Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! MrsnLumpedMesh_position + IF(ALLOCATED(Db_Buf)) THEN ! AllHdroOrigin Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! MrsnLumpedMesh_position + IF(ALLOCATED(Int_Buf)) THEN ! AllHdroOrigin Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! MrsnDistribMesh_position: size of buffers for each call to pack subtype - CALL MeshPack( InData%MrsnDistribMesh_position, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! MrsnDistribMesh_position + Int_BufSz = Int_BufSz + 3 ! MrsnMesh_position: size of buffers for each call to pack subtype + CALL MeshPack( InData%MrsnMesh_position, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! MrsnMesh_position CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! MrsnDistribMesh_position + IF(ALLOCATED(Re_Buf)) THEN ! MrsnMesh_position Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! MrsnDistribMesh_position + IF(ALLOCATED(Db_Buf)) THEN ! MrsnMesh_position Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! MrsnDistribMesh_position + IF(ALLOCATED(Int_Buf)) THEN ! MrsnMesh_position Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -4869,11 +6043,23 @@ SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + 1 ! Decimate Db_BufSz = Db_BufSz + 1 ! LastOutTime Int_BufSz = Int_BufSz + 1 ! LastIndWave + Int_BufSz = Int_BufSz + 1 ! F_PtfmAdd allocated yes/no + IF ( ALLOCATED(InData%F_PtfmAdd) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! F_PtfmAdd upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%F_PtfmAdd) ! F_PtfmAdd + END IF Re_BufSz = Re_BufSz + SIZE(InData%F_Hydro) ! F_Hydro + Int_BufSz = Int_BufSz + 1 ! F_Waves allocated yes/no + IF ( ALLOCATED(InData%F_Waves) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! F_Waves upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%F_Waves) ! F_Waves + END IF + Int_BufSz = Int_BufSz + 1 ! WAMIT allocated yes/no + IF ( ALLOCATED(InData%WAMIT) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WAMIT upper/lower bounds for each dimension + DO i1 = LBOUND(InData%WAMIT,1), UBOUND(InData%WAMIT,1) Int_BufSz = Int_BufSz + 3 ! WAMIT: size of buffers for each call to pack subtype - CALL WAMIT_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT + CALL WAMIT_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT(i1), ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4889,8 +6075,14 @@ SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! WAMIT2 allocated yes/no + IF ( ALLOCATED(InData%WAMIT2) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WAMIT2 upper/lower bounds for each dimension + DO i1 = LBOUND(InData%WAMIT2,1), UBOUND(InData%WAMIT2,1) Int_BufSz = Int_BufSz + 3 ! WAMIT2: size of buffers for each call to pack subtype - CALL WAMIT2_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2, ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT2 + CALL WAMIT2_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2(i1), ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4906,6 +6098,8 @@ SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF Int_BufSz = Int_BufSz + 3 ! Waves2: size of buffers for each call to pack subtype CALL Waves2_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%Waves2, ErrStat2, ErrMsg2, .TRUE. ) ! Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -4940,8 +6134,12 @@ SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 1 ! u_WAMIT allocated yes/no + IF ( ALLOCATED(InData%u_WAMIT) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! u_WAMIT upper/lower bounds for each dimension + DO i1 = LBOUND(InData%u_WAMIT,1), UBOUND(InData%u_WAMIT,1) Int_BufSz = Int_BufSz + 3 ! u_WAMIT: size of buffers for each call to pack subtype - CALL WAMIT_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_WAMIT, ErrStat2, ErrMsg2, .TRUE. ) ! u_WAMIT + CALL WAMIT_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_WAMIT(i1), ErrStat2, ErrMsg2, .TRUE. ) ! u_WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4957,8 +6155,14 @@ SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! u_WAMIT2 allocated yes/no + IF ( ALLOCATED(InData%u_WAMIT2) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! u_WAMIT2 upper/lower bounds for each dimension + DO i1 = LBOUND(InData%u_WAMIT2,1), UBOUND(InData%u_WAMIT2,1) Int_BufSz = Int_BufSz + 3 ! u_WAMIT2: size of buffers for each call to pack subtype - CALL WAMIT2_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_WAMIT2, ErrStat2, ErrMsg2, .TRUE. ) ! u_WAMIT2 + CALL WAMIT2_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_WAMIT2(i1), ErrStat2, ErrMsg2, .TRUE. ) ! u_WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4974,6 +6178,8 @@ SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF Int_BufSz = Int_BufSz + 3 ! u_Waves2: size of buffers for each call to pack subtype CALL Waves2_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_Waves2, ErrStat2, ErrMsg2, .TRUE. ) ! u_Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -5005,76 +6211,20 @@ SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs RETURN END IF END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL MeshPack( InData%y_mapped, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! y_mapped - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL MeshPack( InData%AllHdroOrigin_position, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! AllHdroOrigin_position - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL MeshPack( InData%MrsnLumpedMesh_position, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! MrsnLumpedMesh_position + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + CALL MeshPack( InData%AllHdroOrigin, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! AllHdroOrigin CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5102,7 +6252,7 @@ SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL MeshPack( InData%MrsnDistribMesh_position, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! MrsnDistribMesh_position + CALL MeshPack( InData%MrsnMesh_position, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! MrsnMesh_position CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5164,19 +6314,52 @@ SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_Xferred = Db_Xferred + 1 IntKiBuf(Int_Xferred) = InData%LastIndWave Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%F_PtfmAdd,1), UBOUND(InData%F_PtfmAdd,1) - ReKiBuf(Re_Xferred) = InData%F_PtfmAdd(i1) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( .NOT. ALLOCATED(InData%F_PtfmAdd) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_PtfmAdd,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_PtfmAdd,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%F_PtfmAdd,1), UBOUND(InData%F_PtfmAdd,1) + ReKiBuf(Re_Xferred) = InData%F_PtfmAdd(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF DO i1 = LBOUND(InData%F_Hydro,1), UBOUND(InData%F_Hydro,1) ReKiBuf(Re_Xferred) = InData%F_Hydro(i1) Re_Xferred = Re_Xferred + 1 END DO - DO i1 = LBOUND(InData%F_Waves,1), UBOUND(InData%F_Waves,1) - ReKiBuf(Re_Xferred) = InData%F_Waves(i1) - Re_Xferred = Re_Xferred + 1 - END DO - CALL WAMIT_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, OnlySize ) ! WAMIT + IF ( .NOT. ALLOCATED(InData%F_Waves) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_Waves,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_Waves,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%F_Waves,1), UBOUND(InData%F_Waves,1) + ReKiBuf(Re_Xferred) = InData%F_Waves(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WAMIT) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAMIT,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAMIT,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WAMIT,1), UBOUND(InData%WAMIT,1) + CALL WAMIT_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT(i1), ErrStat2, ErrMsg2, OnlySize ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5204,7 +6387,20 @@ SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WAMIT2_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2, ErrStat2, ErrMsg2, OnlySize ) ! WAMIT2 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WAMIT2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAMIT2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAMIT2,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WAMIT2,1), UBOUND(InData%WAMIT2,1) + CALL WAMIT2_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2(i1), ErrStat2, ErrMsg2, OnlySize ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5232,6 +6428,8 @@ SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + END DO + END IF CALL Waves2_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%Waves2, ErrStat2, ErrMsg2, OnlySize ) ! Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5288,7 +6486,18 @@ SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WAMIT_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_WAMIT, ErrStat2, ErrMsg2, OnlySize ) ! u_WAMIT + IF ( .NOT. ALLOCATED(InData%u_WAMIT) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%u_WAMIT,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%u_WAMIT,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%u_WAMIT,1), UBOUND(InData%u_WAMIT,1) + CALL WAMIT_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_WAMIT(i1), ErrStat2, ErrMsg2, OnlySize ) ! u_WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5316,7 +6525,20 @@ SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WAMIT2_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_WAMIT2, ErrStat2, ErrMsg2, OnlySize ) ! u_WAMIT2 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%u_WAMIT2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%u_WAMIT2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%u_WAMIT2,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%u_WAMIT2,1), UBOUND(InData%u_WAMIT2,1) + CALL WAMIT2_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_WAMIT2(i1), ErrStat2, ErrMsg2, OnlySize ) ! u_WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5344,6 +6566,8 @@ SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + END DO + END IF CALL Waves2_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_Waves2, ErrStat2, ErrMsg2, OnlySize ) ! u_Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5434,87 +6658,7 @@ SUBROUTINE HydroDyn_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL MeshUnpack( OutData%y_mapped, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! y_mapped - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL MeshUnpack( OutData%AllHdroOrigin_position, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! AllHdroOrigin_position - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL MeshUnpack( OutData%MrsnLumpedMesh_position, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! MrsnLumpedMesh_position + CALL MeshUnpack( OutData%AllHdroOrigin, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! AllHdroOrigin CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5554,7 +6698,7 @@ SUBROUTINE HydroDyn_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL MeshUnpack( OutData%MrsnDistribMesh_position, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! MrsnDistribMesh_position + CALL MeshUnpack( OutData%MrsnMesh_position, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! MrsnMesh_position CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5607,24 +6751,62 @@ SUBROUTINE HydroDyn_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Db_Xferred = Db_Xferred + 1 OutData%LastIndWave = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%F_PtfmAdd,1) - i1_u = UBOUND(OutData%F_PtfmAdd,1) - DO i1 = LBOUND(OutData%F_PtfmAdd,1), UBOUND(OutData%F_PtfmAdd,1) - OutData%F_PtfmAdd(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_PtfmAdd not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_PtfmAdd)) DEALLOCATE(OutData%F_PtfmAdd) + ALLOCATE(OutData%F_PtfmAdd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_PtfmAdd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%F_PtfmAdd,1), UBOUND(OutData%F_PtfmAdd,1) + OutData%F_PtfmAdd(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF i1_l = LBOUND(OutData%F_Hydro,1) i1_u = UBOUND(OutData%F_Hydro,1) DO i1 = LBOUND(OutData%F_Hydro,1), UBOUND(OutData%F_Hydro,1) OutData%F_Hydro(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO - i1_l = LBOUND(OutData%F_Waves,1) - i1_u = UBOUND(OutData%F_Waves,1) - DO i1 = LBOUND(OutData%F_Waves,1), UBOUND(OutData%F_Waves,1) - OutData%F_Waves(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_Waves not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_Waves)) DEALLOCATE(OutData%F_Waves) + ALLOCATE(OutData%F_Waves(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_Waves.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%F_Waves,1), UBOUND(OutData%F_Waves,1) + OutData%F_Waves(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAMIT not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WAMIT)) DEALLOCATE(OutData%WAMIT) + ALLOCATE(OutData%WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WAMIT,1), UBOUND(OutData%WAMIT,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -5658,13 +6840,29 @@ SUBROUTINE HydroDyn_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT, ErrStat2, ErrMsg2 ) ! WAMIT + CALL WAMIT_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT(i1), ErrStat2, ErrMsg2 ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAMIT2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WAMIT2)) DEALLOCATE(OutData%WAMIT2) + ALLOCATE(OutData%WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WAMIT2,1), UBOUND(OutData%WAMIT2,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -5698,13 +6896,15 @@ SUBROUTINE HydroDyn_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT2_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT2, ErrStat2, ErrMsg2 ) ! WAMIT2 + CALL WAMIT2_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT2(i1), ErrStat2, ErrMsg2 ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -5785,6 +6985,20 @@ SUBROUTINE HydroDyn_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! u_WAMIT not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%u_WAMIT)) DEALLOCATE(OutData%u_WAMIT) + ALLOCATE(OutData%u_WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%u_WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%u_WAMIT,1), UBOUND(OutData%u_WAMIT,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -5818,13 +7032,29 @@ SUBROUTINE HydroDyn_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u_WAMIT, ErrStat2, ErrMsg2 ) ! u_WAMIT + CALL WAMIT_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u_WAMIT(i1), ErrStat2, ErrMsg2 ) ! u_WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! u_WAMIT2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%u_WAMIT2)) DEALLOCATE(OutData%u_WAMIT2) + ALLOCATE(OutData%u_WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%u_WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%u_WAMIT2,1), UBOUND(OutData%u_WAMIT2,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -5858,13 +7088,15 @@ SUBROUTINE HydroDyn_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT2_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u_WAMIT2, ErrStat2, ErrMsg2 ) ! u_WAMIT2 + CALL WAMIT2_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u_WAMIT2(i1), ErrStat2, ErrMsg2 ) ! u_WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -5917,18 +7149,48 @@ SUBROUTINE HydroDyn_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, Er INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_CopyParam' ! ErrStat = ErrID_None ErrMsg = "" - CALL WAMIT_CopyParam( SrcParamData%WAMIT, DstParamData%WAMIT, CtrlCode, ErrStat2, ErrMsg2 ) + DstParamData%nWAMITObj = SrcParamData%nWAMITObj + DstParamData%vecMultiplier = SrcParamData%vecMultiplier +IF (ALLOCATED(SrcParamData%WAMIT)) THEN + i1_l = LBOUND(SrcParamData%WAMIT,1) + i1_u = UBOUND(SrcParamData%WAMIT,1) + IF (.NOT. ALLOCATED(DstParamData%WAMIT)) THEN + ALLOCATE(DstParamData%WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcParamData%WAMIT,1), UBOUND(SrcParamData%WAMIT,1) + CALL WAMIT_CopyParam( SrcParamData%WAMIT(i1), DstParamData%WAMIT(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL WAMIT2_CopyParam( SrcParamData%WAMIT2, DstParamData%WAMIT2, CtrlCode, ErrStat2, ErrMsg2 ) + ENDDO +ENDIF +IF (ALLOCATED(SrcParamData%WAMIT2)) THEN + i1_l = LBOUND(SrcParamData%WAMIT2,1) + i1_u = UBOUND(SrcParamData%WAMIT2,1) + IF (.NOT. ALLOCATED(DstParamData%WAMIT2)) THEN + ALLOCATE(DstParamData%WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcParamData%WAMIT2,1), UBOUND(SrcParamData%WAMIT2,1) + CALL WAMIT2_CopyParam( SrcParamData%WAMIT2(i1), DstParamData%WAMIT2(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + DstParamData%WAMIT2used = SrcParamData%WAMIT2used CALL Waves2_CopyParam( SrcParamData%Waves2, DstParamData%Waves2, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -5936,6 +7198,11 @@ SUBROUTINE HydroDyn_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, Er CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN DstParamData%PotMod = SrcParamData%PotMod + DstParamData%NBody = SrcParamData%NBody + DstParamData%NBodyMod = SrcParamData%NBodyMod + DstParamData%totalStates = SrcParamData%totalStates + DstParamData%totalExctnStates = SrcParamData%totalExctnStates + DstParamData%totalRdtnStates = SrcParamData%totalRdtnStates IF (ALLOCATED(SrcParamData%WaveTime)) THEN i1_l = LBOUND(SrcParamData%WaveTime,1) i1_u = UBOUND(SrcParamData%WaveTime,1) @@ -5977,12 +7244,84 @@ SUBROUTINE HydroDyn_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, Er END IF END IF DstParamData%WaveElev1 = SrcParamData%WaveElev1 +ENDIF +IF (ALLOCATED(SrcParamData%WaveElev2)) THEN + i1_l = LBOUND(SrcParamData%WaveElev2,1) + i1_u = UBOUND(SrcParamData%WaveElev2,1) + i2_l = LBOUND(SrcParamData%WaveElev2,2) + i2_u = UBOUND(SrcParamData%WaveElev2,2) + IF (.NOT. ALLOCATED(DstParamData%WaveElev2)) THEN + ALLOCATE(DstParamData%WaveElev2(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%WaveElev2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%WaveElev2 = SrcParamData%WaveElev2 ENDIF DstParamData%WtrDpth = SrcParamData%WtrDpth +IF (ALLOCATED(SrcParamData%AddF0)) THEN + i1_l = LBOUND(SrcParamData%AddF0,1) + i1_u = UBOUND(SrcParamData%AddF0,1) + i2_l = LBOUND(SrcParamData%AddF0,2) + i2_u = UBOUND(SrcParamData%AddF0,2) + IF (.NOT. ALLOCATED(DstParamData%AddF0)) THEN + ALLOCATE(DstParamData%AddF0(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%AddF0.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstParamData%AddF0 = SrcParamData%AddF0 +ENDIF +IF (ALLOCATED(SrcParamData%AddCLin)) THEN + i1_l = LBOUND(SrcParamData%AddCLin,1) + i1_u = UBOUND(SrcParamData%AddCLin,1) + i2_l = LBOUND(SrcParamData%AddCLin,2) + i2_u = UBOUND(SrcParamData%AddCLin,2) + i3_l = LBOUND(SrcParamData%AddCLin,3) + i3_u = UBOUND(SrcParamData%AddCLin,3) + IF (.NOT. ALLOCATED(DstParamData%AddCLin)) THEN + ALLOCATE(DstParamData%AddCLin(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%AddCLin.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstParamData%AddCLin = SrcParamData%AddCLin +ENDIF +IF (ALLOCATED(SrcParamData%AddBLin)) THEN + i1_l = LBOUND(SrcParamData%AddBLin,1) + i1_u = UBOUND(SrcParamData%AddBLin,1) + i2_l = LBOUND(SrcParamData%AddBLin,2) + i2_u = UBOUND(SrcParamData%AddBLin,2) + i3_l = LBOUND(SrcParamData%AddBLin,3) + i3_u = UBOUND(SrcParamData%AddBLin,3) + IF (.NOT. ALLOCATED(DstParamData%AddBLin)) THEN + ALLOCATE(DstParamData%AddBLin(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%AddBLin.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstParamData%AddBLin = SrcParamData%AddBLin +ENDIF +IF (ALLOCATED(SrcParamData%AddBQuad)) THEN + i1_l = LBOUND(SrcParamData%AddBQuad,1) + i1_u = UBOUND(SrcParamData%AddBQuad,1) + i2_l = LBOUND(SrcParamData%AddBQuad,2) + i2_u = UBOUND(SrcParamData%AddBQuad,2) + i3_l = LBOUND(SrcParamData%AddBQuad,3) + i3_u = UBOUND(SrcParamData%AddBQuad,3) + IF (.NOT. ALLOCATED(DstParamData%AddBQuad)) THEN + ALLOCATE(DstParamData%AddBQuad(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%AddBQuad.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstParamData%AddBQuad = SrcParamData%AddBQuad +ENDIF DstParamData%DT = SrcParamData%DT IF (ALLOCATED(SrcParamData%OutParam)) THEN i1_l = LBOUND(SrcParamData%OutParam,1) @@ -6058,8 +7397,18 @@ SUBROUTINE HydroDyn_DestroyParam( ParamData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" - CALL WAMIT_DestroyParam( ParamData%WAMIT, ErrStat, ErrMsg ) - CALL WAMIT2_DestroyParam( ParamData%WAMIT2, ErrStat, ErrMsg ) +IF (ALLOCATED(ParamData%WAMIT)) THEN +DO i1 = LBOUND(ParamData%WAMIT,1), UBOUND(ParamData%WAMIT,1) + CALL WAMIT_DestroyParam( ParamData%WAMIT(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(ParamData%WAMIT) +ENDIF +IF (ALLOCATED(ParamData%WAMIT2)) THEN +DO i1 = LBOUND(ParamData%WAMIT2,1), UBOUND(ParamData%WAMIT2,1) + CALL WAMIT2_DestroyParam( ParamData%WAMIT2(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(ParamData%WAMIT2) +ENDIF CALL Waves2_DestroyParam( ParamData%Waves2, ErrStat, ErrMsg ) CALL Morison_DestroyParam( ParamData%Morison, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%WaveTime)) THEN @@ -6071,6 +7420,21 @@ SUBROUTINE HydroDyn_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%WaveElev1)) THEN DEALLOCATE(ParamData%WaveElev1) ENDIF +IF (ALLOCATED(ParamData%WaveElev2)) THEN + DEALLOCATE(ParamData%WaveElev2) +ENDIF +IF (ALLOCATED(ParamData%AddF0)) THEN + DEALLOCATE(ParamData%AddF0) +ENDIF +IF (ALLOCATED(ParamData%AddCLin)) THEN + DEALLOCATE(ParamData%AddCLin) +ENDIF +IF (ALLOCATED(ParamData%AddBLin)) THEN + DEALLOCATE(ParamData%AddBLin) +ENDIF +IF (ALLOCATED(ParamData%AddBQuad)) THEN + DEALLOCATE(ParamData%AddBQuad) +ENDIF IF (ALLOCATED(ParamData%OutParam)) THEN DO i1 = LBOUND(ParamData%OutParam,1), UBOUND(ParamData%OutParam,1) CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat, ErrMsg ) @@ -6123,9 +7487,15 @@ SUBROUTINE HydroDyn_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! nWAMITObj + Int_BufSz = Int_BufSz + 1 ! vecMultiplier + Int_BufSz = Int_BufSz + 1 ! WAMIT allocated yes/no + IF ( ALLOCATED(InData%WAMIT) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WAMIT upper/lower bounds for each dimension ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%WAMIT,1), UBOUND(InData%WAMIT,1) Int_BufSz = Int_BufSz + 3 ! WAMIT: size of buffers for each call to pack subtype - CALL WAMIT_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT + CALL WAMIT_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT(i1), ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6141,8 +7511,14 @@ SUBROUTINE HydroDyn_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! WAMIT2 allocated yes/no + IF ( ALLOCATED(InData%WAMIT2) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WAMIT2 upper/lower bounds for each dimension + DO i1 = LBOUND(InData%WAMIT2,1), UBOUND(InData%WAMIT2,1) Int_BufSz = Int_BufSz + 3 ! WAMIT2: size of buffers for each call to pack subtype - CALL WAMIT2_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2, ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT2 + CALL WAMIT2_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2(i1), ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6158,6 +7534,9 @@ SUBROUTINE HydroDyn_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! WAMIT2used Int_BufSz = Int_BufSz + 3 ! Waves2: size of buffers for each call to pack subtype CALL Waves2_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%Waves2, ErrStat2, ErrMsg2, .TRUE. ) ! Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -6193,6 +7572,11 @@ SUBROUTINE HydroDyn_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 1 ! PotMod + Int_BufSz = Int_BufSz + 1 ! NBody + Int_BufSz = Int_BufSz + 1 ! NBodyMod + Int_BufSz = Int_BufSz + 1 ! totalStates + Int_BufSz = Int_BufSz + 1 ! totalExctnStates + Int_BufSz = Int_BufSz + 1 ! totalRdtnStates Int_BufSz = Int_BufSz + 1 ! WaveTime allocated yes/no IF ( ALLOCATED(InData%WaveTime) ) THEN Int_BufSz = Int_BufSz + 2*1 ! WaveTime upper/lower bounds for each dimension @@ -6209,12 +7593,33 @@ SUBROUTINE HydroDyn_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM IF ( ALLOCATED(InData%WaveElev1) ) THEN Int_BufSz = Int_BufSz + 2*2 ! WaveElev1 upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WaveElev1) ! WaveElev1 + END IF + Int_BufSz = Int_BufSz + 1 ! WaveElev2 allocated yes/no + IF ( ALLOCATED(InData%WaveElev2) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! WaveElev2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WaveElev2) ! WaveElev2 END IF Re_BufSz = Re_BufSz + 1 ! WtrDpth + Int_BufSz = Int_BufSz + 1 ! AddF0 allocated yes/no + IF ( ALLOCATED(InData%AddF0) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! AddF0 upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%AddF0) ! AddF0 + END IF + Int_BufSz = Int_BufSz + 1 ! AddCLin allocated yes/no + IF ( ALLOCATED(InData%AddCLin) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! AddCLin upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%AddCLin) ! AddCLin + END IF + Int_BufSz = Int_BufSz + 1 ! AddBLin allocated yes/no + IF ( ALLOCATED(InData%AddBLin) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! AddBLin upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%AddBLin) ! AddBLin + END IF + Int_BufSz = Int_BufSz + 1 ! AddBQuad allocated yes/no + IF ( ALLOCATED(InData%AddBQuad) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! AddBQuad upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%AddBQuad) ! AddBQuad + END IF Db_BufSz = Db_BufSz + 1 ! DT Int_BufSz = Int_BufSz + 1 ! OutParam allocated yes/no IF ( ALLOCATED(InData%OutParam) ) THEN @@ -6290,7 +7695,22 @@ SUBROUTINE HydroDyn_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Db_Xferred = 1 Int_Xferred = 1 - CALL WAMIT_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, OnlySize ) ! WAMIT + IntKiBuf(Int_Xferred) = InData%nWAMITObj + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%vecMultiplier + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%WAMIT) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAMIT,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAMIT,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WAMIT,1), UBOUND(InData%WAMIT,1) + CALL WAMIT_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT(i1), ErrStat2, ErrMsg2, OnlySize ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6318,7 +7738,20 @@ SUBROUTINE HydroDyn_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WAMIT2_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2, ErrStat2, ErrMsg2, OnlySize ) ! WAMIT2 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WAMIT2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAMIT2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAMIT2,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WAMIT2,1), UBOUND(InData%WAMIT2,1) + CALL WAMIT2_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2(i1), ErrStat2, ErrMsg2, OnlySize ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6346,6 +7779,10 @@ SUBROUTINE HydroDyn_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + END DO + END IF + IntKiBuf(Int_Xferred) = TRANSFER(InData%WAMIT2used, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 CALL Waves2_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%Waves2, ErrStat2, ErrMsg2, OnlySize ) ! Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6404,6 +7841,16 @@ SUBROUTINE HydroDyn_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ENDIF IntKiBuf(Int_Xferred) = InData%PotMod Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NBody + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NBodyMod + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%totalStates + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%totalExctnStates + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%totalRdtnStates + Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%WaveTime) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -6462,31 +7909,124 @@ SUBROUTINE HydroDyn_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Re_Xferred = Re_Xferred + 1 END DO END DO + END IF + IF ( .NOT. ALLOCATED(InData%WaveElev2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveElev2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveElev2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveElev2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveElev2,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%WaveElev2,2), UBOUND(InData%WaveElev2,2) + DO i1 = LBOUND(InData%WaveElev2,1), UBOUND(InData%WaveElev2,1) + ReKiBuf(Re_Xferred) = InData%WaveElev2(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF ReKiBuf(Re_Xferred) = InData%WtrDpth Re_Xferred = Re_Xferred + 1 - DO i1 = LBOUND(InData%AddF0,1), UBOUND(InData%AddF0,1) - ReKiBuf(Re_Xferred) = InData%AddF0(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i2 = LBOUND(InData%AddCLin,2), UBOUND(InData%AddCLin,2) - DO i1 = LBOUND(InData%AddCLin,1), UBOUND(InData%AddCLin,1) - ReKiBuf(Re_Xferred) = InData%AddCLin(i1,i2) - Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%AddF0) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddF0,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddF0,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddF0,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddF0,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%AddF0,2), UBOUND(InData%AddF0,2) + DO i1 = LBOUND(InData%AddF0,1), UBOUND(InData%AddF0,1) + ReKiBuf(Re_Xferred) = InData%AddF0(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO END DO - END DO - DO i2 = LBOUND(InData%AddBLin,2), UBOUND(InData%AddBLin,2) - DO i1 = LBOUND(InData%AddBLin,1), UBOUND(InData%AddBLin,1) - ReKiBuf(Re_Xferred) = InData%AddBLin(i1,i2) - Re_Xferred = Re_Xferred + 1 + END IF + IF ( .NOT. ALLOCATED(InData%AddCLin) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddCLin,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddCLin,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddCLin,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddCLin,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddCLin,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddCLin,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%AddCLin,3), UBOUND(InData%AddCLin,3) + DO i2 = LBOUND(InData%AddCLin,2), UBOUND(InData%AddCLin,2) + DO i1 = LBOUND(InData%AddCLin,1), UBOUND(InData%AddCLin,1) + ReKiBuf(Re_Xferred) = InData%AddCLin(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END DO - END DO - DO i2 = LBOUND(InData%AddBQuad,2), UBOUND(InData%AddBQuad,2) - DO i1 = LBOUND(InData%AddBQuad,1), UBOUND(InData%AddBQuad,1) - ReKiBuf(Re_Xferred) = InData%AddBQuad(i1,i2) - Re_Xferred = Re_Xferred + 1 + END IF + IF ( .NOT. ALLOCATED(InData%AddBLin) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddBLin,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddBLin,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddBLin,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddBLin,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddBLin,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddBLin,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%AddBLin,3), UBOUND(InData%AddBLin,3) + DO i2 = LBOUND(InData%AddBLin,2), UBOUND(InData%AddBLin,2) + DO i1 = LBOUND(InData%AddBLin,1), UBOUND(InData%AddBLin,1) + ReKiBuf(Re_Xferred) = InData%AddBLin(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END DO - END DO + END IF + IF ( .NOT. ALLOCATED(InData%AddBQuad) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddBQuad,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddBQuad,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddBQuad,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddBQuad,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AddBQuad,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AddBQuad,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%AddBQuad,3), UBOUND(InData%AddBQuad,3) + DO i2 = LBOUND(InData%AddBQuad,2), UBOUND(InData%AddBQuad,2) + DO i1 = LBOUND(InData%AddBQuad,1), UBOUND(InData%AddBQuad,1) + ReKiBuf(Re_Xferred) = InData%AddBQuad(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF DbKiBuf(Db_Xferred) = InData%DT Db_Xferred = Db_Xferred + 1 IF ( .NOT. ALLOCATED(InData%OutParam) ) THEN @@ -6621,6 +8161,7 @@ SUBROUTINE HydroDyn_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_UnPackParam' @@ -6634,6 +8175,24 @@ SUBROUTINE HydroDyn_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 + OutData%nWAMITObj = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%vecMultiplier = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAMIT not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WAMIT)) DEALLOCATE(OutData%WAMIT) + ALLOCATE(OutData%WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WAMIT,1), UBOUND(OutData%WAMIT,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -6667,13 +8226,29 @@ SUBROUTINE HydroDyn_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT, ErrStat2, ErrMsg2 ) ! WAMIT + CALL WAMIT_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT(i1), ErrStat2, ErrMsg2 ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAMIT2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WAMIT2)) DEALLOCATE(OutData%WAMIT2) + ALLOCATE(OutData%WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WAMIT2,1), UBOUND(OutData%WAMIT2,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -6707,13 +8282,17 @@ SUBROUTINE HydroDyn_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT2_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT2, ErrStat2, ErrMsg2 ) ! WAMIT2 + CALL WAMIT2_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT2(i1), ErrStat2, ErrMsg2 ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + OutData%WAMIT2used = TRANSFER(IntKiBuf(Int_Xferred), OutData%WAMIT2used) + Int_Xferred = Int_Xferred + 1 Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -6796,6 +8375,16 @@ SUBROUTINE HydroDyn_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) OutData%PotMod = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + OutData%NBody = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NBodyMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%totalStates = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%totalExctnStates = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%totalRdtnStates = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveTime not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -6851,57 +8440,151 @@ SUBROUTINE HydroDyn_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%WaveElev1)) DEALLOCATE(OutData%WaveElev1) - ALLOCATE(OutData%WaveElev1(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%WaveElev1)) DEALLOCATE(OutData%WaveElev1) + ALLOCATE(OutData%WaveElev1(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveElev1.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%WaveElev1,2), UBOUND(OutData%WaveElev1,2) + DO i1 = LBOUND(OutData%WaveElev1,1), UBOUND(OutData%WaveElev1,1) + OutData%WaveElev1(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveElev2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WaveElev2)) DEALLOCATE(OutData%WaveElev2) + ALLOCATE(OutData%WaveElev2(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveElev2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%WaveElev2,2), UBOUND(OutData%WaveElev2,2) + DO i1 = LBOUND(OutData%WaveElev2,1), UBOUND(OutData%WaveElev2,1) + OutData%WaveElev2(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + OutData%WtrDpth = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AddF0 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AddF0)) DEALLOCATE(OutData%AddF0) + ALLOCATE(OutData%AddF0(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AddF0.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%AddF0,2), UBOUND(OutData%AddF0,2) + DO i1 = LBOUND(OutData%AddF0,1), UBOUND(OutData%AddF0,1) + OutData%AddF0(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AddCLin not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AddCLin)) DEALLOCATE(OutData%AddCLin) + ALLOCATE(OutData%AddCLin(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AddCLin.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%AddCLin,3), UBOUND(OutData%AddCLin,3) + DO i2 = LBOUND(OutData%AddCLin,2), UBOUND(OutData%AddCLin,2) + DO i1 = LBOUND(OutData%AddCLin,1), UBOUND(OutData%AddCLin,1) + OutData%AddCLin(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AddBLin not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AddBLin)) DEALLOCATE(OutData%AddBLin) + ALLOCATE(OutData%AddBLin(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AddBLin.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%AddBLin,3), UBOUND(OutData%AddBLin,3) + DO i2 = LBOUND(OutData%AddBLin,2), UBOUND(OutData%AddBLin,2) + DO i1 = LBOUND(OutData%AddBLin,1), UBOUND(OutData%AddBLin,1) + OutData%AddBLin(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AddBQuad not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AddBQuad)) DEALLOCATE(OutData%AddBQuad) + ALLOCATE(OutData%AddBQuad(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveElev1.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AddBQuad.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%WaveElev1,2), UBOUND(OutData%WaveElev1,2) - DO i1 = LBOUND(OutData%WaveElev1,1), UBOUND(OutData%WaveElev1,1) - OutData%WaveElev1(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(OutData%AddBQuad,3), UBOUND(OutData%AddBQuad,3) + DO i2 = LBOUND(OutData%AddBQuad,2), UBOUND(OutData%AddBQuad,2) + DO i1 = LBOUND(OutData%AddBQuad,1), UBOUND(OutData%AddBQuad,1) + OutData%AddBQuad(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END IF - OutData%WtrDpth = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - i1_l = LBOUND(OutData%AddF0,1) - i1_u = UBOUND(OutData%AddF0,1) - DO i1 = LBOUND(OutData%AddF0,1), UBOUND(OutData%AddF0,1) - OutData%AddF0(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%AddCLin,1) - i1_u = UBOUND(OutData%AddCLin,1) - i2_l = LBOUND(OutData%AddCLin,2) - i2_u = UBOUND(OutData%AddCLin,2) - DO i2 = LBOUND(OutData%AddCLin,2), UBOUND(OutData%AddCLin,2) - DO i1 = LBOUND(OutData%AddCLin,1), UBOUND(OutData%AddCLin,1) - OutData%AddCLin(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - i1_l = LBOUND(OutData%AddBLin,1) - i1_u = UBOUND(OutData%AddBLin,1) - i2_l = LBOUND(OutData%AddBLin,2) - i2_u = UBOUND(OutData%AddBLin,2) - DO i2 = LBOUND(OutData%AddBLin,2), UBOUND(OutData%AddBLin,2) - DO i1 = LBOUND(OutData%AddBLin,1), UBOUND(OutData%AddBLin,1) - OutData%AddBLin(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - i1_l = LBOUND(OutData%AddBQuad,1) - i1_u = UBOUND(OutData%AddBQuad,1) - i2_l = LBOUND(OutData%AddBQuad,2) - i2_u = UBOUND(OutData%AddBQuad,2) - DO i2 = LBOUND(OutData%AddBQuad,2), UBOUND(OutData%AddBQuad,2) - DO i1 = LBOUND(OutData%AddBQuad,1), UBOUND(OutData%AddBQuad,1) - OutData%AddBQuad(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO OutData%DT = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OutParam not allocated @@ -7062,7 +8745,10 @@ SUBROUTINE HydroDyn_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, Er CALL Morison_CopyInput( SrcInputData%Morison, DstInputData%Morison, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL MeshCopy( SrcInputData%Mesh, DstInputData%Mesh, CtrlCode, ErrStat2, ErrMsg2 ) + CALL MeshCopy( SrcInputData%WAMITMesh, DstInputData%WAMITMesh, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL MeshCopy( SrcInputData%PRPMesh, DstInputData%PRPMesh, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE HydroDyn_CopyInput @@ -7077,7 +8763,8 @@ SUBROUTINE HydroDyn_DestroyInput( InputData, ErrStat, ErrMsg ) ErrStat = ErrID_None ErrMsg = "" CALL Morison_DestroyInput( InputData%Morison, ErrStat, ErrMsg ) - CALL MeshDestroy( InputData%Mesh, ErrStat, ErrMsg ) + CALL MeshDestroy( InputData%WAMITMesh, ErrStat, ErrMsg ) + CALL MeshDestroy( InputData%PRPMesh, ErrStat, ErrMsg ) END SUBROUTINE HydroDyn_DestroyInput SUBROUTINE HydroDyn_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -7133,20 +8820,37 @@ SUBROUTINE HydroDyn_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! Mesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! Mesh + Int_BufSz = Int_BufSz + 3 ! WAMITMesh: size of buffers for each call to pack subtype + CALL MeshPack( InData%WAMITMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! WAMITMesh + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! WAMITMesh + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! WAMITMesh + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! WAMITMesh + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! PRPMesh: size of buffers for each call to pack subtype + CALL MeshPack( InData%PRPMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! PRPMesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Mesh + IF(ALLOCATED(Re_Buf)) THEN ! PRPMesh Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Mesh + IF(ALLOCATED(Db_Buf)) THEN ! PRPMesh Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Mesh + IF(ALLOCATED(Int_Buf)) THEN ! PRPMesh Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -7205,7 +8909,35 @@ SUBROUTINE HydroDyn_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL MeshPack( InData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! Mesh + CALL MeshPack( InData%WAMITMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! WAMITMesh + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL MeshPack( InData%PRPMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! PRPMesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -7334,7 +9066,47 @@ SUBROUTINE HydroDyn_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL MeshUnpack( OutData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! Mesh + CALL MeshUnpack( OutData%WAMITMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! WAMITMesh + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MeshUnpack( OutData%PRPMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! PRPMesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -7358,22 +9130,45 @@ SUBROUTINE HydroDyn_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ! ErrStat = ErrID_None ErrMsg = "" - CALL WAMIT_CopyOutput( SrcOutputData%WAMIT, DstOutputData%WAMIT, CtrlCode, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(SrcOutputData%WAMIT)) THEN + i1_l = LBOUND(SrcOutputData%WAMIT,1) + i1_u = UBOUND(SrcOutputData%WAMIT,1) + IF (.NOT. ALLOCATED(DstOutputData%WAMIT)) THEN + ALLOCATE(DstOutputData%WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcOutputData%WAMIT,1), UBOUND(SrcOutputData%WAMIT,1) + CALL WAMIT_CopyOutput( SrcOutputData%WAMIT(i1), DstOutputData%WAMIT(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL WAMIT2_CopyOutput( SrcOutputData%WAMIT2, DstOutputData%WAMIT2, CtrlCode, ErrStat2, ErrMsg2 ) + ENDDO +ENDIF +IF (ALLOCATED(SrcOutputData%WAMIT2)) THEN + i1_l = LBOUND(SrcOutputData%WAMIT2,1) + i1_u = UBOUND(SrcOutputData%WAMIT2,1) + IF (.NOT. ALLOCATED(DstOutputData%WAMIT2)) THEN + ALLOCATE(DstOutputData%WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcOutputData%WAMIT2,1), UBOUND(SrcOutputData%WAMIT2,1) + CALL WAMIT2_CopyOutput( SrcOutputData%WAMIT2(i1), DstOutputData%WAMIT2(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF CALL Waves2_CopyOutput( SrcOutputData%Waves2, DstOutputData%Waves2, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN CALL Morison_CopyOutput( SrcOutputData%Morison, DstOutputData%Morison, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL MeshCopy( SrcOutputData%Mesh, DstOutputData%Mesh, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL MeshCopy( SrcOutputData%AllHdroOrigin, DstOutputData%AllHdroOrigin, CtrlCode, ErrStat2, ErrMsg2 ) + CALL MeshCopy( SrcOutputData%WAMITMesh, DstOutputData%WAMITMesh, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN IF (ALLOCATED(SrcOutputData%WriteOutput)) THEN @@ -7399,12 +9194,21 @@ SUBROUTINE HydroDyn_DestroyOutput( OutputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" - CALL WAMIT_DestroyOutput( OutputData%WAMIT, ErrStat, ErrMsg ) - CALL WAMIT2_DestroyOutput( OutputData%WAMIT2, ErrStat, ErrMsg ) +IF (ALLOCATED(OutputData%WAMIT)) THEN +DO i1 = LBOUND(OutputData%WAMIT,1), UBOUND(OutputData%WAMIT,1) + CALL WAMIT_DestroyOutput( OutputData%WAMIT(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(OutputData%WAMIT) +ENDIF +IF (ALLOCATED(OutputData%WAMIT2)) THEN +DO i1 = LBOUND(OutputData%WAMIT2,1), UBOUND(OutputData%WAMIT2,1) + CALL WAMIT2_DestroyOutput( OutputData%WAMIT2(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(OutputData%WAMIT2) +ENDIF CALL Waves2_DestroyOutput( OutputData%Waves2, ErrStat, ErrMsg ) CALL Morison_DestroyOutput( OutputData%Morison, ErrStat, ErrMsg ) - CALL MeshDestroy( OutputData%Mesh, ErrStat, ErrMsg ) - CALL MeshDestroy( OutputData%AllHdroOrigin, ErrStat, ErrMsg ) + CALL MeshDestroy( OutputData%WAMITMesh, ErrStat, ErrMsg ) IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF @@ -7445,9 +9249,13 @@ SUBROUTINE HydroDyn_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! WAMIT allocated yes/no + IF ( ALLOCATED(InData%WAMIT) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WAMIT upper/lower bounds for each dimension ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%WAMIT,1), UBOUND(InData%WAMIT,1) Int_BufSz = Int_BufSz + 3 ! WAMIT: size of buffers for each call to pack subtype - CALL WAMIT_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT + CALL WAMIT_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT(i1), ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -7463,8 +9271,14 @@ SUBROUTINE HydroDyn_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! WAMIT2 allocated yes/no + IF ( ALLOCATED(InData%WAMIT2) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WAMIT2 upper/lower bounds for each dimension + DO i1 = LBOUND(InData%WAMIT2,1), UBOUND(InData%WAMIT2,1) Int_BufSz = Int_BufSz + 3 ! WAMIT2: size of buffers for each call to pack subtype - CALL WAMIT2_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2, ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT2 + CALL WAMIT2_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2(i1), ErrStat2, ErrMsg2, .TRUE. ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -7480,6 +9294,8 @@ SUBROUTINE HydroDyn_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF Int_BufSz = Int_BufSz + 3 ! Waves2: size of buffers for each call to pack subtype CALL Waves2_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%Waves2, ErrStat2, ErrMsg2, .TRUE. ) ! Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -7514,37 +9330,20 @@ SUBROUTINE HydroDyn_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! Mesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! Mesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Mesh - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Mesh - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Mesh - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! AllHdroOrigin: size of buffers for each call to pack subtype - CALL MeshPack( InData%AllHdroOrigin, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! AllHdroOrigin + Int_BufSz = Int_BufSz + 3 ! WAMITMesh: size of buffers for each call to pack subtype + CALL MeshPack( InData%WAMITMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! WAMITMesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! AllHdroOrigin + IF(ALLOCATED(Re_Buf)) THEN ! WAMITMesh Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! AllHdroOrigin + IF(ALLOCATED(Db_Buf)) THEN ! WAMITMesh Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! AllHdroOrigin + IF(ALLOCATED(Int_Buf)) THEN ! WAMITMesh Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -7580,7 +9379,18 @@ SUBROUTINE HydroDyn_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Db_Xferred = 1 Int_Xferred = 1 - CALL WAMIT_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT, ErrStat2, ErrMsg2, OnlySize ) ! WAMIT + IF ( .NOT. ALLOCATED(InData%WAMIT) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAMIT,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAMIT,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WAMIT,1), UBOUND(InData%WAMIT,1) + CALL WAMIT_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT(i1), ErrStat2, ErrMsg2, OnlySize ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -7608,7 +9418,20 @@ SUBROUTINE HydroDyn_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WAMIT2_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2, ErrStat2, ErrMsg2, OnlySize ) ! WAMIT2 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WAMIT2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAMIT2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAMIT2,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WAMIT2,1), UBOUND(InData%WAMIT2,1) + CALL WAMIT2_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%WAMIT2(i1), ErrStat2, ErrMsg2, OnlySize ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -7636,6 +9459,8 @@ SUBROUTINE HydroDyn_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + END DO + END IF CALL Waves2_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%Waves2, ErrStat2, ErrMsg2, OnlySize ) ! Waves2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -7692,35 +9517,7 @@ SUBROUTINE HydroDyn_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL MeshPack( InData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! Mesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL MeshPack( InData%AllHdroOrigin, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! AllHdroOrigin + CALL MeshPack( InData%WAMITMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! WAMITMesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -7792,6 +9589,20 @@ SUBROUTINE HydroDyn_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAMIT not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WAMIT)) DEALLOCATE(OutData%WAMIT) + ALLOCATE(OutData%WAMIT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WAMIT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WAMIT,1), UBOUND(OutData%WAMIT,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -7825,13 +9636,29 @@ SUBROUTINE HydroDyn_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT, ErrStat2, ErrMsg2 ) ! WAMIT + CALL WAMIT_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT(i1), ErrStat2, ErrMsg2 ) ! WAMIT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAMIT2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WAMIT2)) DEALLOCATE(OutData%WAMIT2) + ALLOCATE(OutData%WAMIT2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WAMIT2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WAMIT2,1), UBOUND(OutData%WAMIT2,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -7865,13 +9692,15 @@ SUBROUTINE HydroDyn_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WAMIT2_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT2, ErrStat2, ErrMsg2 ) ! WAMIT2 + CALL WAMIT2_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%WAMIT2(i1), ErrStat2, ErrMsg2 ) ! WAMIT2 CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -7985,47 +9814,7 @@ SUBROUTINE HydroDyn_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL MeshUnpack( OutData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! Mesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL MeshUnpack( OutData%AllHdroOrigin, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! AllHdroOrigin + CALL MeshUnpack( OutData%WAMITMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! WAMITMesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -8147,7 +9936,9 @@ SUBROUTINE HydroDyn_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, Er ScaleFactor = t_out / t(2) CALL Morison_Input_ExtrapInterp1( u1%Morison, u2%Morison, tin, u_out%Morison, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - CALL MeshExtrapInterp1(u1%Mesh, u2%Mesh, tin, u_out%Mesh, tin_out, ErrStat2, ErrMsg2 ) + CALL MeshExtrapInterp1(u1%WAMITMesh, u2%WAMITMesh, tin, u_out%WAMITMesh, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + CALL MeshExtrapInterp1(u1%PRPMesh, u2%PRPMesh, tin, u_out%PRPMesh, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) END SUBROUTINE HydroDyn_Input_ExtrapInterp1 @@ -8206,7 +9997,9 @@ SUBROUTINE HydroDyn_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) CALL Morison_Input_ExtrapInterp2( u1%Morison, u2%Morison, u3%Morison, tin, u_out%Morison, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - CALL MeshExtrapInterp2(u1%Mesh, u2%Mesh, u3%Mesh, tin, u_out%Mesh, tin_out, ErrStat2, ErrMsg2 ) + CALL MeshExtrapInterp2(u1%WAMITMesh, u2%WAMITMesh, u3%WAMITMesh, tin, u_out%WAMITMesh, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + CALL MeshExtrapInterp2(u1%PRPMesh, u2%PRPMesh, u3%PRPMesh, tin, u_out%PRPMesh, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) END SUBROUTINE HydroDyn_Input_ExtrapInterp2 @@ -8305,17 +10098,23 @@ SUBROUTINE HydroDyn_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, E END IF ScaleFactor = t_out / t(2) - CALL WAMIT_Output_ExtrapInterp1( y1%WAMIT, y2%WAMIT, tin, y_out%WAMIT, tin_out, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(y_out%WAMIT) .AND. ALLOCATED(y1%WAMIT)) THEN + DO i1 = LBOUND(y_out%WAMIT,1),UBOUND(y_out%WAMIT,1) + CALL WAMIT_Output_ExtrapInterp1( y1%WAMIT(i1), y2%WAMIT(i1), tin, y_out%WAMIT(i1), tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - CALL WAMIT2_Output_ExtrapInterp1( y1%WAMIT2, y2%WAMIT2, tin, y_out%WAMIT2, tin_out, ErrStat2, ErrMsg2 ) + ENDDO +END IF ! check if allocated +IF (ALLOCATED(y_out%WAMIT2) .AND. ALLOCATED(y1%WAMIT2)) THEN + DO i1 = LBOUND(y_out%WAMIT2,1),UBOUND(y_out%WAMIT2,1) + CALL WAMIT2_Output_ExtrapInterp1( y1%WAMIT2(i1), y2%WAMIT2(i1), tin, y_out%WAMIT2(i1), tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO +END IF ! check if allocated CALL Waves2_Output_ExtrapInterp1( y1%Waves2, y2%Waves2, tin, y_out%Waves2, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) CALL Morison_Output_ExtrapInterp1( y1%Morison, y2%Morison, tin, y_out%Morison, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - CALL MeshExtrapInterp1(y1%Mesh, y2%Mesh, tin, y_out%Mesh, tin_out, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - CALL MeshExtrapInterp1(y1%AllHdroOrigin, y2%AllHdroOrigin, tin, y_out%AllHdroOrigin, tin_out, ErrStat2, ErrMsg2 ) + CALL MeshExtrapInterp1(y1%WAMITMesh, y2%WAMITMesh, tin, y_out%WAMITMesh, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) @@ -8380,17 +10179,23 @@ SUBROUTINE HydroDyn_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrSta END IF ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) - CALL WAMIT_Output_ExtrapInterp2( y1%WAMIT, y2%WAMIT, y3%WAMIT, tin, y_out%WAMIT, tin_out, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(y_out%WAMIT) .AND. ALLOCATED(y1%WAMIT)) THEN + DO i1 = LBOUND(y_out%WAMIT,1),UBOUND(y_out%WAMIT,1) + CALL WAMIT_Output_ExtrapInterp2( y1%WAMIT(i1), y2%WAMIT(i1), y3%WAMIT(i1), tin, y_out%WAMIT(i1), tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - CALL WAMIT2_Output_ExtrapInterp2( y1%WAMIT2, y2%WAMIT2, y3%WAMIT2, tin, y_out%WAMIT2, tin_out, ErrStat2, ErrMsg2 ) + ENDDO +END IF ! check if allocated +IF (ALLOCATED(y_out%WAMIT2) .AND. ALLOCATED(y1%WAMIT2)) THEN + DO i1 = LBOUND(y_out%WAMIT2,1),UBOUND(y_out%WAMIT2,1) + CALL WAMIT2_Output_ExtrapInterp2( y1%WAMIT2(i1), y2%WAMIT2(i1), y3%WAMIT2(i1), tin, y_out%WAMIT2(i1), tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO +END IF ! check if allocated CALL Waves2_Output_ExtrapInterp2( y1%Waves2, y2%Waves2, y3%Waves2, tin, y_out%Waves2, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) CALL Morison_Output_ExtrapInterp2( y1%Morison, y2%Morison, y3%Morison, tin, y_out%Morison, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - CALL MeshExtrapInterp2(y1%Mesh, y2%Mesh, y3%Mesh, tin, y_out%Mesh, tin_out, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - CALL MeshExtrapInterp2(y1%AllHdroOrigin, y2%AllHdroOrigin, y3%AllHdroOrigin, tin, y_out%AllHdroOrigin, tin_out, ErrStat2, ErrMsg2 ) + CALL MeshExtrapInterp2(y1%WAMITMesh, y2%WAMITMesh, y3%WAMITMesh, tin, y_out%WAMITMesh, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) diff --git a/modules/hydrodyn/src/Morison.f90 b/modules/hydrodyn/src/Morison.f90 index c0fdc4b52e..b98fec7192 100644 --- a/modules/hydrodyn/src/Morison.f90 +++ b/modules/hydrodyn/src/Morison.f90 @@ -35,7 +35,7 @@ MODULE Morison ! ..... Public Subroutines ................................................................................................... - PUBLIC:: Morison_ProcessMorisonGeometry + PUBLIC:: Morison_GenerateSimulationNodes PUBLIC :: Morison_Init ! Initialization routine PUBLIC :: Morison_End ! Ending routine (includes clean up) @@ -100,8 +100,8 @@ SUBROUTINE Morison_DirCosMtrx( pos0, pos1, DirCos ) ELSE - DirCos(1, 1) = -(z0-z1)/xz - DirCos(1, 2) = -(x0-x1)*(y0-y1)/(xz*xyz) + DirCos(1, 1) = (z1-z0)/xz + DirCos(1, 2) = -(x1-x0)*(y1-y0)/(xz*xyz) DirCos(1, 3) = (x1-x0)/xyz DirCos(2, 1) = 0.0 @@ -109,13 +109,9 @@ SUBROUTINE Morison_DirCosMtrx( pos0, pos1, DirCos ) DirCos(2, 3) = (y1-y0)/xyz DirCos(3, 1) = -(x1-x0)/xz - DirCos(3, 2) = -(y0-y1)*(z0-z1)/(xz*xyz) + DirCos(3, 2) = -(y1-y0)*(z1-z0)/(xz*xyz) DirCos(3, 3) = (z1-z0)/xyz - - ! DEBUG: TODO : Remove - !PRINT*, sqrt(DirCos(1,1)*DirCos(1,1) + DirCos(1,2)*DirCos(1,2)+DirCos(1,3)*DirCos(1,3)) - !PRINT*, sqrt(DirCos(2,1)*DirCos(2,1) + DirCos(2,2)*DirCos(2,2)+DirCos(2,3)*DirCos(2,3)) - !PRINT*, sqrt(DirCos(3,1)*DirCos(3,1) + DirCos(3,2)*DirCos(3,2)+DirCos(3,3)*DirCos(3,3)) + END IF END SUBROUTINE Morison_DirCosMtrx @@ -350,671 +346,200 @@ FUNCTION InterpWrappedStpLogical( XValIn, XAry, YAry, Ind, AryLen ) RETURN END FUNCTION InterpWrappedStpLogical ! ( XVal, XAry, YAry, Ind, AryLen ) -SUBROUTINE DistrBuoyancy( densWater, R, tMG, dRdz, Z, C, g, F_B ) - ! This calculates the distributed buoyancy forces and moments on a given node - - REAL(ReKi), INTENT ( IN ) :: densWater - REAL(ReKi), INTENT ( IN ) :: R ! Radius of node [m] - REAL(ReKi), INTENT ( IN ) :: tMG ! Thickness of marine growth (adds to radius) [m] - REAL(ReKi), INTENT ( IN ) :: dRdz ! Rate of change in radius with length at node [-] - REAL(ReKi), INTENT ( IN ) :: Z ! z elevation of node [m] (not currently used) - REAL(ReKi), INTENT ( IN ) :: C(3,3) - REAL(ReKi), INTENT ( IN ) :: g - REAL(ReKi), INTENT ( OUT ) :: F_B(6) ! Distributed force and moment vector [N/m and N-m/m] - - REAL(DbKi) :: Reff,ReffSq,ReffCub,f1,f2,f3 - - REAL(DbKi) :: CC(3,3) - - CC = REAL(C,DbKi) - Reff = REAL(R + tMG,DbKi) ! Effective radius after adding marine growth - - - - ReffSq = Reff*Reff - ReffCub = ReffSq*Reff - f1 = REAL(denswater,DbKi)*REAL(g,DbKi)*Pi_D - f2 = f1*ReffCub*REAL(dRdz,DbKi) - f3 = Reff*REAL(dRdz,DbKi)*REAL(Z,DbKi) - - - F_B(1) = f1*( (CC(1,1)*CC(3,1) + CC(1,2)*CC(3,2))*ReffSq - 2.0*CC(1,3)*f3 ) - F_B(2) = f1*( (CC(2,1)*CC(3,1) + CC(2,2)*CC(3,2))*ReffSq - 2.0*CC(2,3)*f3 ) - F_B(3) = f1*( (CC(3,1)*CC(3,1) + CC(3,2)*CC(3,2))*ReffSq - 2.0*CC(3,3)*f3 ) - F_B(4) = -f2*( CC(1,1)*CC(3,2) - CC(1,2)*CC(3,1) ) - F_B(5) = -f2*( CC(2,1)*CC(3,2) - CC(2,2)*CC(3,1) ) - F_B(6) = -f2*( CC(3,1)*CC(3,2) - CC(3,2)*CC(3,1) ) - - - - -END SUBROUTINE DistrBuoyancy - - -SUBROUTINE DistrInertialLoads( nodeIndx, densWater, Ca, Cp, AxCa, AxCp, R, tMG, dRdZ, k, NStepWave, WaveAcc0, WaveDynP0, F_I, ErrStat, ErrMsg ) - - INTEGER, INTENT ( IN ) :: nodeIndx - REAL(ReKi), INTENT ( IN ) :: densWater - REAL(ReKi), INTENT ( IN ) :: Ca - REAL(ReKi), INTENT ( IN ) :: Cp - REAL(ReKi), INTENT ( IN ) :: AxCa - REAL(ReKi), INTENT ( IN ) :: AxCp - REAL(ReKi), INTENT ( IN ) :: R - REAL(ReKi), INTENT ( IN ) :: tMG - REAL(ReKi), INTENT ( IN ) :: dRdZ - REAL(ReKi), INTENT ( IN ) :: k(3) - INTEGER, INTENT ( IN ) :: NStepWave - REAL(SiKi), INTENT ( IN ) :: WaveAcc0(0:,:,:) - REAL(SiKi), INTENT ( IN ) :: WaveDynP0(0:,:) - REAL(ReKi),ALLOCATABLE, INTENT ( OUT ) :: F_I(:,:) - INTEGER, INTENT ( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT ( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - INTEGER :: I - REAL(ReKi) :: f, f1, f2, f3, adotk !, v_len - REAL(ReKi) :: v(3), af(3) !p0(3), m(3), - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - - ! Allocate F_I - ALLOCATE ( F_I(0:NStepWave, 6), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating distributed inertial loads array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - f = (Ca + Cp)*densWater*Pi*(R+tMG)*(R+tMG) - f2 = AxCa*densWater*2.0*Pi*(R+tMG)*(R+tMG)*abs(dRdZ) - f1 = AxCp*2.0*Pi*(R+tMG)*dRdz - - DO I=0,NStepWave - - af = WaveAcc0(I,nodeIndx,:) - adotk = af(1)*k(1) + af(2)*k(2) + af(3)*k(3) - v = af - adotk*k - - ! NOTE: (k cross l) x k = l - (l dot k)k - - f3 = f1*WaveDynP0(I,nodeIndx) - - !CALL GetDistance( p0, v, v_len ) - !TODO What about multiplying by the magnitude? - - - - F_I(I,1) = f*v(1) + (f3 + f2*adotk)*k(1) - F_I(I,2) = f*v(2) + (f3 + f2*adotk)*k(2) - F_I(I,3) = f*v(3) + (f3 + f2*adotk)*k(3) - F_I(I,4) = 0.0 - F_I(I,5) = 0.0 - F_I(I,6) = 0.0 - - END DO - -END SUBROUTINE DistrInertialLoads - - - -SUBROUTINE DistrInertialLoads2( densWater, Ca, Cp, AxCa, AxCp, R, tMG, dRdZ, k, WaveAcc, WaveDynP, F_I, ErrStat, ErrMsg ) - - REAL(ReKi), INTENT ( IN ) :: densWater - REAL(ReKi), INTENT ( IN ) :: Ca - REAL(ReKi), INTENT ( IN ) :: Cp - REAL(ReKi), INTENT ( IN ) :: AxCa - REAL(ReKi), INTENT ( IN ) :: AxCp - REAL(ReKi), INTENT ( IN ) :: R - REAL(ReKi), INTENT ( IN ) :: tMG - REAL(ReKi), INTENT ( IN ) :: dRdZ - REAL(ReKi), INTENT ( IN ) :: k(3) - REAL(ReKi), INTENT ( IN ) :: WaveAcc(3) - REAL(ReKi), INTENT ( IN ) :: WaveDynP - REAL(ReKi), INTENT ( OUT ) :: F_I(3) - !REAL(ReKi), INTENT ( OUT ) :: F_I(3) - INTEGER, INTENT ( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT ( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - INTEGER :: I - REAL(ReKi) :: f, f1, f2, f3, v_len, adotk - REAL(ReKi) :: p0(3), m(3), v(3), af(3) - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - - - - f = (Ca + Cp)*densWater*Pi*(R+tMG)*(R+tMG) - f2 = AxCa*densWater*2.0*Pi*(R+tMG)*(R+tMG)*abs(dRdZ) - f1 = AxCp*2.0*Pi*(R+tMG)*dRdz - - adotk = WaveAcc(1)*k(1) + WaveAcc(2)*k(2) + WaveAcc(3)*k(3) - v = WaveAcc - adotk*k - - ! NOTE: (k cross l) x k = l - (l dot k)k - - f3 = f1*WaveDynP - - !CALL GetDistance( p0, v, v_len ) - !TODO What about multiplying by the magnitude? - - - - F_I(1) = f*v(1) + (f3 + f2*adotk)*k(1) - F_I(2) = f*v(2) + (f3 + f2*adotk)*k(2) - F_I(3) = f*v(3) + (f3 + f2*adotk)*k(3) - !F_I(4) = 0.0_ReKi - !F_I(5) = 0.0_ReKi - !F_I(6) = 0.0_ReKi - - - -END SUBROUTINE DistrInertialLoads2 - - -SUBROUTINE DistrMGLoads(MGdens, g, R, tMG, F_MG ) - REAL(ReKi), INTENT ( IN ) :: MGdens - REAL(ReKi), INTENT ( IN ) :: g - REAL(ReKi), INTENT ( IN ) :: R - REAL(ReKi), INTENT ( IN ) :: tMG - REAL(ReKi), INTENT ( OUT ) :: F_MG(6) - - F_MG(:) = 0.0 - F_MG(3) = -MGdens*g*Pi* ( (R + tMG ) * ( R + tMG ) - R*R ) - -END SUBROUTINE DistrMGLoads - -SUBROUTINE DistrDragConst( densWater, Cd, R, tMG, DragConst ) - - ! This is used to minimize the computations which occur at each timestep - - REAL(ReKi), INTENT ( IN ) :: Cd - REAL(ReKi), INTENT ( IN ) :: densWater - REAL(ReKi), INTENT ( IN ) :: R - REAL(ReKi), INTENT ( IN ) :: tMG - REAL(ReKi), INTENT ( OUT ) :: DragConst - - DragConst = Cd*densWater*(R+tMG) - -END SUBROUTINE DistrDragConst - - -SUBROUTINE DistrFloodedBuoyancy( densFluid, Z_f, R, t, dRdz, Z, C, g, F_B ) - - REAL(ReKi), INTENT ( IN ) :: densFluid - REAL(ReKi), INTENT ( IN ) :: Z_f - REAL(ReKi), INTENT ( IN ) :: R - REAL(ReKi), INTENT ( IN ) :: t - REAL(ReKi), INTENT ( IN ) :: dRdz - REAL(ReKi), INTENT ( IN ) :: Z - REAL(ReKi), INTENT ( IN ) :: C(3,3) - REAL(ReKi), INTENT ( IN ) :: g - REAL(ReKi), INTENT ( OUT ) :: F_B(6) - - REAL(DbKi) :: Zeff,Reff,ReffSq,ReffCub,f1,f2,f3 - - - REAL(DbKi) :: CC(3,3) - CC = REAL(C,DbKi) - - - Reff = REAL(R - t,DbKi) - Zeff = REAL(Z - Z_f,DbKi) - - ReffSq = Reff*Reff - ReffCub = ReffSq*Reff - f1 = -REAL(densFluid,DbKi)*REAL(g,DbKi)*Pi_D - f2 = f1*ReffCub*REAL(dRdz,DbKi) - f3 = Reff*REAL(dRdz,DbKi)*Zeff - - - - F_B(1) = f1*( (CC(1,1)*CC(3,1) + CC(1,2)*CC(3,2))*ReffSq - 2.0*CC(1,3)*f3 ) - F_B(2) = f1*( (CC(2,1)*CC(3,1) + CC(2,2)*CC(3,2))*ReffSq - 2.0*CC(2,3)*f3 ) - F_B(3) = f1*( (CC(3,1)*CC(3,1) + CC(3,2)*CC(3,2))*ReffSq - 2.0*CC(3,3)*f3 ) - F_B(4) = -f2*( CC(1,1)*CC(3,2) - CC(1,2)*CC(3,1) ) - F_B(5) = -f2*( CC(2,1)*CC(3,2) - CC(2,2)*CC(3,1) ) - F_B(6) = -f2*( CC(3,1)*CC(3,2) - CC(3,2)*CC(3,1) ) - -END SUBROUTINE DistrFloodedBuoyancy - -SUBROUTINE DistrAddedMass( densWater, Ca, AxCa, C, R, tMG, dRdZ, AM_M) - ! This calculates the distributed hydrodynamic added mass matrix for a given node. - - REAL(ReKi), INTENT ( IN ) :: densWater - REAL(ReKi), INTENT ( IN ) :: Ca ! Transverse added mass coefficient - REAL(ReKi), INTENT ( IN ) :: AxCa ! Axial added mass coefficient (applied to tapered portions) - REAL(ReKi), INTENT ( IN ) :: C(3,3) - REAL(ReKi), INTENT ( IN ) :: R ! Radius at node [m] - REAL(ReKi), INTENT ( IN ) :: tMG ! Thickness of marine growth (adds to radius) [m] - REAL(ReKi), INTENT ( IN ) :: dRdZ ! Rate of change in radius with length at node [-] - REAL(ReKi), INTENT ( OUT ) :: AM_M(3,3) ! Distributed added mass matrix to be calculated [kg/m] - - REAL(ReKi) :: f,f2 - - f = Ca*densWater*Pi*(R+tMG)*(R+tMG) ! Transverse added mass scaler, applied to I - k*k^T - f2 = AxCa*2.0*densWater*Pi*abs(dRdZ)*(R+tMG)*(R+tMG) ! Axial added mass scaler, applied to k k^T - !AM_M = 0.0 - AM_M(1,1) = f*( C(2,3)*C(2,3) + C(3,3)*C(3,3) ) -f2*C(1,3)*C(1,3) !<----@mhall: why is the f2 term being subtracted rather than added? - AM_M(1,2) = f*( -C(1,3)*C(2,3) ) -f2*C(1,3)*C(2,3) - AM_M(1,3) = f*( -C(1,3)*C(3,3) ) -f2*C(1,3)*C(3,3) - - AM_M(2,1) = f*( -C(1,3)*C(2,3) ) -f2*C(2,3)*C(1,3) - AM_M(2,2) = f*( C(1,3)*C(1,3) + C(3,3)*C(3,3) ) -f2*C(2,3)*C(2,3) !<----@mhall: would it be cleaner to just use the k unit vector? (also, diagonal terms can be shortened (1-k*kT)) - AM_M(2,3) = f*( -C(2,3)*C(3,3) ) -f2*C(2,3)*C(3,3) - - AM_M(3,1) = f*( -C(1,3)*C(3,3) ) -f2*C(3,3)*C(1,3) - AM_M(3,2) = f*( -C(2,3)*C(3,3) ) -f2*C(3,3)*C(2,3) - AM_M(3,3) = f*( C(1,3)*C(1,3) + C(2,3)*C(2,3) ) -f2*C(3,3)*C(3,3) - - -END SUBROUTINE DistrAddedMass - - -SUBROUTINE DistrAddedMassMG( densMG, R, tMG, AM_MG) - - REAL(ReKi), INTENT ( IN ) :: densMG - REAL(ReKi), INTENT ( IN ) :: R - REAL(ReKi), INTENT ( IN ) :: tMG - REAL(ReKi), INTENT ( OUT ) :: AM_MG - - AM_MG = densMG*Pi*((R+tMG)*(R+tMG) - R*R) - - -END SUBROUTINE DistrAddedMassMG - - -SUBROUTINE DistrAddedMassFlood( densFluid, R, t, AM_F) - - REAL(ReKi), INTENT ( IN ) :: densFluid - REAL(ReKi), INTENT ( IN ) :: R - REAL(ReKi), INTENT ( IN ) :: t - REAL(ReKi), INTENT ( OUT ) :: AM_F - - - AM_F = densFluid*Pi*(R-t)*(R-t) - -END SUBROUTINE DistrAddedMassFlood - - - -SUBROUTINE LumpDragConst( densWater, Cd, R, tMG, DragConst ) - - ! This is used to minimize the computations which occur at each timestep - - REAL(ReKi), INTENT ( IN ) :: Cd - REAL(ReKi), INTENT ( IN ) :: densWater - REAL(ReKi), INTENT ( IN ) :: R - REAL(ReKi), INTENT ( IN ) :: tMG - REAL(ReKi), INTENT ( OUT ) :: DragConst - - DragConst = 0.5*Cd*densWater*(R+tMG)*(R+tMG) +subroutine GetOrientationAngles(p1, p2, phi, sinPhi, cosPhi, tanPhi, sinBeta, cosBeta, k_hat, errStat, errMsg) + real(ReKi), intent(in ) :: p1(3),p2(3) + real(ReKi), intent( out) :: phi, sinPhi, cosPhi, tanPhi, sinBeta, cosBeta, k_hat(3) + integer, intent( out) :: errStat ! returns a non-zero value when an error occurs + character(*), intent( out) :: errMsg ! Error message if errStat /= ErrID_None + + + real(ReKi) :: vec(3), vecLen, vecLen2D, beta + + ! Initialize errStat + + errStat = ErrID_None + errMsg = "" + + ! calculate isntantaneous incline angle and heading, and related trig values + ! the first and last NodeIndx values point to the corresponding Joint nodes idices which are at the start of the Mesh + vec = p2 - p1 + vecLen = SQRT(Dot_Product(vec,vec)) + vecLen2D = SQRT(vec(1)**2+vec(2)**2) + if ( vecLen < 0.000001 ) then + call SeterrStat(ErrID_Fatal, 'An element of the Morison structure has co-located endpoints! This should never occur. Please review your model.', errStat, errMsg, 'Morison_CalcOutput' ) + else + k_hat = vec / vecLen + phi = atan2(vecLen2D, vec(3)) ! incline angle + end if + if ( EqualRealNos(phi, 0.0_ReKi) ) then + beta = 0.0_ReKi + else + beta = atan2(vec(2), vec(1)) ! heading of incline + endif + sinPhi = sin(phi) + cosPhi = cos(phi) + tanPhi = tan(phi) + sinBeta = sin(beta) + cosBeta = cos(beta) + +end subroutine GetOrientationAngles + + +!function to return conical taper geometry calculations (volume and center of volume) +SUBROUTINE TaperCalc(R1, R2, H, taperV, h_c) + REAL(ReKi), INTENT ( IN ) :: R1 + REAL(ReKi), INTENT ( IN ) :: R2 + REAL(ReKi), INTENT ( IN ) :: H + REAL(ReKi), INTENT ( OUT ) :: taperV ! volume of tapered section + REAL(ReKi), INTENT ( OUT ) :: h_c ! center of mass offset from first node + + real(ReKi) :: m + + m = (R2-R1)/H + + 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 + taperV = abs(1.0/3.0*pi*R2*R2*H) ! cone volume + h_c = 3.0/4.0*H ! from base + else + taperV = abs(pi/3.0/m*(R2**3 - R1**3)) + h_c = H*(R1**2 + 2*R1*R2 + 3*R2**2)/4.0/(R1**2 + R1*R2 + R2**2) !( coneV*1./4.*coneH - coneVtip*(1./4.*(coneH-H) + H) )/ taperV ! from base + end if + +END SUBROUTINE TaperCalc + + +SUBROUTINE CylInertia(R1, R2, H, rho, Il, Ir) + REAL(ReKi), INTENT ( IN ) :: R1 + REAL(ReKi), INTENT ( IN ) :: R2 + REAL(ReKi), INTENT ( IN ) :: H + REAL(ReKi), INTENT ( IN ) :: rho ! density of material + REAL(ReKi), INTENT ( OUT ) :: Il + REAL(ReKi), INTENT ( OUT ) :: Ir + + real(ReKi) :: m, Ir_tip, h_c + + m = (R2-R1)/H + + 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 + 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 + h_c = H*(R1**2 + 2*R1*R2 + 3*R2**2)/4.0/(R1**2 + R1*R2 + R2**2) + !l_c = R1/M + (R2-R1)/m *(R1**2 + 2*R1*R2 + 3*R2**2)/4/(R1**2 + R1*R2 + R2**2) + Ir_tip = abs(pi/20.0 *rho/m*(1.0 + 4.0/m**2) * (R2**5 - R1**5)) ! radial moment of inertia about tip of cone + Ir = abs(Ir_tip - rho/3.0/m*pi*(R2**3-R1**3) * (R1/m + 2.0*h_c)*R1/m ) ! radial moment of inertia about node 1 + Il = abs(1.0/10.0/m*rho*pi*(R2**5 - R1**5)) + END IF -END SUBROUTINE LumpDragConst - - -SUBROUTINE LumpDynPressure( nodeIndx, Cp, k, R, tMG, NStepWave, WaveDynP, F_DP, ErrStat, ErrMsg ) +END SUBROUTINE CylInertia - INTEGER, INTENT ( IN ) :: nodeIndx - REAL(ReKi), INTENT ( IN ) :: Cp - REAL(ReKi), INTENT ( IN ) :: k(3) - REAL(ReKi), INTENT ( IN ) :: R - REAL(ReKi), INTENT ( IN ) :: tMG - INTEGER, INTENT ( IN ) :: NStepWave - REAL(SiKi), INTENT ( IN ) :: WaveDynP(0:,:) - REAL(ReKi),ALLOCATABLE, INTENT ( OUT ) :: F_DP(:,:) - INTEGER, INTENT ( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT ( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - INTEGER :: I +SUBROUTINE MarineGrowthPartSegment(R1, R2, Rmg1, Rmg2, L, rho, Vinner, Vouter, m_mg, h_c, Ilmg, Irmg) - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" + REAL(ReKi), INTENT ( IN ) :: R1 + REAL(ReKi), INTENT ( IN ) :: R2 + REAL(ReKi), INTENT ( IN ) :: Rmg1 + REAL(ReKi), INTENT ( IN ) :: Rmg2 + REAL(ReKi), INTENT ( IN ) :: L + REAL(ReKi), INTENT ( IN ) :: rho ! density of material + REAL(ReKi), INTENT ( OUT ) :: Vinner ! volume from inner radius + REAL(ReKi), INTENT ( OUT ) :: Vouter ! volume from outer radius + REAL(ReKi), INTENT ( OUT ) :: m_mg ! mass of marine growth + REAL(ReKi), INTENT ( OUT ) :: h_c ! center of mass offset from first node + REAL(ReKi), INTENT ( OUT ) :: Ilmg ! moment of inertia about axis + REAL(ReKi), INTENT ( OUT ) :: Irmg ! moment of inertia about radial axis from first node + ! Local variables - ! Allocate F_DP - - ALLOCATE ( F_DP(0:NStepWave,6), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating distributed dynamic pressure loads array.' - ErrStat = ErrID_Fatal - RETURN - END IF + REAL(ReKi) :: cVinner ! center of volume from inner radius + REAL(ReKi) :: cVouter ! center of volume from outer radius + REAL(ReKi) :: Ilinner + REAL(ReKi) :: Irinner + REAL(ReKi) :: Ilouter + REAL(ReKi) :: Irouter - DO I=0,NStepWave - F_DP(I,1) = Cp*k(1)*Pi*(R+tMG)*(R+tMG)*WaveDynP(I,nodeIndx) - F_DP(I,2) = Cp*k(2)*Pi*(R+tMG)*(R+tMG)*WaveDynP(I,nodeIndx) - F_DP(I,3) = Cp*k(3)*Pi*(R+tMG)*(R+tMG)*WaveDynP(I,nodeIndx) - F_DP(I,4) = 0.0 - F_DP(I,5) = 0.0 - F_DP(I,6) = 0.0 - END DO -END SUBROUTINE LumpDynPressure - - - -SUBROUTINE LumpBuoyancy( sgn, densWater, R, tMG, Z, C, g, F_B ) - ! This calculates lumped buoyancy forces/moments on a member end. + ! get V and CV for element + call TaperCalc(R1, R2, L, Vinner, cVinner) - REAL(ReKi), INTENT ( IN ) :: sgn ! @mhall: this indicates if this is the start or end node so that direction is correct? - REAL(ReKi), INTENT ( IN ) :: densWater - REAL(ReKi), INTENT ( IN ) :: R ! Radius of end [m] - REAL(ReKi), INTENT ( IN ) :: tMG ! Thickness of marine growth (adds to radius) [m] - REAL(ReKi), INTENT ( IN ) :: Z ! z elevation of end [m] - - REAL(ReKi), INTENT ( IN ) :: C(3,3) - REAL(ReKi), INTENT ( IN ) :: g - REAL(ReKi), INTENT ( OUT ) :: F_B(6) ! Lumped force and moment vector [N and N-m] - - - REAL(DbKi) :: f, f1, f2, f3, Reff, Rsq,R_4 - Reff = REAL(R+tMG,DbKi) - Rsq = Reff**2 - R_4 = Rsq**2 - f = REAL(g,DbKi)*REAL(densWater,DbKi)*REAL(sgn,DbKi) - f1 = -REAL(Z,DbKi)*Pi_D*Rsq - f2 = f*Pi_D*R_4 - !f3 = C(3,1)*R_4 - - F_B(1) = C(1,3)*f1*f - F_B(2) = C(2,3)*f1*f - F_B(3) = C(3,3)*f1*f - F_B(4) = 0.25*( -C(3,2)*C(1,1) + C(1,2)*C(3,1) )*f2 ! TODO: We flipped the signs of the moments because 1 member tapered integrated moments were not zero. GJH 10/1/13 Jason is verifying. - F_B(5) = 0.25*( -C(3,2)*C(2,1) + C(2,2)*C(3,1) )*f2 - F_B(6) = 0.25*( -C(3,2)*C(3,1) + C(3,2)*C(3,1) )*f2 + ! get V and CV for marine growth displacement + call TaperCalc(Rmg1, Rmg2, L, Vouter, cVouter) + ! get mass and CV specific to marine growth thickness + m_mg = (Vouter - Vinner)*rho + if ( EqualRealNos(m_mg, 0.0_ReKi) ) then + h_c = 0.0 + else + h_c = (cVouter*Vouter - Vinner*cVinner)/(Vouter - Vinner) + end if -END SUBROUTINE LumpBuoyancy + ! get two moments of inertia for marine growth as if solid... + call CylInertia(Rmg1, Rmg2, L, rho, Ilouter, Irouter) ! inertias for marine growth if solid + call CylInertia(R1 , R2 , L, rho, Ilinner, Irinner) ! inertias for element if filled with marine growth + ! subtract to get moments of inertia of marine growth shell + Ilmg = Ilouter - Ilinner + Irmg = Irouter - Irinner +END SUBROUTINE MarineGrowthPartSegment -SUBROUTINE LumpFloodedBuoyancy( sgn, densFill, R, tM, FillFS, Z, C, g, F_BF ) - - REAL(ReKi), INTENT ( IN ) :: sgn - REAL(ReKi), INTENT ( IN ) :: densFill - REAL(ReKi), INTENT ( IN ) :: R - REAL(ReKi), INTENT ( IN ) :: tM - REAL(ReKi), INTENT ( IN ) :: FillFS - REAL(ReKi), INTENT ( IN ) :: Z - REAL(ReKi), INTENT ( IN ) :: C(3,3) - REAL(ReKi), INTENT ( IN ) :: g - REAL(ReKi), INTENT ( OUT ) :: F_BF(6) - - - REAL(ReKi) :: f, f1, f2 !, f3 - - f = -densFill*g*sgn - - f1 = -(Z - FillFS)*Pi* (R-tM)*(R-tM) - f2 = 0.25*Pi*(R-tM)*(R-tM)*(R-tM)*(R-tM) - - F_BF(1) = C(1,3)*f1*f - F_BF(2) = C(2,3)*f1*f - F_BF(3) = C(3,3)*f1*f - F_BF(4) = (-C(1,1)*C(3,2) + C(1,2)*C(3,1))*f*f2 ! TODO: We flipped the signs of the moments because 1 member tapered integrated moments were not zero. GJH 10/1/13 Jason is verifying. - F_BF(5) = (-C(2,1)*C(3,2) + C(2,2)*C(3,1))*f*f2 - F_BF(6) = (-C(3,1)*C(3,2) + C(3,2)*C(3,1))*f*f2 +SUBROUTINE FloodedBallastPartSegment(R1, R2, L, rho, V, m, h_c, Il, Ir) + REAL(ReKi), INTENT ( IN ) :: R1 ! interior radius of element at node point + REAL(ReKi), INTENT ( IN ) :: R2 ! interior radius of other end of part-element + REAL(ReKi), INTENT ( IN ) :: L ! distance positive along axis to end of part-element + REAL(ReKi), INTENT ( OUT ) :: V ! volume from inner radius + REAL(ReKi), INTENT ( IN ) :: rho ! density of ballast + REAL(ReKi), INTENT ( OUT ) :: m ! mass of material + REAL(ReKi), INTENT ( OUT ) :: h_c ! center of mass offset from first node + REAL(ReKi), INTENT ( OUT ) :: Il ! moment of inertia about axis + REAL(ReKi), INTENT ( OUT ) :: Ir ! moment of inertia about radial axis from first node -END SUBROUTINE LumpFloodedBuoyancy -LOGICAL FUNCTION IsThisSplitValueUsed(nSplits, splits, checkVal) - - INTEGER, INTENT ( IN ) :: nSplits - REAL(ReKi), INTENT ( IN ) :: splits(:) - REAL(ReKi), INTENT ( IN ) :: checkVal - INTEGER :: I + ! get V and CV for flooded part of part-element + call TaperCalc(R1, R2, L, V, h_c) + m = rho*V - DO I=1,nSplits - IF ( EqualRealNos(splits(I), checkVal ) ) THEN - IsThisSplitValueUsed = .TRUE. - RETURN - END IF -END DO + call CylInertia(R1, R2, L, rho, Il, Ir) ! inertias for filled section - IsThisSplitValueUsed = .FALSE. - -END FUNCTION IsThisSplitValueUsed -!==================================================================================================== -SUBROUTINE GetMaxSimQuantities( numMGDepths, MGTop, MGBottom, MSL2SWL, Zseabed, filledGroups, numJoints, joints, numMembers, members, maxNodes, maxElements, maxSuperMembers ) -! This private subroutine determines the maximum nodes, elements, and super members which may appear -! in the final simulation mesh. This is based on the following: -! 1) Member splitting at the marine growth boundaries ( new nodes and members ) -! 2) Member splitting due to internal subdivision ( new nodes and members ) -! 3) New nodes and super members if a joint marked with JointOvrlp = 1 (and additional conditions are satisfied) -! -!---------------------------------------------------------------------------------------------------- - INTEGER, INTENT ( IN ) :: numMGDepths ! number of MGDepths specified in the input table - REAL(ReKi), INTENT ( IN ) :: MGTop ! Global Z-value of the upper marine growth boundary - REAL(ReKi), INTENT ( IN ) :: MGBottom ! Global Z-value of the lower marine growth boundary - REAL(ReKi), INTENT ( IN ) :: MSL2SWL ! Global Z-value of mean sea level - REAL(ReKi), INTENT ( IN ) :: Zseabed ! Global Z-value of the top of the seabed - TYPE(Morison_FilledGroupType), INTENT ( IN ) :: filledGroups(:) - INTEGER, INTENT ( IN ) :: numJoints ! number of joints specified in the inputs - TYPE(Morison_JointType), INTENT ( IN ) :: joints(:) ! array of input joint data structures - INTEGER, INTENT ( IN ) :: numMembers ! number of members specified in the inputs - TYPE(Morison_MemberInputType), INTENT ( INOUT ) :: members(:) ! array of input member data structures - INTEGER, INTENT ( OUT ) :: maxNodes ! maximum number of nodes which may appear in the final simulation mesh - INTEGER, INTENT ( OUT ) :: maxElements ! maximum number of elements which may appear in the final simulation mesh - INTEGER, INTENT ( OUT ) :: maxSuperMembers ! maximum number of super members which may appear in the final simulation mesh - - ! Local variables - INTEGER :: WtrSplitCount = 0 ! number of possible new members due to splitting at water boundaries - INTEGER :: MGsplitCount = 0 ! number of possible new members due to splitting at marine growth boundaries - INTEGER :: maxSubMembers = 0 ! maximum added nodes and members due to member subdivision - INTEGER :: maxSuperMemNodes = 0 ! maximum number of new nodes due to super member generation - INTEGER :: I, J, j1, j2 ! generic integer for counting - TYPE(Morison_JointType) :: joint1, joint2 ! joint data structures - Real(ReKi) :: z1, z2 ! z values of the first and second joints - Real(ReKi) :: temp ! temporary variable - REAL(ReKi) :: memLen ! member length - INTEGER :: nSplits, totalSplits, nodeSplits - REAL(ReKi) :: possibleSplits(5) - ! Initialize quantities - maxNodes = numJoints - maxElements = numMembers - maxSuperMembers = 0 - maxSuperMemNodes = 0 - maxSubMembers = 0 - MGsplitCount = 0 - WtrSplitCount = 0 - nodeSplits = 0 - totalSplits = 0 - - ! Determine new members and nodes due to internal member subdivision - DO I = 1,numMembers - - - z1 = joints( members(I)%MJointID1Indx )%JointPos(3) - z2 = joints( members(I)%MJointID2Indx )%JointPos(3) - IF ( z1 > z2) THEN - temp = z1 - z1 = z2 - z2 = temp - END IF - - - - ! For this member, determine possible split conditions due to crossing through: - ! MSL, seabed, marine growth boundaries, filled free surface location. - ! - - ! Start with no splits. - nSplits = 0 - possibleSplits = -9999999.0 ! Initialize possibleSplit values to a number that never appears in the geometry. - - ! If the member is filled, add a possible split location at the global Z location of the filled free surface. - IF ( members(I)%MmbrFilledIDIndx /= -1 ) THEN - nSplits = 1 - ! The free surface is specified relative to the MSL. - possibleSplits(1) = filledGroups(members(I)%MmbrFilledIDIndx)%FillFSLoc - END IF - - - ! If the filled fluid hasn't already caused a split in the member at the still water line, then add a possible split there (at the water free surface, MSL2SWL). - IF ( .NOT. IsThisSplitValueUsed(nSplits, possibleSplits, MSL2SWL )) THEN - nSplits = nSplits + 1 - possibleSplits(nSplits) = MSL2SWL - END IF - - ! If there are one more depth-defined marine growth regions, add a possible split at each boundary if one doesn't already exist. - IF ( numMGDepths > 0 ) THEN - - ! Recursively check to see if this - IF ( .NOT. IsThisSplitValueUsed(nSplits, possibleSplits, MGTop) ) THEN - nSplits = nSplits + 1 - possibleSplits(nSplits) = MGTop - END IF - IF ( .NOT. IsThisSplitValueUsed(nSplits, possibleSplits, MGBottom) ) THEN - nSplits = nSplits + 1 - possibleSplits(nSplits) = MGBottom - END IF - - END IF - - ! Add a possible split a the seabed if there isn't already one there. - ! Check if seabed is equal to other possibleSplits - IF ( .NOT. IsThisSplitValueUsed(nSplits, possibleSplits, Zseabed) ) THEN - nSplits = nSplits + 1 - possibleSplits(nSplits) = Zseabed - END IF - - - ! Now determine which possible splits this member actually crosses and record them in the member's data structure. - - DO J=1,nSplits - - IF ( z1 < possibleSplits(J) .AND. z2 > possibleSplits(J) ) THEN - members(I)%NumSplits = members(I)%NumSplits + 1 - members(I)%Splits(members(I)%NumSplits) = possibleSplits(J) - END IF - - END DO - ! Sort the splits from smallest Z value to largest Z value - CALL BSortReal ( members(I)%Splits, members(I)%NumSplits ) - totalSplits = totalSplits + members(I)%NumSplits - - ! ! Determine new members due to elements crossing the MSL or the seabed - !IF ( z2 > MSL2SWL ) THEN - ! IF ( z1 < MSL2SWL .AND. z1 >= Zseabed ) THEN - ! ! Split this member - ! WtrSplitCount = WtrSplitCount + 1 - ! members(I).WtrSplitState = 1 - ! END IF - ! IF ( z1 < Zseabed ) THEN - ! ! Split this member twice because it crosses both boundaries - ! WtrSplitCount = WtrSplitCount + 2 - ! members(I).WtrSplitState = 3 - ! END IF - !END IF - !IF ( z2 < MSL2SWL .AND. z2 >= Zseabed ) THEN - ! IF ( z1 < MGBottom ) THEN - ! ! Split this member - ! WtrSplitCount = WtrSplitCount + 1 - ! members(I).WtrSplitState = 2 - ! END IF - ! - !END IF - ! - ! ! Determine new members and nodes due to marine growth boundary splitting - ! members(I).MGSplitState = 0 - !IF ( numMGDepths > 0 ) THEN - ! - ! IF ( z2 > MGTop ) THEN - ! IF ( z1 < MGTop .AND. z1 >= MGBottom ) THEN - ! ! Split this member - ! MGsplitCount = MGsplitCount + 1 - ! members(I).MGSplitState = 1 - ! END IF - ! IF ( z1 < MGBottom ) THEN - ! ! Split this member twice because it crosses both boundaries - ! MGsplitCount = MGsplitCount + 2 - ! members(I).MGSplitState = 3 - ! END IF - ! END IF - ! IF ( z2 < MGTop .AND. z2 >= MGBottom ) THEN - ! IF ( z1 < MGBottom ) THEN - ! ! Split this member - ! MGsplitCount = MGsplitCount + 1 - ! members(I).MGSplitState = 2 - ! END IF - ! - ! END IF - ! - !END IF - - j1 = members(I)%MJointID1Indx - j2 = members(I)%MJointID2Indx - joint1 = joints(j1) ! note Inspector complains of uninitialized variables; this is due to copying types here (and some fields haven't been initialized) - joint2 = joints(j2) ! note Inspector complains of uninitialized variables; this is due to copying types here (and some fields haven't been initialized) - CALL GetDistance(joint1%JointPos, joint2%JointPos, memLen) - maxSubMembers = maxSubMembers + CEILING( memLen / members(I)%MDivSize ) - 1 - - END DO - - ! Look for all possible super member creation - DO I = 1,numJoints - - ! Check #1 are there more than 2 members connected to the joint? - IF ( joints(I)%JointOvrlp == 1 .AND. joints(I)%NConnections > 2) THEN - maxSuperMemNodes = maxSuperMemNodes + ( joints(I)%NConnections - 1 ) - maxSuperMembers = maxSuperMembers + 1 - ELSE - nodeSplits = nodeSplits + joints(I)%NConnections - 1 - END IF - - - END DO - - maxNodes = maxNodes + totalSplits*2 + nodeSplits + maxSubMembers + maxSuperMemNodes - maxElements = maxElements + totalSplits + maxSubMembers - - -END SUBROUTINE GetMaxSimQuantities +END SUBROUTINE FloodedBallastPartSegment -SUBROUTINE WriteSummaryFile( UnSum, MSL2SWL, WtrDpth, numNodes, nodes, numElements, elements, NOutputs, OutParam, NMOutputs, MOutLst, distribToNodeIndx, NJOutputs, JOutLst, inLumpedMesh, outLumpedMesh, inDistribMesh, outDistribMesh, L_F_B, L_F_BF, D_F_B, D_F_BF, D_F_MG, g, ErrStat, ErrMsg ) !, numDistribMarkers, distribMarkers, numLumpedMarkers, lumpedMarkers +SUBROUTINE WriteSummaryFile( UnSum, g, MSL2SWL, WtrDpth, numJoints, numNodes, nodes, numMembers, members, & + NOutputs, OutParam, NMOutputs, MOutLst, NJOutputs, JOutLst, uMesh, yMesh, & + p, m, errStat, errMsg ) + + INTEGER, INTENT ( IN ) :: UnSum + REAL(ReKi), INTENT ( IN ) :: g ! gravity REAL(ReKi), INTENT ( IN ) :: MSL2SWL REAL(ReKi), INTENT ( IN ) :: WtrDpth - INTEGER, INTENT ( IN ) :: UnSum + INTEGER, INTENT ( IN ) :: numJoints INTEGER, INTENT ( IN ) :: numNodes TYPE(Morison_NodeType), INTENT ( IN ) :: nodes(:) - INTEGER, INTENT ( IN ) :: numElements - TYPE(Morison_MemberType), INTENT ( IN ) :: elements(:) + INTEGER, INTENT ( IN ) :: numMembers + TYPE(Morison_MemberType), INTENT ( IN ) :: members(:) INTEGER, INTENT ( IN ) :: NOutputs TYPE(OutParmType), INTENT ( IN ) :: OutParam(:) INTEGER, INTENT ( IN ) :: NMOutputs TYPE(Morison_MOutput), INTENT ( IN ) :: MOutLst(:) - INTEGER, INTENT ( IN ) :: distribToNodeIndx(:) INTEGER, INTENT ( IN ) :: NJOutputs TYPE(Morison_JOutput), INTENT ( IN ) :: JOutLst(:) - TYPE(MeshType), INTENT ( INOUT ) :: inLumpedMesh - TYPE(MeshType), INTENT ( INOUT ) :: outLumpedMesh - TYPE(MeshType), INTENT ( INOUT ) :: inDistribMesh - TYPE(MeshType), INTENT ( INOUT ) :: outDistribMesh - REAL(ReKi), INTENT ( IN ) :: L_F_B(:,:) ! Lumped buoyancy force associated with the member - REAL(ReKi), INTENT ( IN ) :: L_F_BF(:,:) ! Lumped buoyancy force associated flooded/filled fluid within the member - REAL(ReKi), INTENT ( IN ) :: D_F_B(:,:) ! Lumped buoyancy force associated with the member - REAL(ReKi), INTENT ( IN ) :: D_F_BF(:,:) ! Lumped buoyancy force associated flooded/filled fluid within the member - REAL(ReKi), INTENT ( IN ) :: D_F_MG(:,:) - REAL(ReKi), INTENT ( IN ) :: g ! gravity - !INTEGER, INTENT ( IN ) :: numDistribMarkers - !TYPE(Morison_NodeType), INTENT ( IN ) :: distribMarkers(:) - !INTEGER, INTENT ( IN ) :: numLumpedMarkers - !TYPE(Morison_NodeType), INTENT ( IN ) :: lumpedMarkers(:) - INTEGER, INTENT ( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT ( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None + TYPE(MeshType), INTENT ( INOUT ) :: uMesh + TYPE(MeshType), INTENT ( INOUT ) :: yMesh + TYPE(Morison_ParameterType), INTENT ( IN ) :: p + TYPE(Morison_MiscVarType), INTENT ( IN ) :: m + INTEGER, INTENT ( OUT ) :: errStat ! returns a non-zero value when an error occurs + CHARACTER(*), INTENT ( OUT ) :: errMsg ! Error message if errStat /= ErrID_None INTEGER :: I, J REAL(ReKi) :: l ! length of an element @@ -1040,16 +565,19 @@ SUBROUTINE WriteSummaryFile( UnSum, MSL2SWL, WtrDpth, numNodes, nodes, numElemen INTEGER :: m1, m2 ! Indices of the markers which surround the requested output location REAL(ReKi) :: s ! The linear interpolation factor for the requested location REAL(ReKi) :: outloc(3) ! Position of the requested member output - INTEGER :: mbrIndx, nodeIndx + INTEGER :: mbrIndx, nodeIndx, c, N CHARACTER(ChanLen) :: tmpName - REAL(ReKi) :: totalFillMass, mass_fill, fillVol + REAL(ReKi) :: totalFillMass, mass_fill, fillVol, memberVol REAL(ReKi) :: totalMGMass, mass_MG TYPE(Morison_NodeType) :: node1, node2 - REAL(ReKi) :: Cd1, Cd2, Ca1, Ca2, Cp1, Cp2, AxCa1, AxCa2, AxCp1, AxCp2, JAxCd1, JAxCd2, JAxCa1, JAxCa2, JAxCp1, JAxCp2 ! tmp coefs - + real(ReKi) :: ptLoad(6) + logical :: fillFlag + type(Morison_MemberType) :: mem + REAL(ReKi) :: Cd1, Cd2, Ca1, Ca2, Cp1, Cp2, AxCd1, AxCd2, AxCa1, AxCa2, AxCp1, AxCp2, JAxCd1, JAxCd2, JAxCa1, JAxCa2, JAxCp1, JAxCp2 ! tmp coefs + real(ReKi) :: F_B(6, numNodes), F_BF(6, numNodes), F_WMG(6, numNodes) ! Initialize data - ErrStat = ErrID_None - ErrMsg = "" + errStat = ErrID_None + errMsg = "" ExtBuoyancy = 0.0 totalFillMass = 0.0 totalDisplVol = 0.0 @@ -1058,74 +586,40 @@ SUBROUTINE WriteSummaryFile( UnSum, MSL2SWL, WtrDpth, numNodes, nodes, numElemen totalFillVol = 0.0 totalMGMass = 0.0 COB = 0.0 + F_B = 0.0 + F_BF = 0.0 + F_WMG = 0.0 ! Create identity matrix - CALL EYE(ident,ErrStat,ErrMsg) + CALL EYE(ident,errStat,errMsg) IF ( UnSum > 0 ) THEN - - - - !WRITE( UnSum, '(//)' ) - !WRITE( UnSum, '(A8)' ) 'Elements' - !WRITE( UnSum, '(/)' ) - !WRITE( UnSum, '(1X,A5,2X,A5,2X,A5,5(2X,A12),2X,A12,17(2X,A12))' ) ' i ', 'node1','node2',' Length ', ' MGVolume ', ' MGDensity ', 'PropPot ', 'FilledFlag', 'FillDensity', ' FillFSLoc ', ' FillMass ', ' Cd1 ', ' CdMG1 ', ' Ca1 ', ' CaMG1 ', ' R1 ', ' t1 ',' Cd2 ', ' CdMG2 ', ' Ca2 ', ' CaMG2 ', ' R2 ', ' t2 ' - !WRITE( UnSum, '(1X,A5,2X,A5,2X,A5,5(2X,A12),2X,A12,17(2X,A12))' ) ' (-) ', ' (-) ',' (-) ',' (m) ', ' (m^3) ', ' (kg/m^3) ', ' (-) ', ' (-) ', ' (kg/m^3) ', ' (-) ', ' (kg) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (m) ', ' (m) ',' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (m) ', ' (m) ' - ! - - DO I = 1,numElements - - node1 = nodes(elements(I)%Node1Indx) - node2 = nodes(elements(I)%Node2Indx) - IF ( ( (node1%tMG > 0.0_ReKi ) .AND. EqualRealNos(node2%tMG,0.0_ReKi) ) .OR. ( (node2%tMG > 0.0_ReKi ) .AND. EqualRealNos(node1%tMG,0.0_ReKi) ) ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'If one node of an element has MG, then both must. This is an internal code problem within HydroDyn.' - RETURN - END IF - CALL GetDistance( nodes(elements(I)%Node1Indx)%JointPos, nodes(elements(I)%Node2Indx)%JointPos, l ) - - - IF (elements(I)%PropPot) THEN - MGvolume = 0.0 - elementVol = 0.0 - ELSE - elementVol = ElementVolume(elements(I)%R1 + node1%tMG, elements(I)%R2 + node2%tMG, l) - MGvolume = elementVol - ElementVolume(elements(I)%R1, elements(I)%R2, l) - END IF - totalMGVol = totalMGVol + MGvolume - mass_MG = MGvolume*elements(I)%FillDens - totalMGMass = totalMGMass + mass_MG - CALL ElementCentroid(elements(I)%R1 + node1%tMG, elements(I)%R2 + node2%tMG, node1%JointPos, l, elements(I)%R_LToG, elemCentroid) - - COB = COB + elementVol*elemCentroid - - totalVol = totalVol + elementVol - - IF ( node2%JointPos(3) <= MSL2SWL .AND. node1%JointPos(3) >= -WtrDpth) totalDisplVol = totalDisplVol + elementVol - - IF ( elements(I)%MmbrFilledIDIndx > 0 ) THEN - ! filledFlag = .TRUE. - !IF ( ( node2%JointPos(3) <= elements(I)%FillFSLoc ) .AND. ( node1%JointPos(3) <= elements(I)%FillFSLoc ) ) THEN - fillVol = ElementVolume(elements(I)%R1 - elements(I)%t1, elements(I)%R2 - elements(I)%t2, l) - totalFillVol = totalFillVol + fillVol - mass_fill = elements(I)%FillDens*fillVol - totalFillMass = totalFillMass + mass_fill - !END IF - ELSE - ! mass_fill = 0.0 - ! filledFlag = .FALSE. - END IF + do j = 1, numMembers + + mem = members(j) + totalVol = totalVol + mem%Vouter + totalMGVol = totalMGVol + mem%Vouter - mem%Vinner + totalDisplVol = totalDisplVol + mem%Vsubmerged + totalFillVol = totalFillVol + mem%Vballast - !WRITE( UnSum, '(1X,I5,2X,I5,2X,I5,3(2X,ES12.5),2(2X,L12),2X,ES12.5,17(2X,ES12.5))' ) I, elements(I)%Node1Indx, elements(I)%Node2Indx, l, MGvolume, node1%MGdensity, elements(I)%PropPot, filledFlag, elements(I)%FillDens, elements(I)%FillFSLoc, mass_fill, elements(I)%Cd1, elements(I)%CdMG1, elements(I)%Ca1, elements(I)%CaMG1, elements(I)%R1, elements(I)%t1, elements(I)%Cd2, elements(I)%CdMG2, elements(I)%Ca2, elements(I)%CaMG2, elements(I)%R2, elements(I)%t2 + ! IF ( node2%Position(3) <= MSL2SWL .AND. node1%Position(3) >= -WtrDpth) totalDisplVol = totalDisplVol + elementVol - END DO ! I = 1,numElements - + + do i = 1, mem%NElements + totalMGMass = totalMGMass + mem%m_mg_l(i) + totalMGMass = totalMGMass + mem%m_mg_u(i) + end do + do i = 1, mem%NElements+1 + F_B (:,mem%NodeIndx(i)) = F_B (:,mem%NodeIndx(i)) + m%memberLoads(j)%F_B (:,i) + F_BF (:,mem%NodeIndx(i)) = F_BF (:,mem%NodeIndx(i)) + m%memberLoads(j)%F_BF (:,i) + F_WMG(:,mem%NodeIndx(i)) = F_WMG(:,mem%NodeIndx(i)) + m%memberLoads(j)%F_WMG(:,i) + end do + end do - WRITE( UnSum, '(//)' ) - WRITE( UnSum, '(A24)' ) 'Volume Calculations(m^3)' - WRITE( UnSum, '(A24)' ) '------------------------' + WRITE( UnSum, '(A37)' ) 'Strip-Theory Volume Calculations(m^3)' + WRITE( UnSum, '(A37)' ) '-------------------------------------' WRITE( UnSum, '(A27,ES12.5)' ) ' Structure Volume : ', totalVol WRITE( UnSum, '(A27,ES12.5)' ) ' Submerged Volume : ', totalDisplVol WRITE( UnSum, '(A27,ES12.5)' ) ' Marine Growth Volume : ', totalMGVol @@ -1133,25 +627,14 @@ SUBROUTINE WriteSummaryFile( UnSum, MSL2SWL, WtrDpth, numNodes, nodes, numElemen WRITE( UnSum, '(A111)') ' NOTE: Structure, Submerged and Marine Growth volumes are based on members not modelled with WAMIT' WRITE( UnSum, '(A149)') ' Ballasted volume is computed from all members which are marked as filled in the HydroDyn input file, regardless of PropPot flag' - - - ! Sum all buoyancy loads to the COB - ! Do this by creating a temporary mesh which is for (0,0,0) - - !COB = COB / totalVol - - ! Write out the Center of Buoyancy (geometric center of the displaced volume) - !WRITE( UnSum, '(//)' ) - !WRITE( UnSum, '(A18)' ) 'Center of Buoyancy' - !WRITE( UnSum, '(3(2X,A10 ))' ) ' COBXi ', ' COBYi ', ' COBZi ' - !WRITE( UnSum, '(3(2X,A10 ))' ) ' (m) ', ' (m) ', ' (m) ' - !WRITE( UnSum, '(3(2X,F10.3))' ) COB(1) , COB(2) , COB(3) + + ! Create a point mesh at (0,0,0) so that we can integrate the Morison load contributions to a single point for reporting purposes CALL MeshCreate( BlankMesh = WRP_Mesh & ,IOS = COMPONENT_INPUT & ,Nnodes = 1 & - ,ErrStat = ErrStat & - ,ErrMess = ErrMsg & + ,errStat = errStat & + ,ErrMess = errMsg & ,Force = .TRUE. & ,Moment = .TRUE. & ) @@ -1160,25 +643,25 @@ SUBROUTINE WriteSummaryFile( UnSum, MSL2SWL, WtrDpth, numNodes, nodes, numElemen CALL MeshPositionNode (WRP_Mesh & , 1 & , (/0.0_ReKi, 0.0_ReKi, 0.0_ReKi/) & - , ErrStat & - , ErrMsg & + , errStat & + , errMsg & ) - IF ( ErrStat /= 0 ) RETURN + IF ( errStat /= 0 ) RETURN ! Create the mesh element CALL MeshConstructElement ( WRP_Mesh & , ELEMENT_POINT & - , ErrStat & - , ErrMsg & + , errStat & + , errMsg & , 1 & ) CALL MeshCommit ( WRP_Mesh & - , ErrStat & - , ErrMsg ) + , errStat & + , errMsg ) - IF ( ErrStat /= ErrID_None ) RETURN + IF ( errStat /= ErrID_None ) RETURN ! we need the translation displacement mesh for loads transfer: CALL MeshCopy ( SrcMesh = WRP_Mesh & @@ -1186,10 +669,10 @@ SUBROUTINE WriteSummaryFile( UnSum, MSL2SWL, WtrDpth, numNodes, nodes, numElemen , CtrlCode = MESH_SIBLING & , IOS = COMPONENT_INPUT & , TranslationDisp = .TRUE. & - , ErrStat = ErrStat & - , ErrMess = ErrMsg ) ! automatically sets DestMesh%RemapFlag = .TRUE. + , errStat = errStat & + , ErrMess = errMsg ) ! automatically sets DestMesh%RemapFlag = .TRUE. - IF ( ErrStat /= ErrID_None ) RETURN + IF ( errStat /= ErrID_None ) RETURN WRP_Mesh_position%TranslationDisp = 0.0 ! bjj: this is actually initialized in the ModMesh module, but I'll do it here anyway. WRP_Mesh%RemapFlag = .TRUE. @@ -1201,76 +684,39 @@ SUBROUTINE WriteSummaryFile( UnSum, MSL2SWL, WtrDpth, numNodes, nodes, numElemen ! in the hydrodynamics for conditions where the wave height is > SWL. So we now need to check that the vertical position ! is <= SWL for this summary file calculation. - DO J = 1, outDistribMesh%Nnodes - if ( outDistribMesh%Position(3,J) <= MSL2SWL ) then - DO I=1,6 - - IF (I < 4 ) THEN - - outDistribMesh%Force(I ,J) = D_F_B(I,J) - - ELSE - - outDistribMesh%Moment(I-3,J) = D_F_B(I,J) - - END IF - - END DO ! DO I - end if ! <= MSL2SWL check + + DO J = 1, yMesh%Nnodes + if ( yMesh%Position(3,J) <= 0.0 ) then + + if (J <= numJoints) then + ptLoad = F_B(:,J) + m%F_B_end(:,J) + else + ptLoad = F_B(:,J) + end if + yMesh%Force(:,J) = ptLoad(1:3) + yMesh%Moment(:,J) = ptLoad(4:6) + else + yMesh%Force(:,J) = 0.0 + yMesh%Moment(:,J) = 0.0 + end if ! <= still water line check END DO ! DO J - + ! Transfer the loads from the distributed mesh to the (0,0,0) point mesh - CALL MeshMapCreate ( outDistribMesh, WRP_Mesh, M_L_2_P, ErrStat, ErrMsg ) - !CALL CheckError( ErrStat, 'Message from MeshMapCreate HD_M_L_2_ED_P: '//NewLine//ErrMsg ) - CALL Transfer_Line2_to_Point( outDistribMesh, WRP_Mesh, M_L_2_P, ErrStat, ErrMsg, inDistribMesh, WRP_Mesh_position ) + CALL MeshMapCreate ( yMesh, WRP_Mesh, M_P_2_P, errStat, errMsg ) + !CALL CheckError( errStat, 'Message from MeshMapCreate HD_M_L_2_ED_P: '//NewLine//errMsg ) + CALL Transfer_Point_to_Point( yMesh, WRP_Mesh, M_P_2_P, errStat, errMsg, uMesh, WRP_Mesh_position ) ExtBuoyancy(1:3) = WRP_Mesh%Force (:,1) ExtBuoyancy(4:6) = WRP_Mesh%Moment(:,1) - - - ! Transfer the loads from the lumped mesh to the (0,0,0) point mesh - - ! Because of wave stretching and user-supplied waves, we may have loads above the still water line (SWL) which will be used - ! in the hydrodynamics for conditions where the wave height is > SWL. So we now need to check that the vertical position - ! is <= SWL for this summary file calculation. - - DO J = 1, outLumpedMesh%Nnodes - if ( outLumpedMesh%Position(3,J) <= MSL2SWL ) then - DO I=1,6 - - IF (I < 4 ) THEN - - outLumpedMesh%Force(I ,J) = L_F_B(I,J) - - ELSE - - outLumpedMesh%Moment(I-3,J) = L_F_B(I,J) - - END IF - - END DO ! DO I - end if ! <= MSL2SWL check - END DO ! DO J - - ! Remap for the lumped to WRP mesh transfer - WRP_Mesh%RemapFlag = .TRUE. - - CALL MeshMapCreate ( outLumpedMesh, WRP_Mesh, M_P_2_P, ErrStat, ErrMsg ) - CALL Transfer_Point_to_Point( outLumpedMesh, WRP_Mesh, M_P_2_P, ErrStat, ErrMsg, inLumpedMesh, WRP_Mesh_position ) - - ExtBuoyancy(1:3) = ExtBuoyancy(1:3) + WRP_Mesh%Force (:,1) - ExtBuoyancy(4:6) = ExtBuoyancy(4:6) + WRP_Mesh%Moment(:,1) - - - + ! Write the buoyancy table headers and the external results - + WRITE( UnSum, '(//)' ) - WRITE( UnSum, '(A45)' ) 'Buoyancy loads summed about ( 0.0, 0.0, 0.0 )' - WRITE( UnSum, '(A45)' ) '---------------------------------------------' + WRITE( UnSum, '(A51)' ) 'Total Buoyancy loads summed about ( 0.0, 0.0, 0.0 )' + WRITE( UnSum, '(A51)' ) '---------------------------------------------------' WRITE( UnSum, '(18x,6(2X,A20))' ) ' BuoyFxi ', ' BuoyFyi ', ' BuoyFzi ', ' BuoyMxi ', ' BuoyMyi ', ' BuoyMzi ' WRITE( UnSum, '(18x,6(2X,A20))' ) ' (N) ', ' (N) ', ' (N) ', ' (N-m) ', ' (N-m) ', ' (N-m) ' WRITE( UnSum, '(A18,6(2X,ES20.6))') 'External: ', ExtBuoyancy(1), ExtBuoyancy(2), ExtBuoyancy(3), ExtBuoyancy(4), ExtBuoyancy(5), ExtBuoyancy(6) @@ -1278,242 +724,159 @@ SUBROUTINE WriteSummaryFile( UnSum, MSL2SWL, WtrDpth, numNodes, nodes, numElemen ! Now compute internal Buoyancy - DO J = 1, outDistribMesh%Nnodes + DO J = 1, yMesh%Nnodes - DO I=1,6 - - IF (I < 4 ) THEN - - outDistribMesh%Force(I,J ) = D_F_BF(I,J) - - ELSE - - outDistribMesh%Moment(I-3,J) = D_F_BF(I,J) - - END IF - - END DO ! DO I + if (J <= numJoints) then + ptLoad = F_BF(:,J) + m%F_BF_end(:,J) + else + ptLoad = F_BF(:,J) + end if + yMesh%Force(:,J) = ptLoad(1:3) + yMesh%Moment(:,J) = ptLoad(4:6) END DO ! DO J IntBuoyancy = 0.0 - CALL Transfer_Line2_to_Point( outDistribMesh, WRP_Mesh, M_L_2_P, ErrStat, ErrMsg, inDistribMesh, WRP_Mesh_position ) + CALL Transfer_Point_to_Point( yMesh, WRP_Mesh, M_P_2_P, errStat, errMsg, uMesh, WRP_Mesh_position ) IntBuoyancy(1:3) = WRP_Mesh%Force(:,1) IntBuoyancy(4:6) = WRP_Mesh%Moment(:,1) + + WRITE( UnSum, '(A18,6(2X,ES20.6))') 'Internal: ', IntBuoyancy(1), IntBuoyancy(2), IntBuoyancy(3), IntBuoyancy(4), IntBuoyancy(5), IntBuoyancy(6) + IntBuoyancy = IntBuoyancy + ExtBuoyancy + WRITE( UnSum, '(A18,6(2X,ES20.6))') 'Total : ', IntBuoyancy(1), IntBuoyancy(2), IntBuoyancy(3), IntBuoyancy(4), IntBuoyancy(5), IntBuoyancy(6) + WRITE( UnSum, '(A81)') ' NOTE: External buoyancy is based on members not modelled with WAMIT' + WRITE( UnSum, '(A150)') ' Internal buoyancy is computed from all members which are marked as filled in the HydroDyn input file, regardless of PropPot flag' + WRITE( UnSum, '(A88)') ' Total buoyancy does not include WAMIT-modelled buoyancy contribution' + + - DO J = 1, outLumpedMesh%Nnodes + ! ! Now compute marine growth weight at the WRP - DO I=1,6 - - IF (I < 4 ) THEN - - outLumpedMesh%Force(I,J) = L_F_BF(I,J) - - ELSE - - outLumpedMesh%Moment(I-3,J) = L_F_BF(I,J) - - END IF - - END DO ! DO I - - END DO ! DO J - - CALL Transfer_Point_to_Point( outLumpedMesh, WRP_Mesh, M_P_2_P, ErrStat, ErrMsg, inLumpedMesh, WRP_Mesh_position ) - IntBuoyancy(1:3) = IntBuoyancy(1:3) + WRP_Mesh%Force(:,1) - IntBuoyancy(4:6) = IntBuoyancy(4:6) + WRP_Mesh%Moment(:,1) - - - ! clean up - - CALL MeshMapDestroy( M_P_2_P, ErrStat, ErrMsg ); IF ( ErrStat /= ErrID_None ) CALL WrScr(TRIM(ErrMsg)) - - WRITE( UnSum, '(A18,6(2X,ES20.6))') 'Internal: ', IntBuoyancy(1), IntBuoyancy(2), IntBuoyancy(3), IntBuoyancy(4), IntBuoyancy(5), IntBuoyancy(6) - IntBuoyancy = IntBuoyancy + ExtBuoyancy - WRITE( UnSum, '(A18,6(2X,ES20.6))') 'Total : ', IntBuoyancy(1), IntBuoyancy(2), IntBuoyancy(3), IntBuoyancy(4), IntBuoyancy(5), IntBuoyancy(6) - !WRITE( UnSum, '(/)' ) - WRITE( UnSum, '(A81)') ' NOTE: External buoyancy is based on members not modelled with WAMIT' - WRITE( UnSum, '(A150)') ' Internal buoyancy is computed from all members which are marked as filled in the HydroDyn input file, regardless of PropPot flag' - WRITE( UnSum, '(A88)') ' Total buoyancy does not include WAMIT-modelled buoyancy contribution' - - - - ! Now compute marine growth weight at the WRP - - DO J = 1, outDistribMesh%Nnodes + DO J = 1, yMesh%Nnodes + if (J <= numJoints) then + yMesh%Force(:,J) = F_WMG(1:3,J) + p%F_WMG_End(:,J) + else + yMesh%Force(:,J) = F_WMG(1:3,J) + end if - DO I=1,6 - - IF (I < 4 ) THEN - - outDistribMesh%Force(I,J) = D_F_MG(I,J) - - ELSE - - outDistribMesh%Moment(I-3,J) = D_F_MG(I,J) - - END IF - - END DO ! DO I + yMesh%Moment(:,J) = F_WMG(4:6,J) - END DO ! DO J - + END DO ! DO J MG_Wt = 0.0 - CALL Transfer_Line2_to_Point( outDistribMesh, WRP_Mesh, M_L_2_P, ErrStat, ErrMsg, inDistribMesh, WRP_Mesh_position ) + CALL Transfer_Point_to_Point( yMesh, WRP_Mesh, M_P_2_P, errStat, errMsg, uMesh, WRP_Mesh_position ) MG_Wt(1:3) = WRP_Mesh%Force(:,1) MG_Wt(4:6) = WRP_Mesh%Moment(:,1) - + ! + CALL MeshMapDestroy( M_P_2_P, errStat, errMsg ); IF ( errStat /= ErrID_None ) CALL WrScr(TRIM(errMsg)) + WRITE( UnSum, '(//)' ) WRITE( UnSum, '(A36)' ) 'Weight loads about ( 0.0, 0.0, 0.0 )' WRITE( UnSum, '(A36)' ) '------------------------------------' WRITE( UnSum, '(18x,6(2X,A20))' ) ' MGFxi ', ' MGFyi ', ' MGFzi ', ' MGMxi ', ' MGMyi ', ' MGMzi ' WRITE( UnSum, '(18x,6(2X,A20))' ) ' (N) ', ' (N) ', ' (N) ', ' (N-m) ', ' (N-m) ', ' (N-m) ' - !WRITE( UnSum, '(A16,6(2X,E20.6))') 'Structure : ', M_Wt(1), M_Wt(2), M_Wt(3), M_Wt(4), M_Wt(5), M_Wt(6) WRITE( UnSum, '(A18,6(2X,ES20.6))') 'Marine Growth: ', MG_Wt(1), MG_Wt(2), MG_Wt(3), MG_Wt(4), MG_Wt(5), MG_Wt(6) - !WRITE( UnSum, '(A16,6(2X,E20.6))') 'Filled Fluid : ', F_Wt(1), F_Wt(2), F_Wt(3), F_Wt(4), F_Wt(5), F_Wt(6) - !M_Wt = M_Wt + MG_Wt + F_Wt - !WRITE( UnSum, '(A16,6(2X,E20.6))') 'Total : ', M_Wt(1), M_Wt(2), M_Wt(3), M_Wt(4), M_Wt(5), M_Wt(6) - - - CALL MeshMapDestroy( M_L_2_P, ErrStat, ErrMsg ); IF ( ErrStat /= ErrID_None ) CALL WrScr(TRIM(ErrMsg)) - CALL MeshDestroy(WRP_Mesh, ErrStat, ErrMsg ); IF ( ErrStat /= ErrID_None ) CALL WrScr(TRIM(ErrMsg)) - CALL MeshDestroy(WRP_Mesh_position, ErrStat, ErrMsg ); IF ( ErrStat /= ErrID_None ) CALL WrScr(TRIM(ErrMsg)) + - ! Write the header for this section + CALL MeshDestroy(WRP_Mesh, errStat, errMsg ); IF ( errStat /= ErrID_None ) CALL WrScr(TRIM(errMsg)) + CALL MeshDestroy(WRP_Mesh_position, errStat, errMsg ); IF ( errStat /= ErrID_None ) CALL WrScr(TRIM(errMsg)) + ! + ! ! Write the header for this section WRITE( UnSum, '(//)' ) - WRITE( UnSum, '(A5)' ) 'Nodes' + WRITE( UnSum, '(A14,I4,A44)' ) 'Nodes (first [',numJoints,'] are joints, remainder are internal nodes)' WRITE( UnSum, '(/)' ) - WRITE( UnSum, '(1X,A5,24(2X,A10),2X,A5,2X,A15)' ) ' i ', 'JointIndx ', 'JointOvrlp', 'InpMbrIndx', ' Nxi ', ' Nyi ', ' Nzi ', 'InpMbrDist', ' R ', ' dRdZ ', ' t ', ' tMG ', ' MGDens ', ' PropPot ', 'FilledFlag', ' FillDens ', 'FillFSLoc ', ' Cd ', ' Ca ', ' Cp ', ' AxCa ', ' AxCp ', ' JAxCd ', ' JAxCa ', ' JAxCp ', 'NConn ', 'Connection List' - WRITE( UnSum, '(1X,A5,24(2X,A10),2X,A5,2X,A15)' ) ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (m) ', ' (m) ', ' (m) ', ' (-) ', ' (m) ', ' (-) ', ' (m) ', ' (m) ', ' (kg/m^3) ', ' (-) ', ' (-) ', ' (kg/m^3) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' ' - - ! Write the data - DO I = 1,numNodes - WRITE(strFmt,'(I2)') nodes(I)%NConnections - IF ( nodes(I)%NodeType == 1 ) THEN - strNodeType = 'End ' - ELSE IF ( nodes(I)%NodeType == 2 ) THEN - strNodeType = 'Interior ' - ELSE IF ( nodes(I)%NodeType == 3 ) THEN - strNodeType = 'Super ' - ELSE - strNodeType = 'ERROR ' - END IF - - WRITE( UnSum, '(1X,I5,3(2X,I10),4(2X,F10.4),5(2X,ES10.3),2(2X,L10),10(2X,ES10.3),2X,I5,' // strFmt // '(2X,I4))' ) I, nodes(I)%JointIndx, nodes(I)%JointOvrlp, nodes(I)%InpMbrIndx, nodes(I)%JointPos, nodes(I)%InpMbrDist, nodes(I)%R, nodes(I)%DRDZ, nodes(I)%t, nodes(I)%tMG, nodes(I)%MGdensity, nodes(I)%PropPot, nodes(I)%FillFlag, nodes(I)%FillDensity, nodes(I)%FillFSLoc, nodes(I)%Cd, nodes(I)%Ca, nodes(I)%Cp, nodes(I)%AxCa, nodes(I)%AxCp, nodes(I)%JAxCd, nodes(I)%JAxCa, nodes(I)%JAxCp, nodes(I)%NConnections, nodes(I)%ConnectionList(1:nodes(I)%NConnections) - END DO + WRITE( UnSum, '(1X,A5,20(2X,A10))' ) ' i ', ' MbrIndx ', ' Nxi ', ' Nyi ', ' Nzi ', ' R ', ' t ', ' tMG ', ' MGDens ', ' PropPot ', 'FilledFlag', 'FilledMass', ' Cd ', ' Ca ', ' Cp ', ' AxCd ', ' AxCa ', ' AxCp ', ' JAxCd ', ' JAxCa ', ' JAxCp ' + WRITE( UnSum, '(1X,A5,20(2X,A10))' ) ' (-) ', ' (-) ', ' (m) ', ' (m) ', ' (m) ', ' (m) ', ' (m) ', ' (m) ', ' (kg/m^3) ', ' (-) ', ' (-) ', ' (kg) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ' - WRITE( UnSum, '(//)' ) - WRITE( UnSum, '(A8)' ) 'Elements' - WRITE( UnSum, '(/)' ) - WRITE( UnSum, '(1X,A5,2X,A5,2X,A5,13(2X,A12),2X,A12,21(2X,A12))' ) ' i ', 'node1','node2',' Length ', ' Volume ', ' MGVolume ', ' R1 ', ' tMG1 ', ' t1 ', ' R2 ', ' tMG2 ', ' t2 ', ' MGDens1 ', ' MGDens2 ', ' PropPot ', 'FilledFlag', 'FillDensity', ' FillFSLoc ', ' FillMass ', ' Cd1 ', ' Ca1 ', ' Cp1 ', ' AxCa1 ', ' AxCp1 ', ' JAxCd1 ', ' JAxCa1 ', ' JAxCp1 ', ' Cd2 ', ' Ca2 ', ' Cp2 ', ' AxCa2 ', ' AxCp2 ', ' JAxCd2 ', ' JAxCa2 ', ' JAxCp2 ' - WRITE( UnSum, '(1X,A5,2X,A5,2X,A5,13(2X,A12),2X,A12,21(2X,A12))' ) ' (-) ', ' (-) ',' (-) ',' (m) ', ' (m^3) ', ' (m^3) ', ' (m) ', ' (m) ', ' (m) ', ' (m) ', ' (m) ', ' (m) ', ' (kg/m^3) ', ' (kg/m^3) ', ' (-) ', ' (-) ', ' (kg/m^3) ', ' (-) ', ' (kg) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ' + ! Write the node data + do I = 1,numJoints + write( UnSum, '(1X,I5,(2X,A10),3(2X,F10.4),2(2X,A10),2(2X,ES10.3),9(2X,A10),3(2X,ES10.3))' ) i,' - ', nodes(i)%Position, ' - ', ' - ', nodes(i)%tMG, nodes(i)%MGdensity, ' - ', ' - ', ' - ', ' - ', ' - ', ' - ', ' - ', ' - ', ' - ', nodes(i)%JAxCd, nodes(i)%JAxCa, nodes(i)%JAxCp + end do + c = numJoints + do j= 1, numMembers + do i = 2, members(j)%NElements + c = c + 1 + if (members(j)%l_fill - members(j)%dl*(i-1) > 0.0) then + fillFlag = .true. + else + fillFlag = .false. + end if + write( UnSum, '(1X,I5,(2X,I10),3(2X,F10.4),4(2X,ES10.3),2(6X,L6),7(2X,ES10.3),3(7x,A5))' ) c, members(j)%MemberID, nodes(c)%Position, members(j)%R(i), members(j)%R(i)-members(j)%Rin(i), members(j)%tMG(i), members(j)%MGdensity(i), members(j)%PropPot, fillFlag, members(j)%m_fb_u(i)+members(j)%m_fb_l(i), members(j)%Cd(i), members(j)%Ca(i), members(j)%Cp(i), members(j)%AxCd(i), members(j)%AxCa(i), members(j)%AxCp(i), ' - ', ' - ', ' - ' + end do + end do - - - DO I = 1,numElements - - node1 = nodes(elements(I)%Node1Indx) - node2 = nodes(elements(I)%Node2Indx) - IF ( ( (node1%tMG > 0.0_ReKi ) .AND. EqualRealNos(node2%tMG,0.0_ReKi) ) .OR. ( (node2%tMG > 0.0_ReKi ) .AND. EqualRealNos(node1%tMG,0.0_ReKi) ) ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'If one node of an element has MG, then both must. This is an internal code problem within HydroDyn.' - RETURN - END IF - CALL GetDistance( nodes(elements(I)%Node1Indx)%JointPos, nodes(elements(I)%Node2Indx)%JointPos, l ) - - - IF (elements(I)%PropPot) THEN + write( UnSum, '(//)' ) + write( UnSum, '(A8)' ) 'Members' + write( UnSum, '(/)' ) + write( UnSum, '(1X,A8,2X,A6,2X,A6,31(2X,A12))' ) 'MemberID', 'joint1','joint2',' Length ', ' NElem ', ' Volume ', ' MGVolume ', ' R1 ', ' t1 ', ' R2 ', ' t2 ', ' PropPot ', 'FilledFlag', 'FillDensity', ' FillFSLoc ', ' FillMass ', ' Cd1 ', ' Ca1 ', ' Cp1 ', ' AxCd1 ', ' AxCa1 ', ' AxCp1 ', ' JAxCd1 ', ' JAxCa1 ', ' JAxCp1 ', ' Cd2 ', ' Ca2 ', ' Cp2 ', ' AxCd2 ', ' AxCa2 ', ' AxCp2 ', ' JAxCd2 ', ' JAxCa2 ', ' JAxCp2 ' + write( UnSum, '(1X,A8,2X,A6,2X,A6,31(2X,A12))' ) ' (-) ', ' (-) ',' (-) ',' (m) ', ' (-) ', ' (m^3) ', ' (m^3) ', ' (m) ', ' (m) ', ' (m) ', ' (m) ', ' (-) ', ' (-) ', ' (kg/m^3) ', ' (-) ', ' (kg) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ', ' (-) ' + + + + + do i = 1,numMembers + N = members(i)%NElements + + IF (members(i)%PropPot) THEN MGvolume = 0.0 - elementVol = 0.0 + memberVol = 0.0 ELSE - elementVol = ElementVolume(elements(I)%R1 + node1%tMG, elements(I)%R2 + node2%tMG, l) - MGvolume = elementVol - ElementVolume(elements(I)%R1, elements(I)%R2, l) + memberVol = members(i)%Vouter + MGvolume = members(i)%Vouter - members(i)%Vinner END IF - ! totalMGVol = totalMGVol + MGvolume - ! mass_MG = MGvolume*elements(I)%FillDens - ! totalMGMass = totalMGMass + mass_MG - CALL ElementCentroid(elements(I)%R1 + node1%tMG, elements(I)%R2 + node2%tMG, node1%JointPos, l, elements(I)%R_LToG, elemCentroid) - - ! COB = COB + elementVol*elemCentroid - - ! totalVol = totalVol + elementVol - - !IF ( node2%JointPos(3) <= MSL2SWL .AND. node1%JointPos(3) >= ) totalDisplVol = totalDisplVol + elementVol - - IF ( elements(I)%MmbrFilledIDIndx > 0 ) THEN - filledFlag = .TRUE. - !IF ( ( node2%JointPos(3) <= elements(I)%FillFSLoc ) .AND. ( node1%JointPos(3) <= elements(I)%FillFSLoc ) ) THEN - fillVol = ElementVolume(elements(I)%R1 - elements(I)%t1, elements(I)%R2 - elements(I)%t2, l) - ! totalFillVol = totalFillVol + fillVol - mass_fill = elements(I)%FillDens*fillVol - ! totalFillMass = totalFillMass + mass_fill - !END IF + + IF ( members(i)%l_fill > 0.0 ) THEN + filledFlag = .TRUE. + mass_fill = members(i)%FillDens*members(i)%Vballast ELSE mass_fill = 0.0 filledFlag = .FALSE. END IF + + Cd1 = members(i)%Cd(1) + Cd2 = members(i)%Cd(N+1) + Ca1 = members(i)%Ca(1) + Ca2 = members(i)%Ca(N+1) + Cp1 = members(i)%Cp(1) + Cp2 = members(i)%Cp(N+1) + AxCd1 = members(i)%AxCd(1) + AxCd2 = members(i)%AxCd(N+1) + AxCa1 = members(i)%AxCa(1) + AxCa2 = members(i)%AxCa(N+1) + AxCp1 = members(i)%AxCp(1) + AxCp2 = members(i)%AxCp(N+1) + + JAxCd1 = nodes(members(i)%NodeIndx(1 ))%JAxCd + JAxCd2 = nodes(members(i)%NodeIndx(1+N))%JAxCd + JAxCa1 = nodes(members(i)%NodeIndx(1 ))%JAxCa + JAxCa2 = nodes(members(i)%NodeIndx(1+N))%JAxCa + JAxCp1 = nodes(members(i)%NodeIndx(1 ))%JAxCp + JAxCp2 = nodes(members(i)%NodeIndx(1+N))%JAxCp + - IF (EqualRealNos(node1%tMG,0.0_ReKi)) THEN - Cd1 = elements(I)%Cd1 - Cd2 = elements(I)%Cd2 - Ca1 = elements(I)%Ca1 - Ca2 = elements(I)%Ca2 - Cp1 = elements(I)%Cp1 - Cp2 = elements(I)%Cp2 - AxCa1 = elements(I)%AxCa1 - AxCa2 = elements(I)%AxCa2 - AxCp1 = elements(I)%AxCp1 - AxCp2 = elements(I)%AxCp2 - ELSE - Cd1 = elements(I)%CdMG1 - Cd2 = elements(I)%CdMG2 - Ca1 = elements(I)%CaMG1 - Ca2 = elements(I)%CaMG2 - Cp1 = elements(I)%CpMG1 - Cp2 = elements(I)%CpMG2 - AxCa1 = elements(I)%AxCaMG1 - AxCa2 = elements(I)%AxCaMG2 - AxCp1 = elements(I)%AxCpMG1 - AxCp2 = elements(I)%AxCpMG2 - END IF - - JAxCd1 = node1%JAxCd - JAxCa1 = node1%JAxCa - JAxCp1 = node1%JAxCp - JAxCd2 = node2%JAxCd - JAxCa2 = node2%JAxCa - JAxCp2 = node2%JAxCp - - WRITE( UnSum, '(1X,I5,2X,I5,2X,I5,11(2X,ES12.5),2(2X,L12),2X,ES12.5,21(2X,ES12.5))' ) I, & - elements(I)%Node1Indx, elements(I)%Node2Indx, l, elementVol, MGvolume, elements(I)%R1, & - node1%tMG, elements(I)%t1, elements(I)%R2, node2%tMG, elements(I)%t2, node1%MGdensity, node2%MGdensity, & - elements(I)%PropPot, filledFlag, elements(I)%FillDens, elements(I)%FillFSLoc, & - mass_fill, Cd1, Ca1, Cp1, AxCa1, AxCp1, JAxCd1, JAxCa1, JAxCp1, & - Cd2, Ca2, Cp2, AxCa2, AxCp2, JAxCd2, JAxCa2, JAxCp2 - - END DO ! I = 1,numElements + write( UnSum, '(1X,I8,2X,I6,2X,I6,2X,ES12.5,2X,I12, 6(2X,ES12.5),2(2X,L12),21(2X,ES12.5))' ) members(i)%MemberID, & + members(i)%NodeIndx(1), members(i)%NodeIndx(N+1), members(i)%RefLength, N, & + memberVol, MGvolume, members(i)%Rmg(1), members(i)%Rmg(1)-members(i)%Rin(1), & + members(i)%Rmg(N+1), members(i)%Rmg(N+1)-members(i)%Rin(N+1), & + members(i)%PropPot, filledFlag, members(i)%FillDens, members(i)%FillFSLoc, & + mass_fill, Cd1, Ca1, Cp1, AxCd1, AxCa1, AxCp1, JAxCd1, JAxCa1, JAxCp1, & + Cd2, Ca2, Cp2, AxCd2, AxCa2, AxCp2, JAxCd2, JAxCa2, JAxCp2 + + end do ! i = 1,numMembers WRITE( UnSum, '(//)' ) WRITE( UnSum, '(A24)' ) 'Requested Member Outputs' WRITE( UnSum, '(/)' ) - WRITE( UnSum, '(1X,A10,11(2X,A10))' ) ' Label ', ' Xi ', ' Yi ', ' Zi ', 'InpMbrIndx', ' StartXi ', ' StartYi ', ' StartZi ', ' EndXi ', ' EndYi ', ' EndZi ', ' Loc ' + WRITE( UnSum, '(1X,A10,11(2X,A10))' ) ' Label ', ' Xi ', ' Yi ', ' Zi ', ' MemberID ', ' StartXi ', ' StartYi ', ' StartZi ', ' EndXi ', ' EndYi ', ' EndZi ', ' Loc ' WRITE( UnSum, '(1X,A10,11(2X,A10))' ) ' (-) ', ' (m) ', ' (m) ', ' (m) ', ' (-) ', ' (m) ', ' (m) ', ' (m) ', ' (m) ', ' (m) ', ' (m) ', ' (-) ' DO I = 1,NOutputs - ! DO J=1, NMOutputs - !DO I=1, MOutLst(J)%NOutLoc - - - ! Get the member index and node index for this output label. If this is not a member output the indices will return 0 with no errcode. - ! CALL MrsnOut_GetMemberOutputInfo(WriteOutputHdr(I), NMOutputs, MOutLst, mbrIndx, nodeIndx, ErrStat, ErrMsg ) - ! IF (ErrStat >= AbortErrLev ) RETURN - ! IF ( mbrIndx > 0 ) THEN + tmpName = OutParam(I)%Name IF (OutParam(I)%SignM == -1 ) tmpName = tmpName(2:10) @@ -1522,24 +885,20 @@ SUBROUTINE WriteSummaryFile( UnSum, MSL2SWL, WtrDpth, numNodes, nodes, numElemen read (tmpName(2:2),*) mbrIndx read (tmpName(4:4),*) nodeIndx - ! These indices are in the DistribMesh index system, not the overal nodes index system, so distribToNodeIndx() mapping needs to be performed if you want - ! to index into the nodes array or wave kinematics arrays - - m1 = MOutLst(mbrIndx)%Marker1(nodeIndx) - m2 = MOutLst(mbrIndx)%Marker2(nodeIndx) - s = MOutLst(mbrIndx)%s (nodeIndx) - + + + s = MOutLst(mbrIndx)%NodeLocs(nodeIndx) + ! Find the member starting and ending node locations ! The member output is computed as a linear interpolation of the nearest two markers - node1 = nodes(distribToNodeIndx((m1))) - node2 = nodes(distribToNodeIndx((m2))) + mem = members(MOutLst(mbrIndx)%MemberIDIndx) + node1 = nodes(mem%NodeIndx(1)) + node2 = nodes(mem%NodeIndx(mem%NElements+1)) + + outLoc = node1%Position*(1-s) + node2%Position*s - outLoc = node1%JointPos*(1-s) + node2%JointPos*s - WRITE( UnSum, '(1X,A10,3(2x,F10.4),2x,I10,7(2x,F10.4))' ) OutParam(I)%Name, outLoc, node1%InpMbrIndx, node1%JointPos, node2%JointPos, s + WRITE( UnSum, '(1X,A10,3(2x,F10.4),2x,I10,7(2x,F10.4))' ) OutParam(I)%Name, outLoc, MOutLst(mbrIndx)%MemberID, node1%Position, node2%Position, s END IF - - ! END IF - !WRITE( UnSum, '(1X,A10,11(2X,ES10.3))' ) WriteOutputHdr(I) - ! END DO + END DO @@ -1551,14 +910,6 @@ SUBROUTINE WriteSummaryFile( UnSum, MSL2SWL, WtrDpth, numNodes, nodes, numElemen DO I = 1,NOutputs - ! DO J=1, NMOutputs - !DO I=1, MOutLst(J)%NOutLoc - - - ! Get the member index and node index for this output label. If this is not a member output the indices will return 0 with no errcode. - ! CALL MrsnOut_GetMemberOutputInfo(WriteOutputHdr(I), NMOutputs, MOutLst, mbrIndx, nodeIndx, ErrStat, ErrMsg ) - ! IF (ErrStat >= AbortErrLev ) RETURN - ! IF ( mbrIndx > 0 ) THEN tmpName = OutParam(I)%Name IF (OutParam(I)%SignM == -1 ) tmpName = tmpName(2:10) @@ -1566,496 +917,129 @@ SUBROUTINE WriteSummaryFile( UnSum, MSL2SWL, WtrDpth, numNodes, nodes, numElemen !Get Member index and Node index read (tmpName(2:2),*) nodeIndx - m1 = JOutLst(nodeIndx)%Markers(1) - WRITE( UnSum, '(1X,A10,3(2x,F10.4),2x,I10)' ) OutParam(I)%Name, nodes(m1)%JointPos, JOutLst(nodeIndx)%JointID + m1 = JOutLst(nodeIndx)%JointIDIndx + WRITE( UnSum, '(1X,A10,3(2x,F10.4),2x,I10)' ) OutParam(I)%Name, nodes(m1)%Position, JOutLst(nodeIndx)%JointID END IF - ! END IF - !WRITE( UnSum, '(1X,A10,11(2X,ES10.3))' ) WriteOutputHdr(I) - ! END DO + END DO + END IF END SUBROUTINE WriteSummaryFile -!==================================================================================================== -SUBROUTINE SplitElementOnZBoundary( axis, boundary, iCurrentElement, numNodes, numElements, node1, node2, originalElement, newNode, newElement, ErrStat, ErrMsg ) - !@mhall: This splits an element at a given global x, y, or z location? - - INTEGER, INTENT ( IN ) :: axis !@mhall: which axis to work with in calculating positions along element (global x,y, or z)? - REAL(ReKi), INTENT ( IN ) :: boundary !@mhall: [axis] coordinate of boundary? - INTEGER, INTENT ( IN ) :: iCurrentElement - INTEGER, INTENT ( INOUT ) :: numNodes - TYPE(Morison_NodeType), INTENT ( INOUT ) :: node1, node2 !@mhall: element end nodes? - INTEGER, INTENT ( INOUT ) :: numElements - TYPE(Morison_MemberType), INTENT ( INOUT ) :: originalElement - TYPE(Morison_NodeType), INTENT ( OUT ) :: newNode - TYPE(Morison_MemberType), INTENT ( OUT ) :: newElement - INTEGER, INTENT ( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT ( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - INTEGER :: I, J - REAL(ReKi) :: s - INTEGER :: newNodeIndx, newElementIndx - - ErrStat = ErrID_None - ErrMsg = "" - - ! Create new node and element indices - newNodeIndx = numNodes + 1 - newElementIndx = numElements + 1 - - ! find normalized distance from 1nd node to the boundary - CALL FindInterpFactor( boundary, node1%JointPos(axis), node2%JointPos(axis), s ) - newNode = node1 ! copy all base node properties - - newNode%JointPos(axis) = boundary !@mhall: set [axis] coordinate of new node based on provided input [boundary] - - !@mthall: set other two coordinates of new node based on interpolation of original end node coordinates - DO I=axis,axis+1 - J = MOD(I,3) + 1 - newNode%JointPos(J) = node1%JointPos(J)*(1-s) + node2%JointPos(J)*s - END DO - - newNode%R_LToG = node1%R_LToG - ! Create the new node information. - ! Note that the caller will determine if this is an interior node (subdivide) or an endnode (split due to MG, MSL, seabed, filled free surface) - newNode%JointOvrlp = 0 - newNode%NConnections = 2 - newNode%ConnectionList(1) = iCurrentElement - newNode%ConnectionList(2) = newElementIndx - - + - ! Update node2 connectivity - DO I = 1,10 ! 10 is the maximum number of connecting elements for a node, this should probably be a parameter !! TODO - IF ( node2%ConnectionList(I) == iCurrentElement ) THEN - node2%ConnectionList(I) = newElementIndx - EXIT - END IF - END DO - - - ! Create the new element properties by first copying all the properties from the existing element - newElement = originalElement - ! Linearly interpolate the coef values based on depth - originalElement%R2 = originalElement%R1 * (1-s) + originalElement%R2*s - newElement%R1 = originalElement%R2 - originalElement%t2 = originalElement%t1 * (1-s) + originalElement%t2*s - originalElement%InpMbrDist2 = originalElement%InpMbrDist1 * (1-s) + originalElement%InpMbrDist2*s - newElement%t1 = originalElement%t2 - newElement%InpMbrDist1 = originalElement%InpMbrDist2 - - ! The end point of the new element is set to the original end point of the existing element, then - ! the starting point of the new element and the ending point of the existing element are set to the - ! newly created node - newElement%Node2Indx = originalElement%Node2Indx - originalElement%Node2Indx = newNodeIndx - newElement%Node1Indx = newNodeIndx - -END SUBROUTINE SplitElementOnZBoundary - - -!==================================================================================================== -!SUBROUTINE SplitElementsForMG(MGTop, MGBottom, numNodes, nodes, numElements, elements, ErrStat, ErrMsg) -! -! REAL(ReKi), INTENT ( IN ) :: MGTop -! REAL(ReKi), INTENT ( IN ) :: MGBottom -! INTEGER, INTENT ( INOUT ) :: numNodes -! TYPE(Morison_NodeType), INTENT ( INOUT ) :: nodes(:) -! INTEGER, INTENT ( INOUT ) :: numElements -! TYPE(Morison_MemberType), INTENT ( INOUT ) :: elements(:) -! INTEGER, INTENT ( OUT ) :: ErrStat ! returns a non-zero value when an error occurs -! CHARACTER(*), INTENT ( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None -! -! INTEGER :: I, J, K -! INTEGER :: node1Indx, node2Indx -! TYPE(Morison_NodeType) :: node1, node2, newNode, newNode2 -! TYPE(Morison_MemberType) :: element, newElement, newElement2 -! REAL(ReKi) :: zBoundary -! INTEGER :: origNumElements -! -! origNumElements = numElements -! -! DO I=1,origNumElements -! -! IF ( elements(I)%MGSplitState > 0 ) THEN -! -! node1Indx = elements(I)%Node1Indx -! node1 = nodes(node1Indx) -! node2Indx = elements(I)%Node2Indx -! node2 = nodes(node2Indx) -! element = elements(I) -! -! ! Intersects top boundary -! IF ( elements(I)%MGSplitState == 1 ) THEN -! zBoundary = MGTop -! ELSE ! Intersects the bottom boundary -! zBoundary = MGBottom -! END IF -! -! -! CALL SplitElementOnZBoundary( zBoundary, I, numNodes, numElements, node1, node2, element, newNode, newElement, ErrStat, ErrMsg ) -! newNode%NodeType = 1 ! end node -! ! Update the number of nodes and elements by one each -! numNodes = numNodes + 1 -! newNode%JointIndx = numNodes -! numElements = numElements + 1 -! -! ! Copy the altered nodes and elements into the master arrays -! nodes(node1Indx) = node1 -! nodes(node2Indx) = node2 -! nodes(numNodes) = newNode -! elements(I) = element -! elements(numElements) = newElement -! -! ! If the original element spanned both marine growth boundaries, then we need to make an additional split -! IF ( elements(I)%MGSplitState == 3 ) THEN -! -! CALL SplitElementOnZBoundary( MGTop, numElements, numNodes, numElements, newNode, node2, newElement, newNode2, newElement2, ErrStat, ErrMsg ) -! newNode2%NodeType = 1 ! end node -! newNode2%JointIndx = numNodes + 1 -! ! Copy the altered nodes and elements into the master arrays -! nodes(numNodes) = newNode -! nodes(node2Indx) = node2 -! nodes(numNodes+1) = newNode2 -! elements(numElements) = newElement -! elements(numElements+1) = newElement2 -! -! ! Update the number of nodes and elements by one each -! numNodes = numNodes + 1 -! -! numElements = numElements + 1 -! -! END IF -! END IF -! END DO -!END SUBROUTINE SplitElementsForMG - -SUBROUTINE SplitElements(numNodes, nodes, numElements, elements, ErrStat, ErrMsg) - ! This splits all of the Morison elements according to already defined split locations, - ! adding resuling new nodes and elements to the respective master arrays. - - INTEGER, INTENT ( INOUT ) :: numNodes - TYPE(Morison_NodeType), INTENT ( INOUT ) :: nodes(:) - INTEGER, INTENT ( INOUT ) :: numElements - TYPE(Morison_MemberType), INTENT ( INOUT ) :: elements(:) - INTEGER, INTENT ( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT ( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - INTEGER :: I, J, iCurrent, nSplits !, K - REAL(ReKi) :: splits(5) - INTEGER :: node1Indx, node2Indx - TYPE(Morison_NodeType) :: node1, node2, newNode !, newNode2 - TYPE(Morison_MemberType) :: element, newElement !, newElement2 - REAL(ReKi) :: zBoundary - INTEGER :: origNumElements - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - +subroutine Morison_GenerateSimulationNodes( MSL2SWL, numJoints, inpJoints, numMembers, inpMembers, numNodes, nodes, errStat, errMsg ) + ! This subdivides a Morison member according to its maximum desired + ! element length (MDivSize), allocating the member's arrays, and + ! adding resuling new nodes to the master node array. + real(ReKi), intent (in ) :: MSL2SWL ! mean sea level To still water level offset value + integer, intent (in ) :: numJoints ! number of joints in the input file + type(Morison_JointType), intent (in ) :: inpJoints(:) ! array of input joint data structures + integer, intent (in ) :: numMembers ! number of members specified in the inputs + type(Morison_MemberInputType), intent (inout) :: inpMembers(:) ! array of input member data structures + integer, intent (inout) :: numNodes ! the total number of nodes being used for the simulation model + type(Morison_NodeType), allocatable, intent (inout) :: nodes(:) ! the array of simulation nodes + integer, intent ( out) :: errStat ! returns a non-zero value when an error occurs + character(*), intent ( out) :: errMsg ! Error message if errStat /= ErrID_None + + + integer :: numDiv, maxNodes + integer :: i, j + real(ReKi) :: s ! interpolation factor + real(ReKi) :: memLength ! member length + integer :: j1, j2 ! generic integer for counting + INTEGER(IntKi) :: errStat2 ! Error status of the operation (occurs after initial error) + CHARACTER(errMsgLen) :: errMsg2 ! Error message if errStat2 /= ErrID_None + + ! Initialize errStat + + errStat = ErrID_None + errMsg = "" - origNumElements = numElements + ! Initialize quantities + maxNodes = numJoints - DO I=1,origNumElements - - IF ( elements(I)%NumSplits > 0 ) THEN - - - ! The splits are presorted from smallest Z to largest Z - nSplits = elements(I)%NumSplits - splits = elements(I)%Splits - iCurrent = I - - DO J=1,nSplits - - node1Indx = elements(iCurrent)%Node1Indx - node1 = nodes(node1Indx) - node2Indx = elements(iCurrent)%Node2Indx - node2 = nodes(node2Indx) - element = elements(iCurrent) - - CALL SplitElementOnZBoundary( 3, splits(J), iCurrent, numNodes, numElements, node1, node2, element, newNode, newElement, ErrStat, ErrMsg ) - - ! Was this split due to the location of an elements free surface location crossing through the element? - IF ( element%MmbrFilledIDIndx /= -1 ) THEN - IF ( EqualRealNos(element%FillFSLoc, splits(J)) ) THEN - newElement%MmbrFilledIDIndx = -1 - END IF - END IF - - newNode%NodeType = 1 ! end node - ! Update the number of nodes and elements by one each - numNodes = numNodes + 1 - newNode%JointIndx = numNodes - numElements = numElements + 1 - - ! Copy the altered nodes and elements into the master arrays - !nodes(node1Indx) = node1 - nodes(node2Indx) = node2 - nodes(numNodes) = newNode - elements(iCurrent) = element - elements(numElements) = newElement - - - - ! now make element = newElement by setting iCurrent to numElements - iCurrent = numElements - - - END DO + ! Determine maximum nodes in simulation mesh due to internal member subdivision + do i = 1,numMembers + + j1 = inpMembers(I)%MJointID1Indx + j2 = inpMembers(I)%MJointID2Indx + call GetDistance(inpJoints(j1)%Position, inpJoints(j2)%Position, memLength) + if ( EqualRealNos(memLength, 0.0_ReKi) )then + errMsg = ' Input file member with ID: '//trim(num2lstr(inpMembers(i)%MemberID))//' must have length greater than zero.' + errStat = ErrID_Fatal + return + end if + numDiv = CEILING( memLength / inpMembers(i)%MDivSize ) + ! set number of elements in member and element size + inpMembers(i)%NElements = numDiv + inpMembers(i)%dl = memLength/numDiv + inpMembers(i)%refLength = memLength + maxNodes = maxNodes + numDiv - 1 + + end do + + ! Allocate nodes array + allocate ( nodes(maxNodes), STAT = errStat ) + if ( errStat /= 0 ) then + errMsg = ' Error allocating space for Nodes array for Morison Module.' + errStat = ErrID_Fatal + return + end if - END IF - END DO -END SUBROUTINE SplitElements - -!==================================================================================================== -!SUBROUTINE SplitElementsForWtr(MSL2SWL, Zseabed, numNodes, nodes, numElements, elements, ErrStat, ErrMsg) -! -! REAL(ReKi), INTENT ( IN ) :: MSL2SWL -! REAL(ReKi), INTENT ( IN ) :: Zseabed -! INTEGER, INTENT ( INOUT ) :: numNodes -! TYPE(Morison_NodeType), INTENT ( INOUT ) :: nodes(:) -! INTEGER, INTENT ( INOUT ) :: numElements -! TYPE(Morison_MemberType), INTENT ( INOUT ) :: elements(:) -! INTEGER, INTENT ( OUT ) :: ErrStat ! returns a non-zero value when an error occurs -! CHARACTER(*), INTENT ( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None -! -! INTEGER :: I, J, K -! INTEGER :: node1Indx, node2Indx -! TYPE(Morison_NodeType) :: node1, node2, newNode, newNode2 -! TYPE(Morison_MemberType) :: element, newElement, newElement2 -! REAL(ReKi) :: zBoundary -! INTEGER :: origNumElements -! -! origNumElements = numElements -! -! DO I=1,origNumElements -! -! IF ( elements(I)%WtrSplitState > 0 ) THEN -! -! node1Indx = elements(I)%Node1Indx -! node1 = nodes(node1Indx) -! node2Indx = elements(I)%Node2Indx -! node2 = nodes(node2Indx) -! element = elements(I) -! -! ! Intersects top boundary -! IF ( elements(I)%WtrSplitState == 1 ) THEN -! zBoundary = MSL2SWL -! ELSE ! Intersects the bottom boundary -! zBoundary = Zseabed -! END IF -! -! -! CALL SplitElementOnZBoundary( zBoundary, I, numNodes, numElements, node1, node2, element, newNode, newElement, ErrStat, ErrMsg ) -! newNode%NodeType = 1 ! end node -! ! Update the number of nodes and elements by one each -! numNodes = numNodes + 1 -! newNode%JointIndx = numNodes -! numElements = numElements + 1 -! -! ! Copy the altered nodes and elements into the master arrays -! nodes(node1Indx) = node1 -! nodes(node2Indx) = node2 -! nodes(numNodes) = newNode -! elements(I) = element -! elements(numElements) = newElement -! -! ! If the original element spanned both marine growth boundaries, then we need to make an additional split -! IF ( elements(I)%WtrSplitState == 3 ) THEN -! -! CALL SplitElementOnZBoundary( MSL2SWL, numElements, numNodes, numElements, newNode, node2, newElement, newNode2, newElement2, ErrStat, ErrMsg ) -! newNode2%NodeType = 1 ! end node -! newNode2%JointIndx = numNodes + 1 -! ! Copy the altered nodes and elements into the master arrays -! nodes(numNodes) = newNode -! nodes(node2Indx) = node2 -! nodes(numNodes+1) = newNode2 -! elements(numElements) = newElement -! elements(numElements+1) = newElement2 -! -! ! Update the number of nodes and elements by one each -! numNodes = numNodes + 1 -! -! numElements = numElements + 1 -! -! END IF -! END IF -! END DO -!END SUBROUTINE SplitElementsForWtr -!==================================================================================================== -SUBROUTINE SubdivideMembers( numNodes, nodes, numElements, elements, ErrStat, ErrMsg ) - ! This subdivides all of the (already-split) Morison elements according to each element's maximum desired - ! element length (MDivSize), adding resuling new nodes and elements to the respective master arrays. - - INTEGER, INTENT ( INOUT ) :: numNodes - TYPE(Morison_NodeType), INTENT ( INOUT ) :: nodes(:) - INTEGER, INTENT ( INOUT ) :: numElements - TYPE(Morison_MemberType), INTENT ( INOUT ) :: elements(:) - INTEGER, INTENT ( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT ( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - TYPE(Morison_NodeType) :: node1, node2, newNode - TYPE(Morison_MemberType) :: element, newElement - INTEGER :: numDiv - REAL(ReKi) :: divSize(3) - INTEGER :: I, J, K - REAL(ReKi) :: memLen ! Length of member [m] - INTEGER :: origNumElements - INTEGER :: node1Indx, node2Indx, elementIndx, axis - REAL(ReKi) :: start, Loc - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - + ! Loop over the input file joints and add there positions as the node positions at the beginning of the nodes array + do i = 1, numJoints + nodes(i)%Position(1:2) = inpJoints(i)%Position(1:2) + nodes(i)%Position(3) = inpJoints(i)%Position(3) - MSL2SWL ! Correct the Z-coordinate based on the mean sea level To still water level offset value + end do + + numNodes = numJoints + ! Now loop over the input file members and create necessary internal nodes and add them to the nodes array + ! Also augment the input file members data with the new discretization information + do i = 1,numMembers + call AllocAry(inpMembers(i)%NodeIndx, inpMembers(i)%NElements+1, 'inpMembers(i)%NodeIndx', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Morison_GenerateSimulationNodes') + if (errStat >= AbortErrLev) return + + j1 = inpMembers(i)%MJointID1Indx + j2 = inpMembers(i)%MJointID2Indx + numDiv = inpMembers(i)%NElements + inpMembers(i)%NodeIndx(1) = j1 + inpMembers(i)%NodeIndx(1+numDiv) = j2 + ! If the requested division size is less then the member length, create nodes along the member + if (numDiv > 1 ) THEN + ! loop through the new node locations along the member and add a node at each + do j = 1, numDiv-1 + numNodes = numNodes + 1 + s = real(j, ReKi) / real(numDiv, ReKi) + nodes(numNodes)%Position = inpJoints(j1)%Position*(1-s) + inpJoints(j2)%Position*s + nodes(numNodes)%Position(3) = nodes(numNodes)%Position(3) - MSL2SWL ! Correct the Z-coordinate based on the mean sea level To still water level offset value + inpMembers(i)%NodeIndx(j+1) = numNodes + end do + end if + end do +end subroutine Morison_GenerateSimulationNodes - origNumElements = numElements - DO I=1,origNumElements - - CALL Morison_CopyMemberType( elements(I), element, MESH_NEWCOPY, ErrStat, ErrMsg ) ! element = elements(I); bjj: I'm replacing the "equals" here with the copy routine, - ! though at this point there are no allocatable/pointer fields in this type so no harm done. - ! mostly for me to remember that when Inspector complains about uninitialized values, it's - ! because not all *fields* have been initialized. - node1Indx = element%Node1Indx - CALL Morison_CopyNodeType( nodes(node1Indx), node1, MESH_NEWCOPY, ErrStat, ErrMsg ) ! node1 = nodes(node1Indx); bjj: note that not all fields have been initialized, but maybe that's okay. - - node2Indx = element%Node2Indx ! We need this index for the last sub-element - CALL Morison_CopyNodeType( nodes(node2Indx), node2, MESH_NEWCOPY, ErrStat, ErrMsg ) ! node2 = nodes(node2Indx); bjj: note that not all fields have been initialized, but maybe that's okay. - - elementIndx = I - - - CALL GetDistance(node1%JointPos, node2%JointPos, memLen) ! Calculate member length. - - - ! If the requested division size is less then the member length, we will subdivide the member - - IF ( element%MDivSize < memLen ) THEN - - ! Ensure a safe choice of x/y/z axis to use for splitting. - IF ( .NOT. ( EqualRealNos( node2%JointPos(3) , node1%JointPos(3) ) ) ) THEN - axis = 3 - ELSE IF ( .NOT. ( EqualRealNos( node2%JointPos(2) , node1%JointPos(2) ) ) ) THEN - axis = 2 - ELSE IF ( .NOT. ( EqualRealNos( node2%JointPos(1) , node1%JointPos(1) ) ) ) THEN - axis = 1 - ELSE - ! ERROR - END IF - - start = node1%JointPos(axis) - numDiv = CEILING( memLen / element%MDivSize ) - - DO K=1,3 - divSize(K) = (node2%JointPos(K) - node1%JointPos(K)) / numDiv - END DO - - DO J=1,numDiv - 1 - - loc = start + divSize(axis)*J - CALL SplitElementOnZBoundary( axis, loc, elementIndx, numNodes, numElements, node1, node2, element, newNode, newElement, ErrStat, ErrMsg ) - newNode%NodeType = 2 ! interior node - newNode%JointIndx = -1 - ! Copy updated node and element information to the nodes and elements arrays - nodes(node1Indx) = node1 ! this is copying all the fields in the type; type contains no allocatable arrays or pointers - nodes(node2Indx) = node2 ! this is copying all the fields in the type; type contains no allocatable arrays or pointers - numNodes = numNodes + 1 - numElements = numElements + 1 - nodes(numNodes) = newNode ! this is copying all the fields in the type; type contains no allocatable arrays or pointers - elements(elementIndx) = element ! this is copying all the fields in the type; type contains no allocatable arrays or pointers - elements(numElements) = newElement ! this is copying all the fields in the type; type contains no allocatable arrays or pointers - - node1 = newNode ! this is copying all the fields in the type; type contains no allocatable arrays or pointers - element = newElement ! this is copying all the fields in the type; type contains no allocatable arrays or pointers - node1Indx = numNodes - elementIndx = numElements - - - - - - ! Create a new node - !newNode = node2 - ! - !DO K=1,3 - ! newNode%JointPos = node1%JointPos(K) + divSize(K)*J - !END DO - ! - !numNodes = numNodes + 1 - !element%Node2Indx = numNodes - !nodes(numNodes) = newNode - ! - ! ! Create a new element - !newElement = element - !newElement%Node1Indx = numNodes - !element = newElement - !numElements = numElements + 1 - END DO - - !element%Node2Indx = node2Indx - - END IF - - END DO - - -END SUBROUTINE SubdivideMembers - -SUBROUTINE CreateSuperMembers( ) - - - - ! Determine if any of the joints flagged for overlap elimination (super member creation) satisfy the necessary requirements - !IF ( InitInp%NJoints > 0 ) THEN - ! - ! DO I = 1,InitInp%NJoints - ! - ! ! Check #1 are there more than 2 members connected to the joint? - ! IF ( InitInp%InpJoints(I)%JointOvrlp == 1 .AND. InitInp%InpJoints(I)%NConnections > 2) THEN - ! ! Check #2 are there two members whose local z-axis are the same? - ! CALL Get180Members(joint, InitInp%Joints, InitInp%Members, member1, member2) - ! - ! !zVect1 - ! !zVect2 - ! !dot(zVect1, zVect2) - ! - ! END IF - ! - ! - ! END DO - ! - ! - !END IF - - -END SUBROUTINE CreateSuperMembers !==================================================================================================== -SUBROUTINE SetDepthBasedCoefs( z, NCoefDpth, CoefDpths, Cd, CdMG, Ca, CaMG, Cp, CpMG, AxCa, AxCaMG, AxCp, AxCpMG ) +SUBROUTINE SetDepthBasedCoefs( z, tMG, NCoefDpth, CoefDpths, Cd, Ca, Cp, AxCd, AxCa, AxCp ) - REAL(ReKi), INTENT ( IN ) :: z - INTEGER, INTENT (IN ) :: NCoefDpth - TYPE(Morison_CoefDpths), INTENT (IN ) :: CoefDpths(:) + REAL(ReKi), INTENT (IN ) :: z + REAL(ReKi), INTENT (IN ) :: tMG + INTEGER, INTENT (IN ) :: NCoefDpth + TYPE(Morison_CoefDpths), INTENT (IN ):: CoefDpths(:) REAL(ReKi), INTENT ( OUT) :: Cd - REAL(ReKi), INTENT ( OUT) :: CdMG REAL(ReKi), INTENT ( OUT) :: Ca - REAL(ReKi), INTENT ( OUT) :: CaMG REAL(ReKi), INTENT ( OUT) :: Cp - REAL(ReKi), INTENT ( OUT) :: CpMG + REAL(ReKi), INTENT ( OUT) :: AxCd REAL(ReKi), INTENT ( OUT) :: AxCa - REAL(ReKi), INTENT ( OUT) :: AxCaMG REAL(ReKi), INTENT ( OUT) :: AxCp - REAL(ReKi), INTENT ( OUT) :: AxCpMG INTEGER :: I, indx1, indx2 REAL(ReKi) :: dd, s @@ -2070,6 +1054,8 @@ SUBROUTINE SetDepthBasedCoefs( z, NCoefDpth, CoefDpths, Cd, CdMG, Ca, CaMG, Cp, indx1 = 1 indx2 = 1 + if (NCoefDpth == 0) return + DO I = 1, NCoefDpth IF ( CoefDpths(I)%Dpth <= z .AND. .NOT. foundLess ) THEN indx1 = I @@ -2090,319 +1076,131 @@ SUBROUTINE SetDepthBasedCoefs( z, NCoefDpth, CoefDpths, Cd, CdMG, Ca, CaMG, Cp, ELSE s = ( CoefDpths(indx1)%Dpth - z ) / dd END IF + if ( tMG > 0.0_ReKi ) then + Cd = CoefDpths(indx1)%DpthCdMG*(1-s) + CoefDpths(indx2)%DpthCdMG*s + Ca = CoefDpths(indx1)%DpthCaMG*(1-s) + CoefDpths(indx2)%DpthCaMG*s + Cp = CoefDpths(indx1)%DpthCpMG*(1-s) + CoefDpths(indx2)%DpthCpMG*s + AxCd = CoefDpths(indx1)%DpthAxCdMG*(1-s) + CoefDpths(indx2)%DpthAxCdMG*s + AxCa = CoefDpths(indx1)%DpthAxCaMG*(1-s) + CoefDpths(indx2)%DpthAxCaMG*s + AxCp = CoefDpths(indx1)%DpthAxCpMG*(1-s) + CoefDpths(indx2)%DpthAxCpMG*s + else + Cd = CoefDpths(indx1)%DpthCd*(1-s) + CoefDpths(indx2)%DpthCd*s + Ca = CoefDpths(indx1)%DpthCa*(1-s) + CoefDpths(indx2)%DpthCa*s + Cp = CoefDpths(indx1)%DpthCp*(1-s) + CoefDpths(indx2)%DpthCp*s + AxCd = CoefDpths(indx1)%DpthCd*(1-s) + CoefDpths(indx2)%DpthAxCd*s + AxCa = CoefDpths(indx1)%DpthCa*(1-s) + CoefDpths(indx2)%DpthAxCa*s + AxCp = CoefDpths(indx1)%DpthCp*(1-s) + CoefDpths(indx2)%DpthAxCp*s + end if - Cd = CoefDpths(indx1)%DpthCd*(1-s) + CoefDpths(indx2)%DpthCd*s - Ca = CoefDpths(indx1)%DpthCa*(1-s) + CoefDpths(indx2)%DpthCa*s - Cp = CoefDpths(indx1)%DpthCp*(1-s) + CoefDpths(indx2)%DpthCp*s - AxCa = CoefDpths(indx1)%DpthCa*(1-s) + CoefDpths(indx2)%DpthAxCa*s - AxCp = CoefDpths(indx1)%DpthCp*(1-s) + CoefDpths(indx2)%DpthAxCp*s - CdMG = CoefDpths(indx1)%DpthCdMG*(1-s) + CoefDpths(indx2)%DpthCdMG*s - CaMG = CoefDpths(indx1)%DpthCaMG*(1-s) + CoefDpths(indx2)%DpthCaMG*s - CpMG = CoefDpths(indx1)%DpthCpMG*(1-s) + CoefDpths(indx2)%DpthCpMG*s - AxCaMG = CoefDpths(indx1)%DpthAxCaMG*(1-s) + CoefDpths(indx2)%DpthAxCaMG*s - AxCpMG = CoefDpths(indx1)%DpthAxCpMG*(1-s) + CoefDpths(indx2)%DpthAxCpMG*s END SUBROUTINE SetDepthBasedCoefs -!==================================================================================================== -SUBROUTINE SetSplitNodeProperties( numNodes, nodes, numElements, elements, ErrStat, ErrMsg ) -! This private subroutine generates the properties of nodes after the mesh has been split -! the input data. -!---------------------------------------------------------------------------------------------------- - - INTEGER, INTENT ( IN ) :: numNodes - INTEGER, INTENT ( IN ) :: numElements - TYPE(Morison_MemberType), INTENT ( INOUT ) :: elements(:) - TYPE(Morison_NodeType), INTENT ( INOUT ) :: nodes(:) - INTEGER, INTENT ( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT ( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - - INTEGER :: I - TYPE(Morison_MemberType) :: element - REAL(ReKi) :: dR, dz -! REAL(ReKi) :: DirCos(3,3) - - ErrStat = ErrID_None - ErrMsg = "" - - - DO I=1,numNodes - - IF ( nodes(I)%NodeType /= 3 ) THEN - - ! End point or internal member node - ! Super member nodes already have their properties set - - - !element = elements(nodes(I)%ConnectionList(1)) - - ! Calculate the element-level direction cosine matrix and attach it to the entry in the elements array - - ! CALL Morison_DirCosMtrx( nodes(element%Node1Indx)%JointPos, nodes(element%Node2Indx)%JointPos, elements(nodes(I)%ConnectionList(1))%R_LToG ) - - element = elements(nodes(I)%ConnectionList(1)) - - nodes(I)%R_LToG = element%R_LToG - - nodes(I)%InpMbrIndx = element%InpMbrIndx - IF ( .NOT. ( ( nodes(element%Node1Indx)%tMG > 0 ) .AND. ( nodes(element%Node2Indx)%tMG > 0 ) .AND. (.NOT. element%PropPot) ) ) THEN - nodes(element%Node1Indx)%tMG = 0.0 - nodes(element%Node2Indx)%tMG = 0.0 - nodes(element%Node1Indx)%MGdensity = 0.0 - nodes(element%Node2Indx)%MGdensity = 0.0 - END IF - - !@mhall: if this node is Node 1 of the element in question... ? - IF ( element%Node1Indx == I ) THEN - - IF ( nodes(I)%tMG > 0 ) THEN - nodes(I)%Cd = element%CdMG1 - nodes(I)%Ca = element%CaMG1 - nodes(I)%Cp = element%CpMG1 - nodes(I)%AxCa = element%AxCaMG1 - nodes(I)%AxCp = element%AxCpMG1 - ELSE - nodes(I)%Cd = element%Cd1 - nodes(I)%Ca = element%Ca1 - nodes(I)%Cp = element%Cp1 - nodes(I)%AxCa = element%AxCa1 - nodes(I)%AxCp = element%AxCp1 - END IF - - nodes(I)%R = element%R1 - nodes(I)%t = element%t1 - nodes(I)%InpMbrDist = element%InpMbrDist1 - - !@mhall: otherwise this must be Node 2 of the element in question? - ELSE - - IF ( nodes(I)%tMG > 0 ) THEN - nodes(I)%Cd = element%CdMG2 - nodes(I)%Ca = element%CaMG2 - nodes(I)%Cp = element%CpMG2 - nodes(I)%AxCa = element%AxCaMG2 - nodes(I)%AxCp = element%AxCpMG2 - ELSE - nodes(I)%Cd = element%Cd2 - nodes(I)%Ca = element%Ca2 - nodes(I)%Cp = element%Cp2 - nodes(I)%AxCa = element%AxCa2 - nodes(I)%AxCp = element%AxCp2 - END IF - - nodes(I)%R = element%R2 - nodes(I)%t = element%t2 - nodes(I)%InpMbrDist = element%InpMbrDist2 - END IF - - CALL GetDistance( nodes(element%Node1Indx)%JointPos, nodes(element%Node2Indx)%JointPos, dz ) - dR = ( element%R2 + nodes(element%Node2Indx)%tMG ) - ( element%R1 + nodes(element%Node1Indx)%tMG ) - IF ( EqualRealNos(dR, 0.0_ReKi) ) dR = 0.0 - IF ( EqualRealNos(dz, 0.0_ReKi) ) THEN - nodes(I)%dRdz = 0.0 - ELSE - nodes(I)%dRdz = dR / dz - END IF - - nodes(I)%PropPot = element%PropPot - - IF ( element%MmbrFilledIDIndx /= -1 ) THEN - nodes(I)%FillFlag = .TRUE. - nodes(I)%FillFSLoc = element%FillFSLoc ! This is relative to the MSL. - nodes(I)%FillDensity = element%FillDens - - ELSE - nodes(I)%FillFSLoc = 0.0 ! This is the MSL. - nodes(I)%FillDensity = 0.0 - elements(nodes(I)%ConnectionList(1))%FillDens = 0.0 - elements(nodes(I)%ConnectionList(1))%FillFSLoc = 0.0 - END IF - - - - - END IF - -END DO - -END SUBROUTINE SetSplitNodeProperties - !==================================================================================================== -!SUBROUTINE SetMemberCoefs( SimplCd, SimplCdMG, SimplCa, SimplCaMG, CoefMembers, NCoefDpth, CoefDpths, element, node1, node2 ) -SUBROUTINE SetElementCoefs( SimplCd, SimplCdMG, SimplCa, SimplCaMG, SimplCp, SimplCpMG, SimplAxCa, SimplAxCaMG, SimplAxCp, SimplAxCpMG,CoefMembers, NCoefDpth, CoefDpths, numNodes, nodes, numElements, elements ) +!SUBROUTINE SetExternalHydroCoefs +SUBROUTINE SetExternalHydroCoefs( MCoefMod, MmbrCoefIDIndx, SimplCd, SimplCdMG, SimplCa, SimplCaMG, SimplCp, & + SimplCpMG, SimplAxCd, SimplAxCdMG, SimplAxCa, SimplAxCaMG, SimplAxCp, SimplAxCpMG, CoefMembers, & + NCoefDpth, CoefDpths, numNodes, nodes, member ) ! This private subroutine generates the Cd, Ca, Cp, CdMG, CaMG and CpMG coefs for the member based on ! the input data. !---------------------------------------------------------------------------------------------------- + integer(IntKi), intent(in ) :: MCoefMod + integer(IntKi), intent(in ) :: MmbrCoefIDIndx + real(ReKi), intent(in ) :: SimplCd + real(ReKi), intent(in ) :: SimplCdMG + real(ReKi), intent(in ) :: SimplCa + real(ReKi), intent(in ) :: SimplCaMG + real(ReKi), intent(in ) :: SimplCp + real(ReKi), intent(in ) :: SimplCpMG + real(ReKi), intent(in ) :: SimplAxCd + real(ReKi), intent(in ) :: SimplAxCdMG + real(ReKi), intent(in ) :: SimplAxCa + real(ReKi), intent(in ) :: SimplAxCaMG + real(ReKi), intent(in ) :: SimplAxCp + real(ReKi), intent(in ) :: SimplAxCpMG + type(Morison_CoefMembers), intent(in ) :: CoefMembers(:) + integer(IntKi), intent(in ) :: NCoefDpth + type(Morison_CoefDpths), intent(in ) :: CoefDpths(:) + integer(IntKi), intent(in ) :: numNodes + type(Morison_NodeType), intent(in ) :: nodes(:) + type(Morison_MemberType), intent(inout) :: member + + type(Morison_NodeType) :: node, node1, node2 + integer(IntKi) :: i, j + real(ReKi) :: s, Cd, CdMG, Ca, CaMG, Cp, CpMG, AxCa, AxCp, AxCaMG, AxCpMG + + select case ( MCoefMod ) + + case (1) ! Simple model : all nodes receive the same coefficients + do i = 1, member%NElements + 1 + if ( member%tMG(i) > 0.0_ReKi ) then + member%Cd (i) = SimplCdMG + member%Ca (i) = SimplCaMG + member%Cp (i) = SimplCpMG + member%AxCd (i) = SimplAxCdMG + member%AxCa (i) = SimplAxCaMG + member%AxCp (i) = SimplAxCpMG + else + member%Cd (i) = SimplCd + member%Ca (i) = SimplCa + member%Cp (i) = SimplCp + member%AxCd (i) = SimplAxCd + member%AxCa (i) = SimplAxCa + member%AxCp (i) = SimplAxCp + end if + end do + + CASE (2) ! Depth-based model: coefficients are set using depth-based table data + do i = 1, member%NElements + 1 + CALL SetDepthBasedCoefs( nodes(member%NodeIndx(i))%Position(3), member%tMG(i), NCoefDpth, CoefDpths, member%Cd(i), member%Ca(i), & + member%Cp(i), member%AxCd(i), member%AxCa(i), member%AxCp(i) ) + end do + + CASE (3) ! Member-based model: coefficients set using member-specific coefficient tables + do i = 1, member%NElements + 1 + ! Pull member end-node data from the tables and then linearly interpolate it onto the interior member nodes + s = (real(i,ReKi)-1.0) / real(member%NElements,ReKi) + if ( member%tMG(i) > 0.0_ReKi ) then + member%Cd (i) = CoefMembers(MmbrCoefIDIndx)%MemberCdMG1*(1-s) + CoefMembers(MmbrCoefIDIndx)%MemberCdMG2*s + member%Ca (i) = CoefMembers(MmbrCoefIDIndx)%MemberCaMG1*(1-s) + CoefMembers(MmbrCoefIDIndx)%MemberCaMG2*s + member%Cp (i) = CoefMembers(MmbrCoefIDIndx)%MemberCpMG1*(1-s) + CoefMembers(MmbrCoefIDIndx)%MemberCpMG2*s + member%AxCd (i) = CoefMembers(MmbrCoefIDIndx)%MemberAxCaMG1*(1-s) + CoefMembers(MmbrCoefIDIndx)%MemberAxCdMG2*s + member%AxCa (i) = CoefMembers(MmbrCoefIDIndx)%MemberAxCaMG1*(1-s) + CoefMembers(MmbrCoefIDIndx)%MemberAxCaMG2*s + member%AxCp (i) = CoefMembers(MmbrCoefIDIndx)%MemberAxCpMG1*(1-s) + CoefMembers(MmbrCoefIDIndx)%MemberAxCpMG2*s + else + member%Cd (i) = CoefMembers(MmbrCoefIDIndx)%MemberCd1 *(1-s) + CoefMembers(MmbrCoefIDIndx)%MemberCd2 *s + member%Ca (i) = CoefMembers(MmbrCoefIDIndx)%MemberCa1 *(1-s) + CoefMembers(MmbrCoefIDIndx)%MemberCa2 *s + member%Cp (i) = CoefMembers(MmbrCoefIDIndx)%MemberCp1 *(1-s) + CoefMembers(MmbrCoefIDIndx)%MemberCp2 *s + member%AxCd (i) = CoefMembers(MmbrCoefIDIndx)%MemberAxCd1 *(1-s) + CoefMembers(MmbrCoefIDIndx)%MemberAxCd2 *s + member%AxCa (i) = CoefMembers(MmbrCoefIDIndx)%MemberAxCa1 *(1-s) + CoefMembers(MmbrCoefIDIndx)%MemberAxCa2 *s + member%AxCp (i) = CoefMembers(MmbrCoefIDIndx)%MemberAxCp1 *(1-s) + CoefMembers(MmbrCoefIDIndx)%MemberAxCp2 *s + end if + end do + end select + +end subroutine SetExternalHydroCoefs - REAL(ReKi), INTENT( IN ) :: SimplCd - REAL(ReKi), INTENT( IN ) :: SimplCdMG - REAL(ReKi), INTENT( IN ) :: SimplCa - REAL(ReKi), INTENT( IN ) :: SimplCaMG - REAL(ReKi), INTENT( IN ) :: SimplCp - REAL(ReKi), INTENT( IN ) :: SimplCpMG - REAL(ReKi), INTENT( IN ) :: SimplAxCa - REAL(ReKi), INTENT( IN ) :: SimplAxCaMG - REAL(ReKi), INTENT( IN ) :: SimplAxCp - REAL(ReKi), INTENT( IN ) :: SimplAxCpMG - TYPE(Morison_CoefMembers), INTENT( IN ) :: CoefMembers(:) - INTEGER, INTENT( IN ) :: NCoefDpth - TYPE(Morison_CoefDpths), INTENT( IN ) :: CoefDpths(:) - INTEGER, INTENT( IN ) :: numNodes - INTEGER, INTENT( IN ) :: numElements - TYPE(Morison_MemberType), INTENT( INOUT ) :: elements(:) - TYPE(Morison_NodeType), INTENT( IN ) :: nodes(:) - - TYPE(Morison_NodeType) :: node1, node2 - - INTEGER :: MCoefMod - INTEGER :: I, J - REAL(ReKi) :: Cd, CdMG, Ca, CaMG, Cp, CpMG, AxCa, AxCp, AxCaMG, AxCpMG - DO I=1,numElements - - - MCoefMod = elements(I)%MCoefMod - node1 = nodes(elements(I)%Node1Indx) - node2 = nodes(elements(I)%Node2Indx) - - SELECT CASE ( MCoefMod ) - - CASE (1) - - elements(I)%Cd1 = SimplCd - elements(I)%Cd2 = SimplCd - elements(I)%Ca1 = SimplCa - elements(I)%Ca2 = SimplCa - elements(I)%Cp1 = SimplCp - elements(I)%Cp2 = SimplCp - elements(I)%AxCa1 = SimplAxCa - elements(I)%AxCa2 = SimplAxCa - elements(I)%AxCp1 = SimplAxCp - elements(I)%AxCp2 = SimplAxCp - elements(I)%CdMG1 = SimplCdMG - elements(I)%CdMG2 = SimplCdMG - elements(I)%CaMG1 = SimplCaMG - elements(I)%CaMG2 = SimplCaMG - elements(I)%CpMG1 = SimplCpMG - elements(I)%CpMG2 = SimplCpMG - elements(I)%AxCaMG1 = SimplAxCaMG - elements(I)%AxCaMG2 = SimplAxCaMG - elements(I)%AxCpMG1 = SimplAxCpMG - elements(I)%AxCpMG2 = SimplAxCpMG - - CASE (2) - - CALL SetDepthBasedCoefs( node1%JointPos(3), NCoefDpth, CoefDpths, Cd, CdMG, Ca, CaMG, Cp, CpMG, AxCa, AxCaMG, AxCp, AxCpMG ) - elements(I)%Cd1 = Cd - elements(I)%Ca1 = Ca - elements(I)%Cp1 = Cp - elements(I)%AxCa1 = AxCa - elements(I)%AxCp1 = AxCp - elements(I)%CdMG1 = CdMG - elements(I)%CaMG1 = CaMG - elements(I)%CpMG1 = CpMG - elements(I)%AxCaMG1 = AxCaMG - elements(I)%AxCpMG1 = AxCpMG - - CALL SetDepthBasedCoefs( node2%JointPos(3), NCoefDpth, CoefDpths, Cd, CdMG, Ca, CaMG, Cp, CpMG, AxCa, AxCaMG, AxCp, AxCpMG ) - elements(I)%Cd2 = Cd - elements(I)%Ca2 = Ca - elements(I)%Cp2 = Cp - elements(I)%AxCa2 = Ca - elements(I)%AxCp2 = Cp - elements(I)%CdMG2 = CdMG - elements(I)%CaMG2 = CaMG - elements(I)%CpMG2 = CpMG - elements(I)%AxCaMG2 = AxCaMG - elements(I)%AxCpMG2 = AxCpMG - - CASE (3) - - J = elements(I)%MmbrCoefIDIndx - elements(I)%Cd1 = CoefMembers(J)%MemberCd1 - elements(I)%Cd2 = CoefMembers(J)%MemberCd2 - elements(I)%Ca1 = CoefMembers(J)%MemberCa1 - elements(I)%Ca2 = CoefMembers(J)%MemberCa2 - elements(I)%Cp1 = CoefMembers(J)%MemberCp1 - elements(I)%Cp2 = CoefMembers(J)%MemberCp2 - elements(I)%AxCa1 = CoefMembers(J)%MemberAxCa1 - elements(I)%AxCa2 = CoefMembers(J)%MemberAxCa2 - elements(I)%AxCp1 = CoefMembers(J)%MemberAxCp1 - elements(I)%AxCp2 = CoefMembers(J)%MemberAxCp2 - elements(I)%CdMG1 = CoefMembers(J)%MemberCdMG1 - elements(I)%CdMG2 = CoefMembers(J)%MemberCdMG2 - elements(I)%CaMG1 = CoefMembers(J)%MemberCaMG1 - elements(I)%CaMG2 = CoefMembers(J)%MemberCaMG2 - elements(I)%CpMG1 = CoefMembers(J)%MemberCpMG1 - elements(I)%CpMG2 = CoefMembers(J)%MemberCpMG2 - elements(I)%AxCaMG1 = CoefMembers(J)%MemberAxCaMG1 - elements(I)%AxCaMG2 = CoefMembers(J)%MemberAxCaMG2 - elements(I)%AxCpMG1 = CoefMembers(J)%MemberAxCpMG1 - elements(I)%AxCpMG2 = CoefMembers(J)%MemberAxCpMG2 - - END SELECT - - - END DO - -END SUBROUTINE SetElementCoefs - - -SUBROUTINE SetAxialCoefs( NJoints, NAxCoefs, AxialCoefs, numNodes, nodes, numElements, elements ) - - INTEGER, INTENT( IN ) :: NJoints - INTEGER, INTENT( IN ) :: NAxCoefs - TYPE(Morison_AxialCoefType),INTENT( IN ) :: AxialCoefs(:) - INTEGER, INTENT( IN ) :: numNodes - INTEGER, INTENT( IN ) :: numElements - TYPE(Morison_MemberType), INTENT( INOUT ) :: elements(:) - TYPE(Morison_NodeType), INTENT( INOUT ) :: nodes(:) - - ! TYPE(Morison_NodeType) :: node1, node2 - - INTEGER :: I !, J - - DO I=1,numNodes - - IF ( nodes(I)%JointAxIDIndx > 0 .AND. nodes(I)%JointIndx > 0 .AND. nodes(I)%JointIndx <= NJoints) THEN - nodes(I)%JAxCd = AxialCoefs(nodes(I)%JointAxIDIndx)%AxCd - nodes(I)%JAxCa = AxialCoefs(nodes(I)%JointAxIDIndx)%AxCa - nodes(I)%JAxCp = AxialCoefs(nodes(I)%JointAxIDIndx)%AxCp - ELSE ! These are end nodes that were generated by the software, and hence do not have lumped axial loads, or they are interior nodes. - nodes(I)%JAxCd = 0.0 - nodes(I)%JAxCa = 0.0 - nodes(I)%JAxCp = 0.0 - END IF - - !node1 = nodes(elements(I)%Node1Indx) - !node2 = nodes(elements(I)%Node2Indx) - - END DO - -END SUBROUTINE SetAxialCoefs - - -SUBROUTINE SetNodeMG( numMGDepths, MGDepths, numNodes, nodes ) +SUBROUTINE SetNodeMG( numMGDepths, MGDepths, node, tMG, MGdensity ) + ! sets the margine growth thickness of a single node (previously all nodes) INTEGER, INTENT( IN ) :: numMGDepths TYPE(Morison_MGDepthsType), INTENT( IN ) :: MGDepths(:) - INTEGER, INTENT( IN ) :: numNodes - TYPE(Morison_NodeType), INTENT( INOUT ) :: nodes(:) - - INTEGER :: I, J + TYPE(Morison_NodeType), INTENT( IN ) :: node + real(ReKi), intent( inout ) :: tMG + real(ReKi), intent( inout ) :: MGdensity + + INTEGER :: I, J REAL(ReKi) :: z INTEGER :: indx1, indx2 REAL(ReKi) :: dd, s LOGICAL :: foundLess = .FALSE. - DO I=1,numNodes !Find the table entry(ies) which match the node's depth value ! The assumption here is that the depth table is stored from largest ! to smallest in depth - z = nodes(I)%JointPos(3) + z = node%Position(3) foundLess = .FALSE. indx1 = 0 indx2 = 0 @@ -2419,8 +1217,8 @@ SUBROUTINE SetNodeMG( numMGDepths, MGDepths, numNodes, nodes ) END DO IF ( indx2 == 0 .OR. .NOT. foundLess ) THEN !Not at a marine growth depth - nodes(I)%tMG = 0.0 - nodes(I)%MGdensity = 0.0 + tMG = 0.0 + MGdensity = 0.0 ELSE ! Linearly interpolate the coef values based on depth !CALL FindInterpFactor( z, CoefDpths(indx1)%Dpth, CoefDpths(indx2)%Dpth, s ) @@ -2431,1976 +1229,942 @@ SUBROUTINE SetNodeMG( numMGDepths, MGDepths, numNodes, nodes ) ELSE s = ( MGDepths(indx1)%MGDpth - z ) / dd END IF - nodes(I)%tMG = MGDepths(indx1)%MGThck*(1-s) + MGDepths(indx2)%MGThck*s - nodes(I)%MGdensity = MGDepths(indx1)%MGDens*(1-s) + MGDepths(indx2)%MGDens*s + tMG = MGDepths(indx1)%MGThck*(1-s) + MGDepths(indx2)%MGThck*s + MGdensity = MGDepths(indx1)%MGDens*(1-s) + MGDepths(indx2)%MGDens*s END IF - END DO - END SUBROUTINE SetNodeMG -SUBROUTINE SetElementFillProps( numFillGroups, filledGroups, numElements, elements ) + +subroutine AllocateMemberDataArrays( member, memberLoads, errStat, errMsg ) + type(Morison_MemberType), intent (inout) :: member + type(Morison_MemberLoads), intent (inout) :: memberLoads + integer(IntKi), intent ( out) :: errStat ! returns a non-zero value when an error occurs + character(*), intent ( out) :: errMsg ! Error message if errStat /= ErrID_None + + integer(IntKi) :: errStat2 ! returns a non-zero value when an error occurs + CHARACTER(errMsgLen) :: errMsg2 ! Error message if errStat2 /= ErrID_None + character(*), parameter :: routineName = 'AllocateMemberDataArrays' + + errStat = ErrID_None + errMSg = '' + call AllocAry(member%NodeIndx , member%NElements, 'member%NodeIndx' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%dRdl_mg , member%NElements, 'member%dRdl_mg' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%dRdl_in , member%NElements, 'member%dRdl_in' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%floodstatus , member%NElements, 'member%floodstatus' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%alpha , member%NElements, 'member%alpha' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%alpha_fb , member%NElements, 'member%alpha_fb' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%alpha_fb_star, member%NElements, 'member%alpha_fb_star', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%m_fb_l , member%NElements, 'member%m_fb_l ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%m_fb_u , member%NElements, 'member%m_fb_u ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%h_cfb_l , member%NElements, 'member%h_cfb_l ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%h_cfb_u , member%NElements, 'member%h_cfb_u ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%I_lfb_l , member%NElements, 'member%I_lfb_l ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%I_lfb_u , member%NElements, 'member%I_lfb_u ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%I_rfb_l , member%NElements, 'member%I_rfb_l ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%I_rfb_u , member%NElements, 'member%I_rfb_u ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%m_mg_l , member%NElements, 'member%m_mg_l ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%m_mg_u , member%NElements, 'member%m_mg_u ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%h_cmg_l , member%NElements, 'member%h_cmg_l ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%h_cmg_u , member%NElements, 'member%h_cmg_u ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%I_lmg_l , member%NElements, 'member%I_lmg_l ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%I_lmg_u , member%NElements, 'member%I_lmg_u ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%I_rmg_l , member%NElements, 'member%I_rmg_l ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%I_rmg_u , member%NElements, 'member%I_rmg_u ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%Cfl_fb , member%NElements, 'member%Cfl_fb ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%Cfr_fb , member%NElements, 'member%Cfr_fb ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%CM0_fb , member%NElements, 'member%CM0_fb ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%R , member%NElements+1, 'member%R ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%RMG , member%NElements+1, 'member%RMG ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%Rin , member%NElements+1, 'member%Rin ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%tMG , member%NElements+1, 'member%tMG ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%MGdensity , member%NElements+1, 'member%MGdensity ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%Cd , member%NElements+1, 'member%Cd ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%Ca , member%NElements+1, 'member%Ca ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%Cp , member%NElements+1, 'member%Cp ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%AxCd , member%NElements+1, 'member%AxCd ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%AxCa , member%NElements+1, 'member%AxCa ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry(member%AxCp , member%NElements+1, 'member%AxCp ', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( memberLoads%F_D , 6, member%NElements+1, 'memberLoads%F_D' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( memberLoads%F_A , 6, member%NElements+1, 'memberLoads%F_A' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( memberLoads%F_B , 6, member%NElements+1, 'memberLoads%F_B' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( memberLoads%F_BF , 6, member%NElements+1, 'memberLoads%F_BF' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( memberLoads%F_I , 6, member%NElements+1, 'memberLoads%F_I' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( memberLoads%F_If , 6, member%NElements+1, 'memberLoads%F_If' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( memberLoads%F_WMG , 6, member%NElements+1, 'memberLoads%F_WMG' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( memberLoads%F_IMG , 6, member%NElements+1, 'memberLoads%F_IMG' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + + ! Initialize everything to zero + member%NodeIndx = 0.0_ReKi + member%dRdl_mg = 0.0_ReKi + member%dRdl_in = 0.0_ReKi + member%floodstatus = 0.0_ReKi + member%alpha = 0.0_ReKi + member%alpha_fb = 0.0_ReKi + member%alpha_fb_star = 0.0_ReKi + member%m_fb_l = 0.0_ReKi + member%m_fb_u = 0.0_ReKi + member%h_cfb_l = 0.0_ReKi + member%h_cfb_u = 0.0_ReKi + member%I_lfb_l = 0.0_ReKi + member%I_lfb_u = 0.0_ReKi + member%I_rfb_l = 0.0_ReKi + member%I_rfb_u = 0.0_ReKi + member%m_mg_l = 0.0_ReKi + member%m_mg_u = 0.0_ReKi + member%h_cmg_l = 0.0_ReKi + member%h_cmg_u = 0.0_ReKi + member%I_lmg_l = 0.0_ReKi + member%I_lmg_u = 0.0_ReKi + member%I_rmg_l = 0.0_ReKi + member%I_rmg_u = 0.0_ReKi + member%Cfl_fb = 0.0_ReKi + member%Cfr_fb = 0.0_ReKi + member%CM0_fb = 0.0_ReKi + member%R = 0.0_ReKi + member%RMG = 0.0_ReKi + member%Rin = 0.0_ReKi + member%tMG = 0.0_ReKi + member%MGdensity = 0.0_ReKi + member%Cd = 0.0_ReKi + member%Ca = 0.0_ReKi + member%Cp = 0.0_ReKi + member%AxCd = 0.0_ReKi + member%AxCa = 0.0_ReKi + member%AxCp = 0.0_ReKi + memberLoads%F_D = 0.0_ReKi + memberLoads%F_A = 0.0_ReKi + memberLoads%F_B = 0.0_ReKi + memberLoads%F_BF = 0.0_ReKi + memberLoads%F_I = 0.0_ReKi + memberLoads%F_If = 0.0_ReKi + memberLoads%F_WMG = 0.0_ReKi + memberLoads%F_IMG = 0.0_ReKi + +end subroutine AllocateMemberDataArrays + +subroutine FlipMemberNodeData( member, nodes, doSwap, errStat, errMsg ) + type(Morison_MemberType), intent (inout) :: member + type(Morison_NodeType), intent (in ) :: nodes(:) + logical, intent ( out) :: doSwap + integer(IntKi), intent ( out) :: errStat ! returns a non-zero value when an error occurs + character(*), intent ( out) :: errMsg ! Error message if errStat /= ErrID_None + + integer(IntKi) :: i, j1, j2, numMemNodes, indx + + errStat = ErrID_None + errMSg = '' + + doSwap = .FALSE. + numMemNodes = member%NElements + 1 + j1 = member%NodeIndx(1) + j2 = member%NodeIndx(numMemNodes) + IF ( EqualRealNos(nodes(j1)%Position(3), nodes(j2)%Position(3) ) ) THEN ! Z1 = Z2 + IF ( EqualRealNos(nodes(j1)%Position(1), nodes(j2)%Position(1) ) ) THEN ! X1 = X2 + IF ( nodes(j1)%Position(2) > nodes(j2)%Position(2) ) THEN + doSwap = .TRUE. ! Y1 > Y2 + END IF + ELSE IF ( nodes(j1)%Position(1) > nodes(j2)%Position(1) ) THEN + doSwap = .TRUE. ! X1 > X2 + END IF + ELSE IF ( nodes(j1)%Position(3) > nodes(j2)%Position(3) ) THEN + 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 + member%Flipped = doSwap + IF ( doSwap ) THEN + member%NodeIndx(1) = j2 + member%NodeIndx(numMemNodes) = j1 + + ! Loop over half the interior nodes and swap their indices + do i = 1, ceiling( (numMemNodes-2.0_ReKi)/2.0_ReKi) + indx = member%NodeIndx(1+i) + member%NodeIndx(1+i) = member%NodeIndx(numMemNodes-i) + member%NodeIndx(numMemNodes-i) = indx + end do + + end if + +end subroutine FlipMemberNodeData + +subroutine SetMemberProperties( gravity, member, MCoefMod, MmbrCoefIDIndx, MmbrFilledIDIndx, propSet1, propSet2, InitInp, errStat, errMsg ) + real(ReKi), intent (in ) :: gravity + type(Morison_MemberType), intent (inout) :: member + integer(IntKi), intent (in ) :: MCoefMod + integer(IntKi), intent (in ) :: MmbrCoefIDIndx + integer(IntKi), intent (in ) :: MmbrFilledIDIndx + type(Morison_MemberPropType), intent (in ) :: propSet1 ! property set of node 1 + type(Morison_MemberPropType), intent (in ) :: propSet2 ! property set of node N+1 + type(Morison_InitInputType), intent (in ) :: InitInp + integer(IntKi), intent ( out) :: errStat ! returns a non-zero value when an error occurs + character(*), intent ( out) :: errMsg ! Error message if errStat /= ErrID_None + + integer(IntKi) :: N, i + real(ReKi) :: WtrDepth,s, dl + type(Morison_NodeType) :: node1, node2 + real(ReKi) :: vec(3), vecLen + real(ReKi) :: memLength + real(ReKi) :: Za + real(ReKi) :: Zb + real(ReKi) :: phi + real(ReKi) :: sinPhi + real(ReKi) :: cosPhi + real(ReKi) :: Rmid + real(ReKi) :: RmidMG + real(ReKi) :: Rmidin + real(ReKi) :: Lmid + real(ReKi) :: li + real(ReKi) :: Vinner_l, Vinner_u, Vouter_l, Vouter_u, Vballast_l, Vballast_u + real(ReKi) :: tk(1,3), Imat(3,3) + REAL(ReKi) :: h_c ! center of mass offset from first node + + errStat = ErrID_None + errMSg = '' + + WtrDepth = InitInp%WtrDpth + N = member%NElements + dl = member%dl + + vec = InitInp%Nodes(member%NodeIndx(N+1))%Position - InitInp%Nodes(member%NodeIndx(1))%Position + + ! calculate reference orientation information. Note: members are straight to start + memLength = member%RefLength + member%k(1:3) = (vec/memLength) ! vector along member from start to end point, length > 0 was already checked when the members were parsed and generated from the input file data + tk(1,1) = member%k(1) + tk(1,2) = member%k(2) + tk(1,3) = member%k(3) + member%kkt = matmul(transpose(tk),tk) + call Eye(Imat,errStat,errMsg) + member%Ak = Imat - member%kkt + phi = acos(vec(3)/memLength) ! incline angle + sinPhi = sin(phi) + cosPhi = cos(phi) + member%cosPhi_ref = cosPhi + + ! These are all per node and not done here, yet + + do i = 1, member%NElements+1 + call SetNodeMG( InitInp%NMGDepths, InitInp%MGDepths, InitInp%Nodes(member%NodeIndx(i)), member%tMG(i), member%MGDensity(i) ) + end do + + member%R( 1) = propSet1%PropD / 2.0 + member%RMG(1) = propSet1%PropD / 2.0 + member%tMG(1) + member%Rin(1) = propSet1%PropD / 2.0 - propSet1%PropThck + member%R( N+1) = propSet2%PropD / 2.0 + member%RMG(N+1) = propSet2%PropD / 2.0 + member%tMG(N+1) + member%Rin(N+1) = propSet2%PropD / 2.0 - propSet2%PropThck + do i = 2, member%NElements + s = (real(i,ReKi)-1.0) / real(member%NElements,ReKi) + member%R( i) = member%R( 1)*(1-s) + member%R( N+1)*s + member%Rin(i) = member%Rin(1)*(1-s) + member%Rin(N+1)*s + member%RMG(i) = member%R(i) + member%tMG(i) + end do + + call SetExternalHydroCoefs( MCoefMod, MmbrCoefIDIndx, InitInp%SimplCd, InitInp%SimplCdMG, InitInp%SimplCa, InitInp%SimplCaMG, InitInp%SimplCp, & + InitInp%SimplCpMG, InitInp%SimplAxCd, InitInp%SimplAxCdMG, InitInp%SimplAxCa, InitInp%SimplAxCaMG, InitInp%SimplAxCp, InitInp%SimplAxCpMG, InitInp%CoefMembers, & + InitInp%NCoefDpth, InitInp%CoefDpths, InitInp%NNodes, InitInp%Nodes, member ) + + + ! calculate reference incline angle and heading, and related trig values. Note: members are straight to start + Za = InitInp%Nodes(member%NodeIndx(1 ))%Position(3) + Zb = InitInp%Nodes(member%NodeIndx(N+1))%Position(3) + + ! find fill location of member (previously in SetElementFillProps) + member%MmbrFilledIDIndx = MmbrFilledIDIndx ! Set this to the parameter version of this member data + if ( MmbrFilledIDIndx > 0 ) then + member%FillDens = InitInp%FilledGroups(MmbrFilledIDIndx)%FillDens + member%FillFSLoc = InitInp%FilledGroups(MmbrFilledIDIndx)%FillFSLoc - InitInp%MSL2SWL + if (member%FillFSLoc >= Zb) then + member%z_overfill = member%FillFSLoc - Zb + member%l_fill = member%RefLength + member%memfloodstatus = 1 ! fully flooded + elseif (Za >= member%FillFSLoc) then + ! No ballast + member%memfloodstatus = 0 + member%z_overfill = 0.0_ReKi + member%l_fill = 0.0_ReKi + else + member%z_overfill =0 + if ( Zb <= -InitInp%WtrDpth ) then + member%memfloodstatus = 0 ! member fully buried in seabed + member%l_fill = 0 + else + member%memfloodstatus = 2 ! partially flooded member + member%l_fill = (member%FillFSLoc - Za)/cosPhi + end if + + end if + + else + member%FillDens = 0.0 + member%FillFSLoc = 0.0 ! Future calculations for ballasting MUST verify that MbrFilledIDIndx > 0 for any ballasting calcs or this value will cause errors + member%z_overfill =0 + member%l_fill = 0 + member%memfloodstatus = 0 + end if + + ! Check the member does not exhibit any of the following conditions + if (.not. member%PropPot) then + if ( abs(Zb) < abs(member%Rmg(N+1)*sinPhi) ) then + call SetErrStat(ErrID_Fatal, 'The upper end-plate of a member must not cross the water plane. This is not true for Member ID '//trim(num2lstr(member%MemberID)), errStat, errMsg, 'SetMemberProperties' ) + end if + if ( abs(Za) < abs(member%Rmg(1)*sinPhi) ) then + call SetErrStat(ErrID_Fatal, 'The lower end-plate of a member must not cross the water plane. This is not true for Member ID '//trim(num2lstr(member%MemberID)), errStat, errMsg, 'SetMemberProperties' ) + end if + + if ( ( Za < -WtrDepth .and. Zb >= -WtrDepth ) .and. ( phi > 10.0*d2r .or. abs((member%RMG(N+1) - member%RMG(i))/member%RefLength)>0.1 ) ) then + call SetErrStat(ErrID_Fatal, 'A member which crosses the seabed must not be inclined more than 10 degrees from vertical or have a taper larger than 0.1. This is not true for Member ID '//trim(num2lstr(member%MemberID)), errStat, errMsg, 'SetMemberProperties' ) + end if + + end if + + + ! calculate h_floor if seabed-piercing + member%h_floor = 0.0_ReKi + member%i_floor = member%NElements+1 ! Default to entire member is below the seabed + member%doEndBuoyancy = .false. + if (Za < -WtrDepth) then + do i= 2, member%NElements+1 + Za = InitInp%Nodes(member%NodeIndx(i))%Position(3) + if (Za > -WtrDepth) then ! find the lowest node above the seabed + + if (cosPhi < 0.173648178 ) then ! phi > 80 degrees and member is seabed crossing + call SetErrStat(ErrID_Fatal, 'A seabed crossing member must have an inclination angle of <= 80 degrees from vertical. This is not true for Member ID '//trim(num2lstr(member%MemberID)), errStat, errMsg, 'SetMemberProperties' ) + end if + + member%h_floor = (-WtrDepth-Za)/cosPhi ! get the distance from the node to the seabed along the member axis (negative value) + member%i_floor = i-1 ! record the number of the element that pierces the seabed + member%doEndBuoyancy = .true. + exit + else if ( EqualRealNos(Za, -WtrDepth ) ) then + member%doEndBuoyancy = .true. + end if + end do + else + member%i_floor = 0 ! lower end is at or above the seabed + end if - INTEGER, INTENT( IN ) :: numFillGroups - TYPE(Morison_FilledGroupType), INTENT( IN ) :: filledGroups(:) - INTEGER, INTENT( IN ) :: numElements - TYPE(Morison_MemberType), INTENT( INOUT ) :: elements(:) - - INTEGER :: I !, J + + + ! calculate element-level values - DO I=1,numElements + do i = 1, member%NElements + member%dRdl_mg(i) = (member%RMG(i+1) - member%RMG(i))/dl + member%dRdl_in(i) = (member%Rin(i+1) - member%Rin(i))/dl + member%alpha( i) = GetAlpha(member%RMG(i), member%RMG(i+1)) + member%alpha_fb(i) = GetAlpha(member%Rin(i), member%Rin(i+1)) - IF ( elements(I)%MmbrFilledIDIndx > 0 ) THEN - - elements(I)%FillDens = filledGroups(elements(I)%MmbrFilledIDIndx)%FillDens - elements(I)%FillFSLoc = filledGroups(elements(I)%MmbrFilledIDIndx)%FillFSLoc - ELSE - elements(I)%FillDens = 0.0 - elements(I)%FillFSLoc = 0.0 - END IF - - - - END DO - - -END SUBROUTINE SetElementFillProps - -!SUBROUTINE CreateLumpedMarkers( numNodes, nodes, numElements, elements, numLumpedMarkers, lumpedMarkers, ErrStat, ErrMsg ) -! -! INTEGER, INTENT( IN ) :: numNodes -! INTEGER, INTENT( IN ) :: numElements -! TYPE(Morison_MemberType), INTENT( IN ) :: elements(:) -! TYPE(Morison_NodeType), INTENT( IN ) :: nodes(:) -! INTEGER, INTENT( OUT ) :: numLumpedMarkers -! TYPE(Morison_NodeType), ALLOCATABLE, INTENT( OUT ) :: lumpedMarkers(:) -! INTEGER, INTENT ( OUT ) :: ErrStat ! returns a non-zero value when an error occurs -! CHARACTER(*), INTENT ( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None -! -! INTEGER :: I, J, count -! TYPE(Morison_MemberType) :: element -! -! numLumpedMarkers = 0 -! -! ! Count how many distributed markers we need to create by looping over the nodes -! DO I=1,numNodes -! IF ( nodes(I)%NodeType == 1 .AND. nodes(I)%JointOvrlp == 0 ) THEN -! ! end of a member that was not a part of super member creation -! numLumpedMarkers = numLumpedMarkers + 1 -! END IF -! END DO -! -! ! Allocate the array for the distributed markers -! ALLOCATE ( lumpedMarkers(numLumpedMarkers), STAT = ErrStat ) -! IF ( ErrStat /= ErrID_None ) THEN -! ErrMsg = ' Error allocating space for the lumped load markers array.' -! ErrStat = ErrID_Fatal -! RETURN -! END IF -! count = 1 -! DO I=1,numNodes -! -! IF ( nodes(I)%NodeType == 1 .AND. nodes(I)%JointOvrlp == 0) THEN -! -! element = elements(nodes(I)%ConnectionList(1)) -! -! IF ( element%Node1Indx == I ) THEN -! lumpedMarkers(count)%Cd = element%Cd1 -! lumpedMarkers(count)%CdMG = element%CdMG1 -! lumpedMarkers(count)%Ca = element%Ca1 -! lumpedMarkers(count)%CaMG = element%CaMG1 -! lumpedMarkers(count)%R = element%R1 -! lumpedMarkers(count)%t = element%t1 -! ELSE -! lumpedMarkers(count)%Cd = element%Cd2 -! lumpedMarkers(count)%CdMG = element%CdMG2 -! lumpedMarkers(count)%Ca = element%Ca2 -! lumpedMarkers(count)%CaMG = element%CaMG2 -! lumpedMarkers(count)%R = element%R2 -! lumpedMarkers(count)%t = element%t2 -! END IF -! -! lumpedMarkers(count)%PropPot = element%PropPot -! lumpedMarkers(count)%tMG = nodes(I)%tMG -! lumpedMarkers(count)%MGdensity = nodes(I)%MGdensity -! -! -! ! Compute all initialization forces now so we have access to the element information -! -! !IF ( element%PropPot == .FALSE. ) THEN -! ! -! ! ! Member is not modeled with WAMIT -! ! CALL LumpedBuoyancy( ) -! ! CALL LumpedMGLoads( ) -! ! CALL LumpedDynPressure( ) -! ! CALL LumpedAddedMass( ) -! ! CALL LumpedAddedMassMG( ) -! ! CALL LumpedAddedMassFlood( ) ! Do we actually compute this??? TODO -! ! -! !END IF -! ! -! ! ! These are the only two loads we compute at initialization if the member is modeled with WAMIT -! !CALL LumpedDragConst( ) -! !CALL LumpedFloodedBuoyancy( ) -! -! -! count = count + 1 -! -! END IF -! -! END DO -! -!END SUBROUTINE CreateLumpedMarkers - - -SUBROUTINE SplitMeshNodes( numNodes, nodes, numElements, elements, numSplitNodes, splitNodes, ErrStat, ErrMsg ) - - INTEGER, INTENT( IN ) :: numNodes - INTEGER, INTENT( IN ) :: numElements - TYPE(Morison_MemberType), INTENT( INOUT ) :: elements(:) - TYPE(Morison_NodeType), INTENT( IN ) :: nodes(:) - INTEGER, INTENT( OUT ) :: numSplitNodes - TYPE(Morison_NodeType), ALLOCATABLE, INTENT( OUT ) :: splitNodes(:) - INTEGER, INTENT ( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT ( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - INTEGER :: I, J, splitNodeIndx -! TYPE(Morison_MemberType) :: element - TYPE(Morison_NodeType) :: node1, node2, newNode - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - - numSplitNodes = 0 - - ! Count how many distributed markers we need to create by looping over the nodes - DO I=1,numNodes - IF ( nodes(I)%NodeType == 1 ) THEN - ! Nodes at the end of members get one node for each connecting member - numSplitNodes = numSplitNodes + nodes(I)%NConnections - ELSE - ! Internal nodes and super member nodes only get one node - numSplitNodes = numSplitNodes + 1 - END IF - END DO - - ! Allocate the array for the distributed markers - ALLOCATE ( splitNodes(numSplitNodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for split nodes array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - splitNodes(1:numNodes) = nodes(1:numNodes) - - IF ( numSplitNodes > numNodes ) THEN - - splitNodeIndx = numNodes + 1 - - DO I=1,numElements - ! Loop over elements in the processed mesh and create additional nodes/markers at the end of elements if that node connects to other elements - node1 = splitnodes(elements(I)%Node1Indx) - node2 = splitnodes(elements(I)%Node2Indx) - - IF (node1%NodeType == 1 ) THEN ! end node - IF ( node1%NConnections > 1 ) THEN - !create new node by copying the old one - newNode = node1 - newNode%NConnections = 1 - splitnodes(splitNodeIndx) = newNode - splitnodes(elements(I)%Node1Indx)%NConnections = node1%NConnections - 1 - !set the new node as the first node of this element - elements(I)%Node1Indx = splitNodeIndx - splitNodeIndx = splitNodeIndx + 1 - !NOTE: the node connection list entries are now bogus!!!! - END IF - - END IF - - IF (node2%NodeType == 1 ) THEN ! end node - IF ( node2%NConnections > 1 ) THEN - !create new node by copying the old one - newNode = node2 - newNode%NConnections = 1 - splitnodes(splitNodeIndx) = newNode - splitnodes(elements(I)%Node2Indx)%NConnections = node2%NConnections - 1 - !set the new node as the first node of this element - elements(I)%Node2Indx = splitNodeIndx - splitNodeIndx = splitNodeIndx + 1 - !NOTE: the node connection list entries are now bogus!!!! - END IF - - END IF - - END DO - - ! Fix connections - DO J = 1,numSplitNodes - splitnodes(J)%NConnections = 0 - END DO - - DO I = 1,numElements - - - DO J = 1,numSplitNodes - IF ( elements(I)%Node1Indx == J ) THEN - splitnodes(J)%NConnections = splitnodes(J)%NConnections + 1 - splitnodes(J)%ConnectionList(splitnodes(J)%NConnections) = I - END IF - IF ( elements(I)%Node2Indx == J ) THEN - splitnodes(J)%NConnections = splitnodes(J)%NConnections + 1 - splitnodes(J)%ConnectionList(splitnodes(J)%NConnections) = I - END IF - END DO - END DO - - END IF - -END SUBROUTINE SplitMeshNodes - - - -SUBROUTINE GenerateLumpedLoads( nodeIndx, sgn, node, gravity, MSL2SWL, densWater, NStepWave, WaveDynP, dragConst, F_DP, F_B, ErrStat, ErrMsg ) - - INTEGER, INTENT( IN ) :: nodeIndx - REAL(ReKi), INTENT( IN ) :: sgn - TYPE(Morison_NodeType), INTENT( IN ) :: node - REAL(ReKi), INTENT( IN ) :: gravity - REAL(ReKi), INTENT( IN ) :: MSL2SWL - REAL(ReKi), INTENT( IN ) :: densWater - INTEGER, INTENT( IN ) :: NStepWave - REAL(SiKi), INTENT( IN ) :: WaveDynP(:,:) ! TODO: Verify it is ok to use (:,:) for the zero-based first array index GJH 2/5/14 - REAL(ReKi),ALLOCATABLE, INTENT( OUT ) :: F_DP(:,:) - REAL(ReKi), INTENT( OUT ) :: F_B(6) - REAL(ReKi), INTENT( OUT ) :: dragConst - INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - REAL(ReKi) :: k(3) - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - - - IF (.NOT. node%PropPot ) THEN - - k = sgn * node%R_LToG(:,3) - - CALL LumpDynPressure( nodeIndx, node%JAxCp, k, node%R, node%tMG, NStepWave, WaveDynP, F_DP, ErrStat, ErrMsg) - - ! For buoyancy calculations we need to adjust the Z-location based on MSL2SWL. If MSL2SWL > 0 then SWL above MSL, and so we need to place the Z value at a deeper position. - ! SWL is at Z=0 for buoyancy calcs, but geometry was specified relative to MSL (MSL2SWL = 0) - CALL LumpBuoyancy( sgn, densWater, node%R, node%tMG, node%JointPos(3) - MSL2SWL, node%R_LToG, gravity, F_B ) - - - ! This one is tricky because we need to calculate a signed volume which is the signed sum of all connecting elements and then split the - ! result across all the connecting nodes. - !CALL LumpAddedMass() - - ELSE - - ALLOCATE ( F_DP(0:NStepWave, 6), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating distributed dynamic pressure loads array.' - ErrStat = ErrID_Fatal - RETURN - END IF - F_DP = 0.0 - F_B = 0.0 - END IF - - - CALL LumpDragConst( densWater, node%Cd, node%R, node%tMG, dragConst ) - - - - -END SUBROUTINE GenerateLumpedLoads - - - -SUBROUTINE CreateLumpedMesh( densWater, gravity, MSL2SWL, wtrDpth, NStepWave, WaveDynP, WaveAcc, numNodes, nodes, numElements, elements, & - numLumpedMarkers, lumpedMeshIn, lumpedMeshOut, lumpedToNodeIndx, L_An, & - L_F_B, L_F_I, L_F_BF, L_AM_M, L_dragConst, & - ErrStat, ErrMsg ) - - REAL(ReKi), INTENT( IN ) :: densWater - REAL(ReKi), INTENT( IN ) :: gravity - REAL(ReKi), INTENT( IN ) :: MSL2SWL - REAL(ReKi), INTENT( IN ) :: wtrDpth - INTEGER, INTENT( IN ) :: NStepWave - REAL(SiKi), INTENT( IN ) :: WaveDynP(0:,:) - REAL(SiKi), INTENT( IN ) :: WaveAcc(0:,:,:) - INTEGER, INTENT( IN ) :: numNodes - INTEGER, INTENT( IN ) :: numElements - TYPE(Morison_MemberType), INTENT( IN ) :: elements(:) - TYPE(Morison_NodeType), INTENT( INOUT ) :: nodes(:) - INTEGER, INTENT( OUT ) :: numLumpedMarkers - !TYPE(Morison_NodeType), ALLOCATABLE, INTENT( OUT ) :: lumpedMarkers(:) - TYPE(MeshType), INTENT( OUT ) :: lumpedMeshIn - TYPE(MeshType), INTENT( OUT ) :: lumpedMeshOut - INTEGER, ALLOCATABLE, INTENT( OUT ) :: lumpedToNodeIndx(:) - REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: L_An(:,:) ! The signed/summed end cap Area x k of all connected members at a common joint - REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: L_F_B(:,:) ! Buoyancy force associated with the member - REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: L_F_I(:,:,:) ! Inertial force. TODO: Eventually the dynamic pressure will be included in this force! GJH 4/15/14 - !REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: L_F_DP(:,:,:) ! Dynamic pressure force - REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: L_F_BF(:,:) ! Flooded buoyancy force - REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: L_AM_M(:,:,:) ! Added mass of member - REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: L_dragConst(:) ! - INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - - INTEGER :: I, J, M, count - TYPE(Morison_MemberType) :: element - TYPE(Morison_NodeType) :: node, node1, node2 - REAL(ReKi) :: L, sgn -! REAL(ReKi) :: k(3) - REAL(ReKi) :: z0 - REAL(ReKi),ALLOCATABLE :: F_DP(:,:) - REAL(ReKi) :: F_B(6) - REAL(ReKi) :: F_BF(6) - REAL(ReKi) :: Vmat(3,1), F_I(6), AM_M(6,6) !AM(6,6), - REAL(ReKi) :: dragConst - - - INTEGER, ALLOCATABLE :: nodeToLumpedIndx(:) - INTEGER, ALLOCATABLE :: commonNodeLst(:) - LOGICAL, ALLOCATABLE :: usedJointList(:) - INTEGER :: nCommon -! REAL(ReKi) :: CA - REAL(ReKi) :: AMfactor - REAL(ReKi) :: An(3), Vn(3), af(3) -! REAL(ReKi) :: AM11, AM22, AM33 - REAL(ReKi) :: f1, VnDotAf, Vmag !f2, - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - - - numLumpedMarkers = 0 - z0 = -(wtrDpth) ! The total sea depth is the still water depth of the seabed - - - - ! Count how many lumped markers we need to create by looping over the nodes - - DO I=1,numNodes - - IF ( (nodes(I)%NodeType == 3) .OR. ( nodes(I)%NodeType == 1 .AND. nodes(I)%JointOvrlp == 0 ) ) THEN - - numLumpedMarkers = numLumpedMarkers + 1 - - END IF - - END DO - - - ! Create the input and output meshes associated with lumped loads - - CALL MeshCreate( BlankMesh = lumpedMeshIn & - ,IOS = COMPONENT_INPUT & - ,Nnodes = numLumpedMarkers & - ,ErrStat = ErrStat & - ,ErrMess = ErrMsg & - ,TranslationDisp = .TRUE. & - ,Orientation = .TRUE. & - ,TranslationVel = .TRUE. & - ,RotationVel = .TRUE. & - ,TranslationAcc = .TRUE. & - ,RotationAcc = .TRUE. ) - - - - - ! ! Allocate the array for the lumped markers - ! - !ALLOCATE ( lumpedMarkers(numLumpedMarkers), STAT = ErrStat ) - !IF ( ErrStat /= ErrID_None ) THEN - ! ErrMsg = ' Error allocating space for the lumped load markers array.' - ! ErrStat = ErrID_Fatal - ! RETURN - !END IF - - ALLOCATE ( commonNodeLst(10), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the commonNodeLst array.' - ErrStat = ErrID_Fatal - RETURN - END IF - commonNodeLst = -1 - - ALLOCATE ( usedJointList(numNodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the UsedJointList array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - usedJointList = .FALSE. - - ALLOCATE ( lumpedToNodeIndx(numLumpedMarkers), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the lumped index array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - ALLOCATE ( nodeToLumpedIndx(numNodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the lumped index array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - - - ALLOCATE ( L_F_B( 6, numLumpedMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the lumped buoyancy forces/moments array.' - ErrStat = ErrID_Fatal - RETURN - END IF - L_F_B = 0.0 - - ALLOCATE ( L_An( 3, numLumpedMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the L_An array.' - ErrStat = ErrID_Fatal - RETURN - END IF - L_An = 0.0 - - ! This is - ALLOCATE ( L_F_I( 0:NStepWave, 6, numLumpedMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the lumped inertial forces/moments array.' - ErrStat = ErrID_Fatal - RETURN - END IF - L_F_I = 0.0 - - !ALLOCATE ( L_F_DP( 0:NStepWave, 6, numLumpedMarkers ), STAT = ErrStat ) - !IF ( ErrStat /= ErrID_None ) THEN - ! ErrMsg = ' Error allocating space for the lumped dynamic pressure forces/moments array.' - ! ErrStat = ErrID_Fatal - ! RETURN - !END IF - ! L_F_DP = 0.0 - - ALLOCATE ( L_F_BF( 6, numLumpedMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the lumped buoyancy due to flooding forces/moments array.' - ErrStat = ErrID_Fatal - RETURN - END IF - L_F_BF = 0.0 - - ALLOCATE ( L_AM_M( 6, 6, numLumpedMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the lumped member added mass.' - ErrStat = ErrID_Fatal - RETURN - END IF - L_AM_M = 0.0 - - ALLOCATE ( L_dragConst( numLumpedMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the lumped drag constants.' - ErrStat = ErrID_Fatal - RETURN - END IF - L_dragConst = 0.0 - - ! Loop over nodes to create all loads on the resulting markers except for the buoyancy loads - ! For the buoyancy loads, loop over the elements and then apply one half of the resulting value - ! to each of the interior element nodes but the full value to an end node. This means that an internal member node will receive 1/2 of its - ! load from element A and 1/2 from element B. If it is the end of a member it will simply receive - ! the element A load. - - count = 1 - - DO I=1,numNodes - - ! exclude internal member nodes and end nodes which were connected to a joint made into a super member - - IF ( (nodes(I)%NodeType == 3) .OR. ( nodes(I)%NodeType == 1 .AND. nodes(I)%JointOvrlp == 0 ) ) THEN - - lumpedToNodeIndx(count) = I - nodeToLumpedIndx(I) = count - - ! If this is a super member node, then generate the lumped loads now, otherwise save it for the loop over elements - - IF ( nodes(I)%NodeType == 3 ) THEN - - END IF - - - - - ! Create the node on the mesh - - CALL MeshPositionNode (lumpedMeshIn & - , count & - , nodes(I)%JointPos & ! this info comes from FAST - , ErrStat & - , ErrMsg & - ) !, transpose(nodes(I)%R_LToG) ) - IF ( ErrStat /= 0 ) THEN - RETURN - END IF - - ! Create the mesh element - - CALL MeshConstructElement ( lumpedMeshIn & - , ELEMENT_POINT & - , ErrStat & - , ErrMsg & - , count & - ) - count = count + 1 - - - END IF - - END DO - - - - - ! CA is the added mass coefficient for three dimensional bodies in infinite fluid (far from boundaries) The default value is 2/Pi - - - AMfactor = 2.0 * densWater * Pi / 3.0 - - ! Loop over nodes again in order to create lumped axial drag. - - usedJointList = .FALSE. - commonNodeLst = -1 - - DO I=1,numNodes - - - - ! Determine bounds checking based on what load we are calculating, - ! This is for L_An - IF ( nodes(I)%JointPos(3) >= z0 ) THEN - - ! exclude internal member nodes and end nodes which were connected to a joint made into a super member - - - - ! If this is a super member node, then generate the lumped loads now, otherwise save it for the loop over elements - - IF ( nodes(I)%NodeType == 3 ) THEN - - ELSE - - IF ( nodes(I)%JointIndx /= -1 ) THEN ! TODO: MAYBE THIS SHOULD CHECK JointOvrlp value instead!! - - ! Have we already set the added mass for this node? - IF ( .NOT. usedJointList(nodes(I)%JointIndx) ) THEN - - nCommon = 0 - An = 0.0 - Vn = 0.0 - - DO J=1,numNodes - - ! must match joint index but also cannot be modeled using WAMIT - IF ( nodes(I)%JointIndx == nodes(J)%JointIndx ) THEN - - nCommon = nCommon + 1 - commonNodeLst(nCommon) = J - - ! Compute the signed area*outward facing normal of this member - sgn = 1.0 - - element = elements(nodes(J)%ConnectionList(1)) - - IF ( element%Node1Indx == J ) THEN - sgn = -1.0 ! Local coord sys points into element at starting node, so flip sign of local z vector - ELSE IF ( element%Node2Indx == J ) THEN - sgn = 1.0 ! Local coord sys points out of element at ending node, so leave sign of local z vector - ELSE - ErrMsg = 'Internal Error in CreateLumpedMesh: could not find element node index match.' - ErrStat = ErrID_FATAL - RETURN - END IF - ! Compute the signed volume of this member - f1 = (nodes(J)%R+nodes(J)%tMG)*(nodes(J)%R+nodes(J)%tMG)*(nodes(J)%R+nodes(J)%tMG) - Vn = Vn + sgn*f1*nodes(J)%R_LToG(:,3) - An = An + sgn*nodes(J)%R_LtoG(:,3)*Pi*(nodes(J)%R+nodes(J)%tMG)**2 - - END IF - - END DO - - nodes(I)%NConnectPreSplit = nCommon - - ! Divide the directed area equally across all connected markers - Vmag = sqrt(Dot_Product(Vn,Vn)) - - - - AM_M = 0.0 - IF ( (Vmag > 0.0) .AND. (.NOT. nodes(I)%PropPot) ) THEN - Vmat = RESHAPE(Vn,(/3,1/)) - AM_M(1:3,1:3) = (nodes(I)%JAxCa*AMfactor/(REAL( nCommon, ReKi)*Vmag) )*MatMul(Vmat,TRANSPOSE(Vmat)) - END IF - - DO J=1,nCommon - - IF ( nodes(I)%JointPos(3) >= z0 ) THEN - - L_An (:, nodeToLumpedIndx(commonNodeLst(J))) = An / nCommon - L_AM_M(:,:,nodeToLumpedIndx(commonNodeLst(J))) = AM_M - - DO M=0,NStepWave - ! The WaveAcc array has indices of (timeIndx, nodeIndx, vectorIndx), the nodeIndx needs to correspond to the total list of nodes for which - ! the wave kinematics were generated. We can use the nodeToLumpedIndx however for L_F_I and it's indices are (timeIndx, nodeIndx, vectorIndx) - - - F_I = 0.0 - IF ( (Vmag > 0.0) .AND. (.NOT. nodes(I)%PropPot) ) THEN - af = WaveAcc(M,commonNodeLst(J),:) - VnDotAf = Dot_Product(Vn,af) - F_I(1:3) = ( nodes(I)%JAxCa*AMfactor*VnDotAf / ( REAL( nCommon, ReKi ) * Vmag ) ) * Vn - END IF - L_F_I(M, :,nodeToLumpedIndx(commonNodeLst(J))) = F_I - END DO - - ELSE - ! Should we ever land in here? - L_An(:,nodeToLumpedIndx(commonNodeLst(J))) = 0.0 - L_AM_M(:,:,nodeToLumpedIndx(commonNodeLst(J))) = 0.0 - L_F_I(:,:,nodeToLumpedIndx(commonNodeLst(J))) = 0.0 - END IF - - END DO - - usedJointList(nodes(I)%JointIndx) = .TRUE. - END IF !IF ( .NOT. usedJointList(nodes(I)%JointIndx) ) - - END IF ! IF ( nodes(I)%JointIndx /= -1 ) - - END IF ! IF ( nodes(I)%NodeType == 3 ) THEN - - - - END IF ! ( nodes(I)%JointPos(3) >= z0 ) - - - - END DO ! I=1,numNodes - - - ! Loop over elements and identify those end nodes which have a JointOvrlp option of 0. - - DO I=1,numElements - - element = elements(I) - node1 = nodes(element%Node1Indx) - node2 = nodes(element%Node2Indx) - - CALL GetDistance( node1%JointPos, node2%JointPos, L ) - - IF ( node1%NodeType == 1 .AND. node1%JointOvrlp == 0 ) THEN - - !Process Lumped loads for this node - node = node1 - sgn = 1.0 - IF ( ( node%JointPos(3) >= z0 ) .AND. (.NOT. node%PropPot) )THEN - CALL GenerateLumpedLoads( element%Node1Indx, sgn, node, gravity, MSL2SWL, densWater, NStepWave, WaveDynP, dragConst, F_DP, F_B, ErrStat, ErrMsg ) - L_F_I(:, :, nodeToLumpedIndx(element%Node1Indx)) = L_F_I(:, :, nodeToLumpedIndx(element%Node1Indx)) + F_DP - ! L_F_DP(:, :, nodeToLumpedIndx(element%Node1Indx)) = F_DP - - L_dragConst(nodeToLumpedIndx(element%Node1Indx)) = dragConst - IF ( ( node%JointPos(3) >= z0 ) .AND. (.NOT. node%PropPot) )THEN - L_F_B (:, nodeToLumpedIndx(element%Node1Indx)) = F_B - END IF - - ELSE - F_BF = 0.0 - !L_F_DP(:, :, nodeToLumpedIndx(element%Node1Indx)) = 0.0 - L_F_B (:, nodeToLumpedIndx(element%Node1Indx)) = 0.0 - L_dragConst(nodeToLumpedIndx(element%Node1Indx)) = 0.0 - - END IF - IF ( node%FillFlag ) THEN - IF ( (node%JointPos(3) <= (node%FillFSLoc)) .AND. (node%JointPos(3) >= z0) ) THEN - CALL LumpFloodedBuoyancy( sgn, node%FillDensity, node%R, node%t, node%FillFSLoc, node%JointPos(3) , node%R_LToG, gravity, F_BF ) - - L_F_BF(:, nodeToLumpedIndx(element%Node1Indx)) = F_BF - ELSE - L_F_BF(:, nodeToLumpedIndx(element%Node1Indx)) = 0.0 - END IF - ELSE - L_F_BF(:, nodeToLumpedIndx(element%Node1Indx)) = 0.0 - END IF - - - ENDIF - - - IF ( node2%NodeType == 1 .AND. node2%JointOvrlp == 0 ) THEN - - !Process Lumped loads for this node - node = node2 - sgn = -1.0 - - ! Generate the loads regardless of node location, and then make the bounds check per load type because the range is different - CALL GenerateLumpedLoads( element%Node2Indx, sgn, node, gravity, MSL2SWL, densWater, NStepWave, WaveDynP, dragConst, F_DP, F_B, ErrStat, ErrMsg ) - IF ( ( node%JointPos(3) >= z0 ) .AND. (.NOT. node%PropPot) ) THEN - L_F_I(:, :, nodeToLumpedIndx(element%Node2Indx)) = L_F_I(:, :, nodeToLumpedIndx(element%Node2Indx)) + F_DP - !L_F_DP(:, :, nodeToLumpedIndx(element%Node2Indx)) = F_DP - - L_dragConst(nodeToLumpedIndx(element%Node2Indx)) = dragConst - - IF ( ( node%JointPos(3) >= z0 ) .AND. (.NOT. node%PropPot) ) THEN - L_F_B (:, nodeToLumpedIndx(element%Node2Indx)) = F_B - END IF - - ELSE - F_BF = 0.0 - !L_F_DP(:, :, nodeToLumpedIndx(element%Node2Indx)) = 0.0 - L_F_B (:, nodeToLumpedIndx(element%Node2Indx)) = 0.0 - L_dragConst(nodeToLumpedIndx(element%Node2Indx)) = 0.0 - - END IF - IF ( node%FillFlag ) THEN - IF ( (node%JointPos(3) <= (node%FillFSLoc)) .AND. (node%JointPos(3) >= z0) ) THEN - CALL LumpFloodedBuoyancy( sgn, node%FillDensity, node%R, node%t, node%FillFSLoc, node%JointPos(3), node%R_LToG, gravity, F_BF ) - L_F_BF(:, nodeToLumpedIndx(element%Node2Indx)) = F_BF - ELSE - L_F_BF(:, nodeToLumpedIndx(element%Node2Indx)) = 0.0 - END IF - ELSE - L_F_BF(:, nodeToLumpedIndx(element%Node2Indx)) = 0.0 - END IF - ENDIF - - - - - IF ( ErrStat /= 0 ) THEN - RETURN - END IF - - - END DO - - - CALL MeshCommit ( lumpedMeshIn & - , ErrStat & - , ErrMsg ) - - IF ( ErrStat /= 0 ) THEN - RETURN - END IF - - ! Initialize the inputs - DO I=1,lumpedMeshIn%Nnodes - lumpedMeshIn%Orientation(:,:,I) = lumpedMeshIn%RefOrientation(:,:,I) - END DO - lumpedMeshIn%TranslationDisp = 0.0 - lumpedMeshIn%TranslationVel = 0.0 - lumpedMeshIn%RotationVel = 0.0 - lumpedMeshIn%TranslationAcc = 0.0 - lumpedMeshIn%RotationAcc = 0.0 - - CALL MeshCopy ( SrcMesh = lumpedMeshIn & - ,DestMesh = lumpedMeshOut & - ,CtrlCode = MESH_SIBLING & - ,IOS = COMPONENT_OUTPUT & - ,ErrStat = ErrStat & - ,ErrMess = ErrMsg & - ,Force = .TRUE. & - ,Moment = .TRUE. ) - - lumpedMeshIn%RemapFlag = .TRUE. - lumpedMeshOut%RemapFlag = .TRUE. - - -END SUBROUTINE CreateLumpedMesh - -!subroutine ComputeDistributedLoadsAtNode( elementWaterState, densWater, JointZPos, & -! PropPot, R, dRdz, t, tMG, MGdensity, & -! R_LToG, Ca, Cp, AxCa, AxCp, Cd, WaveAcc, WaveDynP, D_dragConst_in, & -! D_AM_M, D_dragConst, D_F_I, ErrStat, ErrMsg ) -! -! INTEGER, INTENT( IN ) :: elementWaterState -! REAL(ReKi), INTENT( IN ) :: densWater -! REAL(ReKi), INTENT( IN ) :: JointZPos -! LOGICAL, INTENT( IN ) :: PropPot -! REAL(ReKi), INTENT( IN ) :: R -! REAL(ReKi), INTENT( IN ) :: dRdz -! REAL(ReKi), INTENT( IN ) :: t -! REAL(ReKi), INTENT( IN ) :: tMG -! REAL(ReKi), INTENT( IN ) :: MGdensity -! REAL(ReKi), INTENT( IN ) :: R_LToG(3,3) -! REAL(ReKi), INTENT( IN ) :: Ca -! REAL(ReKi), INTENT( IN ) :: Cp -! REAL(ReKi), INTENT( IN ) :: AxCa -! REAL(ReKi), INTENT( IN ) :: AxCp -! REAL(ReKi), INTENT( IN ) :: Cd -! REAL(ReKi), INTENT( IN ) :: WaveAcc(3) -! REAL(ReKi), INTENT( IN ) :: WaveDynP -! REAL(ReKi), INTENT( IN ) :: D_dragConst_in ! -! REAL(ReKi), INTENT( OUT ) :: D_AM_M(6,6) ! Added mass of member -! -! REAL(ReKi), INTENT( OUT ) :: D_dragConst ! -! REAL(ReKi), INTENT( OUT ) :: D_F_I(3) ! Inertial force associated with the member -! INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs -! CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None -! REAL(ReKi) :: k(3) -! -! -! IF ( .NOT. PropPot ) THEN ! Member is not modeled with WAMIT -! -! -! ! node is in the water, what about the entire element? -! IF ( elementWaterState == 1 ) THEN -! -! ! Element is in the water -! -! -! ! For buoyancy calculations we need to adjust the Z-location based on MSL2SWL. If MSL2SWL > 0 then SWL above MSL, and so we need to place the Z value at a deeper position. -! ! SWL is at Z=0 for buoyancy calcs, but geometry was specified relative to MSL (MSL2SWL = 0) -! k = R_LToG(:,3) -! CALL DistrInertialLoads( densWater, Ca, Cp, AxCa, AxCp, R, tMG, dRdZ, k, WaveAcc, WaveDynP, D_F_I, ErrStat, ErrMsg ) -! CALL DistrAddedMass( densWater, Ca, AxCa, R_LToG, R, tMG, dRdZ, D_AM_M ) -! -! ELSE -! ! Element is out of the water -! D_F_I (:) = 0.0 -! D_AM_M(:,:) = 0.0 ! This is not time-dependent -! END IF -! -! -! END IF ! IF ( .NOT. nodes(I)%PropPot ) -! -! ! These are the only two loads we compute at initialization if the member is modeled with WAMIT, they are also computed when Morison is used. -! IF ( elementWaterState == 1 )THEN -! ! element is in the water -! D_dragConst = D_dragConst_in -! ELSE -! D_dragConst = 0.0 -! END IF -! -!end subroutine ComputeDistributedLoadsAtNode - - -SUBROUTINE CreateDistributedMesh( densWater, gravity, MSL2SWL, wtrDpth, NStepWave, WaveAcc, WaveDynP, numNodes, nodes, nodeInWater, numElements, elements, & - numDistribMarkers, distribMeshIn, distribMeshOut, distribToNodeIndx, D_F_I, & - D_F_B, D_F_DP, D_F_MG, D_F_BF, D_AM_M, D_AM_MG, D_AM_F, D_dragConst, elementWaterStateArr, & - Morison_Rad, ErrStat, ErrMsg ) - - REAL(ReKi), INTENT( IN ) :: densWater - REAL(ReKi), INTENT( IN ) :: gravity - REAL(ReKi), INTENT( IN ) :: MSL2SWL - REAL(ReKi), INTENT( IN ) :: wtrDpth - INTEGER, INTENT( IN ) :: NStepWave - REAL(SiKi), INTENT( IN ) :: WaveAcc(0:,:,:) - REAL(SiKi), INTENT( IN ) :: WaveDynP(0:,:) - INTEGER, INTENT( IN ) :: numNodes - INTEGER, INTENT( IN ) :: numElements - TYPE(Morison_MemberType), INTENT( IN ) :: elements(:) - TYPE(Morison_NodeType), INTENT( IN ) :: nodes(:) - INTEGER(IntKi), INTENT( IN ) :: nodeInWater(0:,:) ! Flag indicating whether or not a node is in the water at a given wave time - INTEGER, INTENT( OUT ) :: numDistribMarkers - !TYPE(Morison_NodeType), ALLOCATABLE, INTENT( OUT ) :: distribMarkers(:) - TYPE(MeshType), INTENT( OUT ) :: distribMeshIn - TYPE(MeshType), INTENT( OUT ) :: distribMeshOut - INTEGER, ALLOCATABLE, INTENT( OUT ) :: distribToNodeIndx(:) - REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: D_F_I(:,:,:) - REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: D_F_B(:,:) ! Buoyancy force associated with the member - REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: D_F_DP(:,:,:) ! Dynamic pressure force - REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: D_F_MG(:,:) ! Marine growth weight - REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: D_F_BF(:,:) ! Flooded buoyancy force - REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: D_AM_M(:,:,:) ! Added mass of member - REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: D_AM_MG(:) ! Added mass of marine growth - REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: D_AM_F(:) ! Added mass of flooded fluid - REAL(ReKi),ALLOCATABLE, INTENT( OUT) :: D_dragConst(:) ! - INTEGER,ALLOCATABLE, INTENT( OUT) :: elementWaterStateArr(:,:) - REAL(SiKi), ALLOCATABLE, INTENT( OUT ) :: Morison_Rad(:) ! radius of each node (for FAST visualization) - INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - - - INTEGER :: I, J, count, node2Indx - INTEGER :: secondNodeWaterState - TYPE(Morison_MemberType) :: element - TYPE(Morison_NodeType) :: node1, node2 - REAL(ReKi) :: L - REAL(ReKi) :: k(3) - REAL(R8Ki) :: orientation(3,3) - - ! REAL(ReKi),ALLOCATABLE :: F_DP(:,:) - REAL(ReKi) :: F_B(6) - REAL(ReKi) :: F_BF(6) - REAL(ReKi),ALLOCATABLE :: F_I(:,:) - REAL(ReKi) :: z0 - INTEGER, ALLOCATABLE :: nodeToDistribIndx(:) - - numDistribMarkers = 0 - z0 = -(wtrDpth) ! The total sea depth is the still water depth of the seabed - - ! Count how many distributed markers we need to create by looping over the nodes - - DO I=1,numNodes - - IF ( nodes(I)%NodeType /= 3 ) THEN ! exclude super member nodes - - numDistribMarkers = numDistribMarkers + 1 - - END IF - - END DO - - - ! Create the input and output meshes associated with distributed loads - - CALL MeshCreate( BlankMesh = distribMeshIn & - ,IOS = COMPONENT_INPUT & - ,Nnodes = numDistribMarkers & - ,ErrStat = ErrStat & - ,ErrMess = ErrMsg & - ,TranslationDisp = .TRUE. & - ,Orientation = .TRUE. & - ,TranslationVel = .TRUE. & - ,RotationVel = .TRUE. & - ,TranslationAcc = .TRUE. & - ,RotationAcc = .TRUE. ) - - IF ( ErrStat >= AbortErrLev ) RETURN - - CALL AllocAry( Morison_Rad, numDistribMarkers, 'Morison_Rad', ErrStat, ErrMsg) - IF ( ErrStat >= AbortErrLev ) RETURN - - - ! Allocate the array for the distributed markers - - !ALLOCATE ( distribMarkers(numDistribMarkers), STAT = ErrStat ) - !IF ( ErrStat /= ErrID_None ) THEN - ! ErrMsg = ' Error allocating space for the distributed load markers array.' - ! ErrStat = ErrID_Fatal - ! RETURN - !END IF - - ALLOCATE ( distribToNodeIndx(numDistribMarkers), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the distributed index array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - ALLOCATE ( nodeToDistribIndx(numNodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the distributed index array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - - - ALLOCATE ( elementWaterStateArr( 0:NStepWave, numDistribMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the elementWaterStateArr array.' - ErrStat = ErrID_Fatal - RETURN - END IF - elementWaterStateArr = 0 ! out of the water - - ALLOCATE ( D_F_I( 0:NStepWave, 6, numDistribMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the distributed inertial forces/moments array.' - ErrStat = ErrID_Fatal - RETURN - END IF - D_F_I = 0.0 - - ALLOCATE ( D_F_B( 6, numDistribMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the distributed buoyancy forces/moments array.' - ErrStat = ErrID_Fatal - RETURN - END IF - D_F_B = 0.0 - - ALLOCATE ( D_F_DP( 0:NStepWave, 6, numDistribMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the distributed dynamic pressure forces/moments array.' - ErrStat = ErrID_Fatal - RETURN - END IF - D_F_DP = 0.0 - - ALLOCATE ( D_F_MG( 6, numDistribMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the distributed marine growth weight forces/moments array.' - ErrStat = ErrID_Fatal - RETURN - END IF - D_F_MG = 0.0 - - ALLOCATE ( D_F_BF( 6, numDistribMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the distributed buoyancy due to flooding forces/moments array.' - ErrStat = ErrID_Fatal - RETURN - END IF - D_F_BF = 0.0 - - - ALLOCATE ( D_AM_M( 3, 3, numDistribMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the distributed added mass of flooded fluid.' - ErrStat = ErrID_Fatal - RETURN - END IF - D_AM_M = 0.0 - - ALLOCATE ( D_AM_MG( numDistribMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the distributed added mass of marine growth.' - ErrStat = ErrID_Fatal - RETURN - END IF - D_AM_MG = 0.0 - - ALLOCATE ( D_AM_F( numDistribMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the distributed added mass of flooded fluid.' - ErrStat = ErrID_Fatal - RETURN - END IF - D_AM_F = 0.0 - - ALLOCATE ( D_dragConst( numDistribMarkers ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for the distributed drag constants.' - ErrStat = ErrID_Fatal - RETURN - END IF - D_dragConst = 0.0 - - ! Loop over nodes to create all loads on the resulting markers except for the buoyancy loads <---@mhall: what does "create all loads" mean? - ! For the buoyancy loads, loop over the elements and then apply one half of the resulting value - ! to each of the interior element nodes but the full value to an end node. This means that an internal member node will receive 1/2 of its - ! load from element A and 1/2 from element B. If it is the end of a member it will simply receive - ! the element A load. <---@mhall: shouldn't end nodes only receive half too? + end do + + member%Vinner = 0.0_ReKi ! Total volume of member without marine growth + member%Vouter = 0.0_ReKi ! Total outer volume of member including marine growth + member%Vballast = 0.0_ReKi ! Total ballasted volume of member - count = 1 + ! force-related constants for each element + do i = 1, member%NElements - DO I=1,numNodes + Za = InitInp%Nodes(member%NodeIndx( i))%Position(3) ! z location of node i + Zb = InitInp%Nodes(member%NodeIndx(i+1))%Position(3) ! z location of node i+1 - IF ( nodes(I)%NodeType /= 3 ) THEN - - ! End point or internal member node - - ! Find the node index for the other end of this element - !IF ( nodes(I)%NodeType == 1 ) THEN - ! element = elements(nodes(I)%ConnectionList(1)) - ! IF ( element%Node1Indx == I ) THEN - ! node2Indx = element%Node2Indx - ! ELSE - ! node2Indx = element%Node1Indx - ! END IF - !ELSE - ! node2Indx = -1 - !END IF - ! - ! ! Need to see if this node is connected to an element which goes above MSL2SWL or below Seabed. - !IF ( node2Indx > 0 ) THEN - ! IF ( nodes(node2Indx)%JointPos(3) > MSL2SWL ) THEN - ! secondNodeWaterState = 1 - ! ELSE IF ( nodes(node2Indx)%JointPos(3) < z0 ) THEN - ! secondNodeWaterState = 2 - ! ELSE - ! secondNodeWaterState = 0 - ! END IF - !ELSE - ! secondNodeWaterState = 0 - !END IF - - !CALL GetDistance( element - ! ! Compute all initialization forces now so we have access to the element information - ! - IF ( .NOT. nodes(I)%PropPot .AND. nodes(I)%JointPos(3) >= z0 ) THEN - - ! Member is not modeled with WAMIT - - k = nodes(I)%R_LToG(:,3) - - ! IF ( nodes(I)%JointPos(3) <= MSL2SWL .AND. nodes(I)%JointPos(3) >= z0 ) THEN - - - CALL DistrAddedMass( densWater, nodes(I)%Ca, nodes(I)%AxCa, nodes(I)%R_LToG, nodes(I)%R, nodes(I)%tMG, nodes(I)%dRdZ, D_AM_M(:,:,count) ) - ! IF ( secondNodeWaterState == 0 ) THEN - ! Element is in the water - - - !CALL DistrDynPressure( I, nodes(I)%AxCa,nodes(I)%AxCp, nodes(I)%R_LToG, nodes(I)%R, nodes(I)%tMG, nodes(I)%dRdz, NStepWave, WaveDynP, WaveAcc, F_DP, ErrStat, ErrMsg) - ! D_F_DP(:,:,count) = 0.0 !F_DP - ! For buoyancy calculations we need to adjust the Z-location based on MSL2SWL. If MSL2SWL > 0 then SWL above MSL, and so we need to place the Z value at a deeper position. - ! SWL is at Z=0 for buoyancy calcs, but geometry was specified relative to MSL (MSL2SWL = 0) - CALL DistrBuoyancy( densWater, nodes(I)%R, nodes(I)%tMG, nodes(I)%dRdz, nodes(I)%JointPos(3) - MSL2SWL, nodes(I)%R_LToG, gravity, F_B ) - D_F_B(:,count) = F_B - ! ! Compute all initialization forces now so we have access to the element information - ! - ! IF ( ( .NOT. nodes(J)%PropPot ) .AND. ( nodes(J)%JointPos(3) >= z0 ) ) THEN - ! k = nodes(J)%R_LToG(:,3) - CALL DistrInertialLoads( I, densWater, nodes(I)%Ca, nodes(I)%Cp, nodes(I)%AxCa, nodes(I)%AxCp, nodes(I)%R, nodes(I)%tMG, nodes(I)%dRdZ, k, NStepWave, WaveAcc, WaveDynP, F_I, ErrStat, ErrMsg ) - D_F_I(:,:,count) = F_I - - ! END IF + ! ------------------ marine growth weight and inertia ------------------------------------------------ + Vinner_l = 0.0 + Vouter_l = 0.0 + Vinner_U = 0.0 + Vouter_U = 0.0 + if (i > member%i_floor) then + ! full marine growth: get the properties for each half-element lumped to the appropriate node - ! ELSE - ! Element is out of the water - ! D_F_DP(:,:,count) = 0.0 - ! D_F_B(:,count) = 0.0 - - ! END IF - - ! ELSE - ! NOTE: Everything was initialized to zero so this isn't really necessary. GJH 9/24/13 - - ! D_F_DP(:,:,count) = 0.0 - - ! D_F_B(:,count) = 0.0 - ! END IF - - ! IF ( ( nodes(I)%JointPos(3) >= z0 ) .AND. (secondNodeWaterState /= 2 ) ) THEN - ! if the node is at or above the seabed then the element is in the water - CALL DistrMGLoads( nodes(I)%MGdensity, gravity, nodes(I)%R, nodes(I)%tMG, D_F_MG(:,count) ) - CALL DistrAddedMassMG( nodes(I)%MGdensity, nodes(I)%R, nodes(I)%tMG, D_AM_MG(count) ) - ! ELSE - ! D_F_MG(:,count) = 0.0 - ! D_AM_MG(count)= 0.0 - ! END IF - - END IF ! IF ( .NOT. nodes(I)%PropPot ) - - ! This is always computed, but may be zereod out for any given timestep during the CalcOutput work <---@mhall: what is this? - CALL DistrDragConst( densWater, nodes(I)%Cd, nodes(I)%R, nodes(I)%tMG, D_dragConst(count) ) - - IF ( nodes(I)%FillFlag ) THEN - IF ( nodes(I)%JointPos(3) <= nodes(I)%FillFSLoc .AND. nodes(I)%JointPos(3) >= z0 ) THEN - - ! Find the node index for the other end of this element - IF ( nodes(I)%NodeType == 1 ) THEN - element = elements(nodes(I)%ConnectionList(1)) - IF ( element%Node1Indx == I ) THEN - node2Indx = element%Node2Indx - ELSE - node2Indx = element%Node1Indx - END IF - ELSE - node2Indx = -1 - END IF - - ! different check for filled element, based on free-surface location - IF ( node2Indx > 0 ) THEN - IF ( nodes(node2Indx)%JointPos(3) > nodes(I)%FillFSLoc ) THEN - secondNodeWaterState = 0 - ELSE IF ( nodes(node2Indx)%JointPos(3) < z0 ) THEN - secondNodeWaterState = 2 - ELSE - secondNodeWaterState = 1 - END IF - ELSE - secondNodeWaterState = 1 - END IF - - IF (secondNodeWaterState == 1 ) THEN - CALL DistrAddedMassFlood( nodes(I)%FillDensity, nodes(I)%R, nodes(I)%t, D_AM_F(count) ) - ! For buoyancy calculations we need to adjust the Z-location based on MSL2SWL. If MSL2SWL > 0 then SWL above MSL, and so we need to place the Z value at a deeper position. - ! SWL is at Z=0 for buoyancy calcs, but geometry was specified relative to MSL (MSL2SWL = 0) - CALL DistrFloodedBuoyancy( nodes(I)%FillDensity, nodes(I)%FillFSLoc, nodes(I)%R, nodes(I)%t, nodes(I)%dRdZ, nodes(I)%JointPos(3) - MSL2SWL, nodes(I)%R_LToG, gravity, F_BF ) - D_F_BF(:,count ) = F_BF - ELSE - D_AM_F(count) = 0.0 - D_F_BF(:,count ) = 0.0 - END IF - - ELSE - ! NOTE: Everything was initialized to zero so this isn't really necessary. GJH 9/24/13 - D_AM_F(count) = 0.0 - D_F_BF(:,count ) = 0.0 - END IF - ELSE - D_AM_F(count) = 0.0 - D_F_BF(:,count ) = 0.0 - END IF - - - - ! Create the node on the mesh - - orientation = transpose(nodes(I)%R_LToG ) - CALL MeshPositionNode (distribMeshIn & - , count & - , nodes(I)%JointPos & ! this info comes from FAST - , ErrStat & - , ErrMsg & ! , orient = orientation & ! bjj: I need this orientation set for visualization. but, will it mess up calculations (because loads are in different positions?) - ) !, transpose(nodes(I)%R_LToG ) ) - IF ( ErrStat >= AbortErrLev ) RETURN - - Morison_Rad(count) = nodes(I)%R ! set this for FAST visualization - - distribToNodeIndx(count) = I - nodeToDistribIndx(I) = count - count = count + 1 - - END IF - - END DO - - ! Now for time-varying values - - DO count=1,numDistribMarkers - J = distribToNodeIndx(count) - DO I=0,NStepWave - IF ( nodes(J)%NodeType /= 3 ) THEN - - ! End point or internal member node - - ! Find the node index for the other end of this element - IF ( nodes(J)%NodeType == 1 ) THEN - element = elements(nodes(J)%ConnectionList(1)) - IF ( element%Node1Indx == J ) THEN - node2Indx = element%Node2Indx - ELSE - node2Indx = element%Node1Indx - END IF - ELSE - node2Indx = -1 - END IF - - ! Need to see if this node is connected to an element which goes above MSL2SWL or below Seabed. - IF ( node2Indx > 0 ) THEN - IF ( ( nodeInWater(I,node2Indx) == 0 ) .AND. ( nodes(node2Indx)%JointPos(3) >= z0 ) ) THEN - secondNodeWaterState = 0 - ELSE IF ( nodes(node2Indx)%JointPos(3) < z0 ) THEN - secondNodeWaterState = 2 - ELSE - secondNodeWaterState = 1 - END IF - ELSE - secondNodeWaterState = 1 - END IF - - + Rmid = 0.5*(member%R( i)+member%R( i+1)) ! radius at middle of segment, where division occurs + RmidMG = 0.5*(member%RMG(i)+member%RMG(i+1)) ! radius with marine growth at middle of segment, where division occurs + Lmid = 0.5*dl ! = 0.5*(R2-R1)/m half-length of segment + + CALL MarineGrowthPartSegment(member%R(i ), Rmid, member%RMG(i ),RmidMG, Lmid, member%MGDensity(i), Vinner_l, Vouter_l, member%m_mg_l(i), member%h_cmg_l(i), member%I_lmg_l(i), member%I_rmg_l(i)) ! get precomputed quantities for lower half-segment + CALL MarineGrowthPartSegment(member%R(i+1), Rmid, member%RMG(i+1),RmidMG,-Lmid, member%MGDensity(i), Vinner_u, Vouter_u, member%m_mg_u(i), member%h_cmg_u(i), member%I_lmg_u(i), member%I_rmg_u(i)) ! get precomputed quantities for upper half-segment + + else if (i == member%i_floor) then + ! crossing seabed: get the properties for part-element above the seabed and lump to the upper node + + Rmid = (-member%h_floor*member%R( i) +(dl+member%h_floor)*member%R( i+1))/dl + RmidMG = (-member%h_floor*member%RMG(i) +(dl+member%h_floor)*member%RMG(i+1))/dl + Lmid = -member%h_floor + + CALL MarineGrowthPartSegment(member%R(i+1), Rmid, member%RMG(i+1),RmidMG, -Lmid, member%MGDensity(i), Vinner_u, Vouter_u, member%m_mg_u(i), member%h_cmg_u(i), member%I_lmg_u(i), member%I_rmg_u(i)) ! get precomputed quantities for upper half-segment + Vinner_l = 0.0 + Vouter_l = 0.0 + end if + + ! ------------------ flooded ballast inertia --------------------------------------------------------- + Vballast_l = 0.0 + Vballast_U = 0.0 + if (member%memfloodstatus > 0 .and. (member%FillFSLoc > Za)) then + ! Fully filled element, so split in middle + if ((i > member%i_floor) .and. (member%FillFSLoc >= Zb)) then + + ! get the properties for each half-element lumped to the appropriate node + Rmidin = 0.5*(member%Rin(i)+member%Rin(i+1)) ! radius of member interior at middle of segment, where division occurs + Lmid = 0.5*dl ! = 0.5*(R2-R1)/m half-length of segment + CALL FloodedBallastPartSegment(member%Rin(i ), Rmidin, Lmid, member%FillDens, Vballast_l, member%m_fb_l(i), member%h_cfb_l(i), member%I_lfb_l(i), member%I_rfb_l(i)) ! get precomputed quantities for lower half-segment + CALL FloodedBallastPartSegment(member%Rin(i+1), Rmidin, -Lmid, member%FillDens, Vballast_u, member%m_fb_u(i), member%h_cfb_u(i), member%I_lfb_u(i), member%I_rfb_u(i)) ! get precomputed quantities for upper half-segment + + ! partially filled element, so split at FillFSLoc + else if ((i > member%i_floor) .AND. (member%FillFSLoc < Zb)) then + + ! get the properties for each partial-element lumped to the appropriate node + Lmid = member%FillFSLoc - Za + Rmidin = member%Rin(i)+(Lmid/(Zb-Za))*(member%Rin(i+1)-member%Rin(i)) ! radius of member interior at middle of segment, where division occurs + CALL FloodedBallastPartSegment(member%Rin(i ), Rmidin, Lmid, member%FillDens, Vballast_l, member%m_fb_l(i), member%h_cfb_l(i), member%I_lfb_l(i), member%I_rfb_l(i)) ! get precomputed quantities for lower half-segment + CALL FloodedBallastPartSegment(member%Rin(i+1), Rmidin, -Lmid, 0.0, Vballast_u, member%m_fb_u(i), member%h_cfb_u(i), member%I_lfb_u(i), member%I_rfb_u(i)) ! get precomputed quantities for upper half-segment + + else if (i == member%i_floor) then ! Hopefully we don't have a partially filled element crossing the seabed. + + ! crossing seabed: get the properties for part-element above the seabed and lump to the upper node + RmidMG = (-member%h_floor*member%RMG(i) +(dl+member%h_floor)*member%RMG(i+1))/dl + Rmidin = (-member%h_floor*member%Rin(i) +(dl+member%h_floor)*member%Rin(i+1))/dl + Lmid = -member%h_floor + CALL FloodedBallastPartSegment(member%Rin(i+1), Rmidin, -Lmid, member%FillDens, Vballast_u, member%m_fb_u(i), member%h_cfb_u(i), member%I_lfb_u(i), member%I_rfb_u(i)) ! get precomputed quantities for upper half-segment + Vballast_l = 0.0 + + end if + else ! Either no ballast flooding in member, or this particular element isn't flooded at all + Vballast_u = 0.0 + Vballast_l = 0.0 + member%m_fb_u(i) = 0.0 + member%h_cfb_u(i) = 0.0 + member%I_lfb_u(i) = 0.0 + member%I_rfb_u(i) = 0.0 + endif + + + + ! Determine volumes to add to Non-WAMIT modeled members, etc. + if (.not. member%PropPot) then + + if (Zb < -WtrDepth) then + ! fully buried element, do not add these volume contributions to totals + else if (0.0 > Zb) then + ! fully submerged elements. + ! NOTE: For an element which is fractionaly in the seabed, the entire element volume is added to totals + member%Vinner = member%Vinner + Vinner_l + Vinner_u + member%Vouter = member%Vouter + Vouter_l + Vouter_u + member%Vsubmerged = member%Vsubmerged + Vouter_l + Vouter_u + else if ((0.0 > Za) .AND. (0.0 <= Zb)) then + if (i == 1) then + call SetErrStat(ErrID_Fatal, 'The lowest element of a member must not cross the free surface. This is true for MemberID '//trim(num2lstr(member%MemberID)), errStat, errMsg, 'SetMemberProperties') + end if + + ! partially submerged element + member%Vinner = member%Vinner + Vinner_l + Vinner_u + member%Vouter = member%Vouter + Vouter_l + Vouter_u + ! compute volume portion which is submerged + Lmid = -Za/cosPhi + call TaperCalc( member%Rmg(i), member%Rmg(i)+Lmid*member%dRdl_mg(i), Lmid, Vouter_l, h_c) + + member%Vsubmerged = member%Vsubmerged + Vouter_l + + else ! fully above the water + member%Vinner = member%Vinner + Vinner_l + Vinner_u + member%Vouter = member%Vouter + Vouter_l + Vouter_u + end if + end if + + ! ------------------ flooded ballast weight (done) -------------------- + ! NOTE: this section of code is somewhat redundant with "flooded ballast inertia" section above + + li = dl*(i-1) + ! fully buried element + if (Zb < -WtrDepth) then + member%floodstatus(i) = 0 + + ! fully filled elements + else if (member%memfloodstatus > 0 .and. member%FillFSLoc > Zb) then + member%floodstatus(i) = 1 + member%Vballast = member%Vballast + Vballast_l + Vballast_u + ! depth-adjusted force distribution constant + member%alpha_fb_star(i) = member%alpha_fb(i)*( Zb - member%FillFSLoc )**3 / ( ( (1-member%alpha_fb(i))*(Za - member%FillFSLoc))**3 + member%alpha_fb(i)*(Zb - member%FillFSLoc)**3 ) + + ! force and moment magnitude constants + + + member%Cfl_fb(i) = TwoPi * member%dRdl_in(i) * member%FillDens * gravity * dl *( (li - member%l_fill)*member%Rin(i) + 0.5*((li - member%l_fill)* member%dRdl_in(i) + member%Rin(i))*dl + 1.0/3.0* member%dRdl_in(i)*dl**2 ) + member%Cfr_fb(i) = Pi * member%FillDens * gravity * dl *( member%Rin(i)**2 + member%dRdl_in(i)*member%Rin(i)*dl +1.0/3.0 * member%dRdl_in(i)**2 *dl**2 ) + member%CM0_fb(i) = TwoPi * member%FillDens * gravity * dl *( 0.25*dl**3* member%dRdl_in(i)**4 + 0.25*dl**3* member%dRdl_in(i)**2 + dl**2* member%dRdl_in(i)**3*member%Rin(i) + 2.0/3.0*dl**2* member%dRdl_in(i)*member%Rin(i) + 1.5*dl* member%dRdl_in(i)**2*member%Rin(i)**2 + 0.5*dl*member%Rin(i)**2 + member%dRdl_in(i)*member%Rin(i)**3 ) + + + ! partially filled element + else if ((member%memfloodstatus > 0) .and. (member%FillFSLoc > Za) .AND. (member%FillFSLoc < Zb)) then + + ! Need to enforce the modeling requirement that the first/bottom-most element of a member be fully flooded + if (i == 1) then + call SetErrStat(ErrID_Fatal,'The modeling of partially flooded/ballested members requires that the first/bottom-most element of a member must be fully flooded. This is not true for MemberID '//trim(num2lstr(member%MemberID)),ErrStat,ErrMsg,'SetMemberProperties') + return + end if + ! Need to enforce the modeling requirement that a partially flooded member must not be close to horizontal + if ( (InitInp%Nodes(member%NodeIndx(N+1))%Position(3) - member%Rin(N+1)*sinPhi) < member%FillFSLoc ) then + call SetErrStat(ErrID_Fatal,'The modeling of partially flooded/ballested members requires the the member not be near horizontal. This is not true for MemberID '//trim(num2lstr(member%MemberID)),ErrStat,ErrMsg,'SetMemberProperties') + return + end if + + member%floodstatus(i) = 2 + + ! length along axis from node i to fill level + member%h_fill = member%l_fill - (i-1)*dl + !Since this element is only partially flooded/ballasted, compute the Volume fraction which is filled + call TaperCalc( member%Rin(i), member%Rin(i)+member%h_fill*member%dRdl_in(i), member%h_fill, Vballast_l, h_c) + Vballast_u = 0.0 + member%Vballast = member%Vballast + Vballast_l + Vballast_u ! Note: Vballast_l will match calculations above + - - IF ( (nodeInWater(I,J) == 1) .AND. nodes(J)%JointPos(3) >= z0 ) THEN - IF ( secondNodeWaterState == 1 ) THEN - ! Element is in the water - elementWaterStateArr(I,count) = 1 - END IF - END IF + ! depth-adjusted force distribution constant + member%alpha_fb_star(i) = (1 - member%alpha_fb(i))*( Za - member%FillFSLoc )**3 / ( ( (1-member%alpha_fb(i))*(Za - member%FillFSLoc))**3 - member%alpha_fb(i)*(Zb - member%FillFSLoc)**3 ) - END IF + ! force and moment magnitude constants + member%Cfl_fb(i) = TwoPi * member%dRdl_in(i) * member%FillDens * gravity * member%h_fill *( (li - member%l_fill)*member%Rin(i) + 0.5*((li - member%l_fill)*member%dRdl_in(i) + member%Rin(i))*member%h_fill + 1.0/3.0*member%dRdl_in(i)*member%h_fill**2 ) + member%Cfr_fb(i) = Pi * member%FillDens * gravity * member%h_fill *( member%Rin(i)**2 + member%dRdl_in(i)*member%Rin(i)*member%h_fill +1.0/3.0 *member%dRdl_in(i)**2 *member%h_fill**2 ) + member%CM0_fb(i) = TwoPi * member%FillDens * gravity * member%h_fill *( 0.25*member%h_fill**3*member%dRdl_in(i)**4 + 0.25*member%h_fill**3*member%dRdl_in(i)**2 + member%h_fill**2*member%dRdl_in(i)**3*member%Rin(i) + 2.0/3.0*member%h_fill**2*member%dRdl_in(i)*member%Rin(i) & + + 1.5*member%h_fill*member%dRdl_in(i)**2*member%Rin(i)**2 + 0.5*member%h_fill*member%Rin(i)**2 + member%dRdl_in(i)*member%Rin(i)**3 ) & + -0.25 * member%FillDens * gravity * Pi * ( member%Rin(i) + member%h_fill*member%dRdl_in(i))**4 - END DO ! DO I=0,NStepWave - END DO ! DO count=1,numDistribMarkers - - - ! End of time-varying values - - - DO I=1,numElements - - - ! Create the mesh element - - CALL MeshConstructElement ( distribMeshIn & - , ELEMENT_LINE2 & - , ErrStat & - , ErrMsg & - , nodeToDistribIndx(elements(I)%Node1Indx) & - , nodeToDistribIndx(elements(I)%Node2Indx) ) + ! unflooded element + else + member%floodstatus(i) = 0 - IF ( ErrStat /= 0 ) RETURN + end if - - END DO - - - CALL MeshCommit ( distribMeshIn & - , ErrStat & - , ErrMsg ) - - IF ( ErrStat /= 0 ) THEN - RETURN - END IF - - ! Initialize the inputs - DO I=1,distribMeshIn%Nnodes - distribMeshIn%Orientation(:,:,I) = distribMeshIn%RefOrientation(:,:,I) - END DO - distribMeshIn%TranslationDisp = 0.0 - distribMeshIn%TranslationVel = 0.0 - distribMeshIn%RotationVel = 0.0 - distribMeshIn%TranslationAcc = 0.0 - distribMeshIn%RotationAcc = 0.0 - - CALL MeshCopy ( SrcMesh = distribMeshIn & - ,DestMesh = distribMeshOut & - ,CtrlCode = MESH_SIBLING & - ,IOS = COMPONENT_OUTPUT & - ,ErrStat = ErrStat & - ,ErrMess = ErrMsg & - ,Force = .TRUE. & - ,Moment = .TRUE. ) - distribMeshIn%RemapFlag = .TRUE. - distribMeshOut%RemapFlag = .TRUE. - -END SUBROUTINE CreateDistributedMesh - + end do ! end looping through elements + +end subroutine SetMemberProperties -!==================================================================================================== -SUBROUTINE Morison_ProcessMorisonGeometry( InitInp, ErrStat, ErrMsg ) -! This public subroutine process the input geometry and parameters and eliminates joint overlaps, -! sub-divides members, sets joint-level properties, etc. -!---------------------------------------------------------------------------------------------------- - ! Passed variables - - TYPE(Morison_InitInputType), INTENT( INOUT ) :: InitInp ! the Morison initialization data - !TYPE(Morison_ParameterType), INTENT( INOUT ) :: p ! tge Morison parameter data - INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None +subroutine SetupMembers( InitInp, p, m, errStat, errMsg ) + type(Morison_InitInputType), intent (inout) :: InitInp + type(Morison_ParameterType), intent (inout) :: p + type(Morison_MiscVarType), intent (inout) :: m + integer(IntKi), intent ( out) :: errStat ! returns a non-zero value when an error occurs + character(*), intent ( out) :: errMsg ! Error message if errStat /= ErrID_None - - ! Local variables - - INTEGER :: I , J! j1, j2, tempINT ! generic integer for counting -! TYPE(Morison_JointType) :: joint1, joint2 -! Real(ReKi) :: z1 -! Real(ReKi) :: z2 - Real(ReKi) :: d - INTEGER :: temp - INTEGER :: prop1Indx, prop2Indx, node1Indx, node2Indx - INTEGER :: maxNodes = 0 - INTEGER :: maxElements = 0 - INTEGER :: maxSuperMembers = 0 - ! TYPE(Morison_NodeType) :: node1, node2, tempNode - TYPE(Morison_MemberPropType) :: propSet - INTEGER :: numSplitNodes - TYPE(Morison_NodeType),ALLOCATABLE :: splitNodes(:) - LOGICAL :: doSwap - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" + integer(IntKi) :: i, prop1Indx, prop2Indx + integer(IntKi) :: errStat2 ! returns a non-zero value when an error occurs + CHARACTER(errMsgLen) :: errMsg2 ! Error message if errStat2 /= ErrID_None + logical :: doSwap - IF ( InitInp%NMembers > 0 ) THEN - - - ! Determine the maximum number of nodes, elements, and super members which might be generated for the simulation mesh - CALL GetMaxSimQuantities( InitInp%NMGDepths, InitInp%MGTop, InitInp%MGBottom, InitInp%MSL2SWL, -InitInp%WtrDpth, InitInp%FilledGroups, InitInp%NJoints, InitInp%InpJoints, InitInp%NMembers, InitInp%InpMembers, maxNodes, maxElements, maxSuperMembers ) - - - ! Create a worse case size for the number of nodes and number of elements that will be generated for the simulation - ! marine growth split + super member split + member subdivision all creates new nodes - - ! marine growth split + member subdivision creates new elements - - ! Create a worse case size for the number of super members - - ! 1) Let's start by generating a mirror of the input mesh (joints and members) as the initial version of the simulation mesh - ! In doing so, create the initial mapping between the input mesh and this current version of the simulation mesh - - - ! Allocate memory for Joint-related arrays - - InitInp%NNodes = InitInp%NJoints - - ALLOCATE ( InitInp%Nodes(maxNodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for Nodes array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - - DO I = 1,InitInp%NNodes - ! Copy all necessary data from the input joints to these node data structures - InitInp%Nodes(I)%JointPos = InitInp%InpJoints(I)%JointPos - InitInp%Nodes(I)%JointAxIDIndx = InitInp%InpJoints(I)%JointAxIDIndx - InitInp%Nodes(I)%JointOvrlp = InitInp%InpJoints(I)%JointOvrlp - InitInp%Nodes(I)%NConnections = InitInp%InpJoints(I)%NConnections - InitInp%Nodes(I)%ConnectionList = InitInp%InpJoints(I)%ConnectionList - InitInp%Nodes(I)%JointIndx = I - InitInp%Nodes(I)%NodeType = 1 ! 1 = end of a member, 2 = interior of a member, 3 = super member node - InitInp%Nodes(I)%FillFSLoc = InitInp%MSL2SWL - InitInp%Nodes(I)%FillFlag = .FALSE. - InitInp%Nodes(I)%FillDensity = 0.0 - - - - END DO - - - ! Allocate memory for Members arrays - - InitInp%NElements = InitInp%NMembers - - ALLOCATE ( InitInp%Elements(maxElements), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for Elements array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - - DO I = 1,InitInp%NMembers - - InitInp%Elements(I)%Node1Indx = InitInp%InpMembers(I)%MJointID1Indx ! Index of the first node in the Morison_NodeType array - InitInp%Elements(I)%Node2Indx = InitInp%InpMembers(I)%MJointID2Indx ! Index of the second node in the Morison_NodeType array - node1Indx = InitInp%Elements(I)%Node1Indx - node2Indx = InitInp%Elements(I)%Node2Indx - prop1Indx = InitInp%InpMembers(I)%MPropSetID1Indx - prop2Indx = InitInp%InpMembers(I)%MPropSetID2Indx - - ! Make sure that Node1 has the lower Z value, re-order if necessary - ! We need to do this because the local element coordinate system is defined such that the first node is located with a smaller global Z value - ! than the second node. - ! The local element coordinate system requires that Z1 <= Z2, and if Z1=Z2 then X1 <= X2, and if Z1=Z2, X1=X2 then Y1 InitInp%Nodes(node2Indx)%JointPos(2) ) THEN - doSwap = .TRUE. ! Y1 > Y2 - END IF - ELSE IF ( InitInp%Nodes(node1Indx)%JointPos(1) > InitInp%Nodes(node2Indx)%JointPos(1) ) THEN - doSwap = .TRUE. ! X1 > X2 - END IF - ELSE IF ( InitInp%Nodes(node1Indx)%JointPos(3) > InitInp%Nodes(node2Indx)%JointPos(3) ) THEN - doSwap = .TRUE. ! Z1 > Z2 - END IF - - IF ( doSwap ) THEN - - ! Swap node indices to satisfy orientation rules for element nodes - - InitInp%Elements(I)%Node1Indx = InitInp%InpMembers(I)%MJointID2Indx - InitInp%Elements(I)%Node2Indx = InitInp%InpMembers(I)%MJointID1Indx - node1Indx = InitInp%Elements(I)%Node1Indx - node2Indx = InitInp%Elements(I)%Node2Indx - temp = prop1Indx - prop1Indx = prop2Indx - prop2Indx = temp - InitInp%Elements(I)%InpMbrDist1 = 1.0 - InitInp%Elements(I)%InpMbrDist2 = 0.0 - ! --- Swap member coeffs if needed. - ! Fine in this loop since there is a unique CoefMember per Member (otherwise we could swap them several times). - J = InitInp%InpMembers(I)%MmbrCoefIDIndx ! Index in CoefMembers table - IF (J>0) THEN - ! NOTE: SWAP defined at the end of the current subroutine - CALL SWAP(InitInp%CoefMembers(J)%MemberCd1 , InitInp%CoefMembers(J)%MemberCd2) - CALL SWAP(InitInp%CoefMembers(J)%MemberCa1 , InitInp%CoefMembers(J)%MemberCa2) - CALL SWAP(InitInp%CoefMembers(J)%MemberCp1 , InitInp%CoefMembers(J)%MemberCp2) - CALL SWAP(InitInp%CoefMembers(J)%MemberAxCa1 , InitInp%CoefMembers(J)%MemberAxCa2) - CALL SWAP(InitInp%CoefMembers(J)%MemberAxCp1 , InitInp%CoefMembers(J)%MemberAxCp2) - CALL SWAP(InitInp%CoefMembers(J)%MemberCdMG1 , InitInp%CoefMembers(J)%MemberCdMG2) - CALL SWAP(InitInp%CoefMembers(J)%MemberCaMG1 , InitInp%CoefMembers(J)%MemberCaMG2) - CALL SWAP(InitInp%CoefMembers(J)%MemberCpMG1 , InitInp%CoefMembers(J)%MemberCpMG2) - CALL SWAP(InitInp%CoefMembers(J)%MemberAxCaMG1, InitInp%CoefMembers(J)%MemberAxCaMG2) - CALL SWAP(InitInp%CoefMembers(J)%MemberAxCpMG1, InitInp%CoefMembers(J)%MemberAxCpMG2) - END IF - END IF - - propSet = InitInp%MPropSets(prop1Indx) - InitInp%Elements(I)%R1 = propSet%PropD / 2.0 - InitInp%Elements(I)%t1 = propSet%PropThck - - propSet = InitInp%MPropSets(prop2Indx) - InitInp%Elements(I)%R2 = propSet%PropD / 2.0 - InitInp%Elements(I)%t2 = propSet%PropThck - - InitInp%Elements(I)%NumSplits = InitInp%InpMembers(I)%NumSplits - InitInp%Elements(I)%Splits = InitInp%InpMembers(I)%Splits - !InitInp%Elements(I)%MGSplitState = InitInp%InpMembers(I)%MGSplitState - !InitInp%Elements(I)%WtrSplitState = InitInp%InpMembers(I)%WtrSplitState - InitInp%Elements(I)%MDivSize = InitInp%InpMembers(I)%MDivSize - InitInp%Elements(I)%MCoefMod = InitInp%InpMembers(I)%MCoefMod - InitInp%Elements(I)%MmbrCoefIDIndx = InitInp%InpMembers(I)%MmbrCoefIDIndx - InitInp%Elements(I)%MmbrFilledIDIndx = InitInp%InpMembers(I)%MmbrFilledIDIndx - - CALL GetDistance( InitInp%Nodes(node1Indx)%JointPos, InitInp%Nodes(node2Indx)%JointPos, d) - - InitInp%Elements(I)%InpMbrLen = d - InitInp%Elements(I)%InpMbrIndx = I - - ! Direction cosines matrix which transforms a point in member coordinates to the global inertial system - !CALL Morison_DirCosMtrx( node1%JointPos, node2%JointPos, InitInp%Elements(I)%R_LToG ) - + errStat = ErrID_None + errMSg = '' + + ! allocate and copy in the InpMembers array + p%NMembers = InitInp%NMembers + ALLOCATE ( p%Members(p%NMembers), STAT = errStat ) + IF ( errStat /= ErrID_None ) THEN + errMsg = ' Error allocating space for the members array.' + errStat = ErrID_Fatal + RETURN + END IF + + ALLOCATE ( m%MemberLoads(p%NMembers), STAT = errStat ) + IF ( errStat /= ErrID_None ) THEN + errMsg = ' Error allocating space for the memberLoads array.' + errStat = ErrID_Fatal + RETURN + END IF - InitInp%Elements(I)%PropPot = InitInp%InpMembers(I)%PropPot ! Flag specifying whether member is modelled in WAMIT [true = modelled in WAMIT, false = not modelled in WAMIT] - - + do i = 1, p%NMembers + p%Members(i)%MemberID = InitInp%InpMembers(i)%MemberID + p%Members(i)%RefLength = InitInp%InpMembers(i)%RefLength + p%Members(i)%dl = InitInp%InpMembers(i)%dl + p%Members(i)%NElements = InitInp%InpMembers(i)%NElements + p%Members(i)%PropPot = InitInp%InpMembers(i)%PropPot + + call AllocateMemberDataArrays(p%Members(i), m%MemberLoads(i), errStat2, errMsg2) ; call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'SetupMembers') - - ! Calculate the element-level direction cosine matrix and attach it to the entry in the elements array - - CALL Morison_DirCosMtrx( InitInp%Nodes(node1Indx)%JointPos, InitInp%Nodes(node2Indx)%JointPos, InitInp%Elements(I)%R_LToG ) - ! InitInp%Nodes(node1Indx)%R_LToG = InitInp%Elements(I)%R_LToG - ! InitInp%Nodes(node2Indx)%R_LToG = InitInp%Elements(I)%R_LToG - END DO - - - - ! Set the fill properties onto the elements - - CALL SetElementFillProps( InitInp%NFillGroups, InitInp%FilledGroups, InitInp%NElements, InitInp%Elements ) - - ! Split the elements at certain depths according to still water line, internal filled free surface, marine growth transition depths, seabed dpeth, etc. as applicable. - CALL SplitElements(InitInp%NNodes, InitInp%Nodes, InitInp%NElements, InitInp%Elements, ErrStat, ErrMsg) - - ! Split element due to MSL2SWL location and seabed location - !CALL SplitElementsForWtr(InitInp%MSL2SWL, -InitInp%WtrDpth, InitInp%NNodes, InitInp%Nodes, InitInp%NElements, InitInp%Elements, ErrStat, ErrMsg) - - ! Split elements if they cross the marine growth boundary. - - !CALL SplitElementsForMG(InitInp%MGTop, InitInp%MGBottom, InitInp%NNodes, InitInp%Nodes, InitInp%NElements, InitInp%Elements, ErrStat, ErrMsg) - - - ! Create any Super Members - !CALL CreateSuperMembers( InitInp%NNodes, InitInp%Nodes, InitInp%NElements, InitInp%Elements, ErrStat, ErrMsg ) - - ! Subdivide the members based on user-requested maximum division sizes (MDivSize) - - CALL SubdivideMembers( InitInp%NNodes, InitInp%Nodes, InitInp%NElements, InitInp%Elements, ErrStat, ErrMsg ) - - - - ! Set the element Cd, Ca, and Cp coefs - - CALL SetElementCoefs( InitInp%SimplCd, InitInp%SimplCdMG, InitInp%SimplCa, InitInp%SimplCaMG, InitInp%SimplCp, InitInp%SimplCpMG, InitInp%SimplAxCa, InitInp%SimplAxCaMG, InitInp%SimplAxCp, InitInp%SimplAxCpMG,InitInp%CoefMembers, InitInp%NCoefDpth, InitInp%CoefDpths, InitInp%NNodes, InitInp%Nodes, InitInp%NElements, InitInp%Elements ) - - - ! Set the axial coefs AxCd and AxCa - CALL SetAxialCoefs( InitInp%NJoints, InitInp%NAxCoefs, InitInp%AxialCoefs, InitInp%NNodes, InitInp%Nodes, InitInp%NElements, InitInp%Elements ) - - ! Set the marine growth thickness and density information onto the nodes (this is not a per-element quantity, but a per-node quantity - - CALL SetNodeMG( InitInp%NMGDepths, InitInp%MGDepths, InitInp%NNodes, InitInp%Nodes ) - - - ! Create duplicate nodes at the ends of elements so that only one element is connected to any given end node - - CALL SplitMeshNodes( InitInp%NNodes, InitInp%Nodes, InitInp%NElements, InitInp%Elements, numSplitNodes, splitNodes, ErrStat, ErrMsg ) - - IF (numSplitNodes > InitInp%NNodes ) THEN - - InitInp%NNodes = numSplitNodes - !Reallocate the Nodes array - DEALLOCATE ( InitInp%Nodes ) - ALLOCATE ( InitInp%Nodes(numSplitNodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for Nodes array.' - ErrStat = ErrID_Fatal - RETURN - END IF - InitInp%Nodes = splitNodes - DEALLOCATE ( splitNodes ) - - END IF - - - ! Now that the nodes are split, we can push the element properties down to the individual nodes without an issue - - CALL SetSplitNodeProperties( InitInp%NNodes, InitInp%Nodes, InitInp%NElements, InitInp%Elements, ErrStat, ErrMsg ) - - - - - ! 6) Store information necessary to compute the user-requested member outputs and joint outputs. The requested output locations - ! may be located in between two simulation nodes, so quantities will need to be interpolated. qOutput = q1*s + q2*(1-s), where 0<= s <= 1. - - ! NOTE: since we need to mantain the input geometry, the altered members are now part of the simulation mesh and - ! we will generate a mapping between the input and simulation meshes which is needed to generate user-requested outputs. - - - - ELSE - - - ! No Morison elements, so no processing is necessary, but set nodes and elements to 0. - - ! p%NMorisonNodes = 0 - ! p%NMorisonElements = 0 - - END IF - CONTAINS - SUBROUTINE SWAP(x1,x2) - Real(Reki),intent(inout) :: x1,x2 - Real(Reki) :: tmp - tmp = x1 - x1 = x2 - x2 = tmp - END SUBROUTINE SWAP -END SUBROUTINE Morison_ProcessMorisonGeometry - + p%Members(i)%NodeIndx = InitInp%InpMembers(i)%NodeIndx ! now that the parameter version is allocated, copy the data from the InitInp version + + ! only reorder the nodes if the end nodes do not follow the necessary coordinate ordering rules + call FlipMemberNodeData(p%Members(i), InitInp%nodes, doSwap, errStat2, errMsg2) ; call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'SetupMembers') + if (doSwap) then + prop2Indx = InitInp%InpMembers(I)%MPropSetID1Indx + prop1Indx = InitInp%InpMembers(I)%MPropSetID2Indx + else + prop1Indx = InitInp%InpMembers(I)%MPropSetID1Indx + prop2Indx = InitInp%InpMembers(I)%MPropSetID2Indx + end if + ! Now populate the various member data arrays using the HydroDyn input file data + call SetMemberProperties( InitInp%Gravity, p%Members(i), InitInp%InpMembers(i)%MCoefMod, InitInp%InpMembers(i)%MmbrCoefIDIndx, InitInp%InpMembers(i)%MmbrFilledIDIndx, InitInp%MPropSets(prop1Indx), InitInp%MPropSets(prop2Indx), InitInp, errStat2, errMsg2 ) ; call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'SetupMembers') + end do + +end subroutine SetupMembers !---------------------------------------------------------------------------------------------------------------------------------- !> This routine is called at the start of the simulation to perform initialization steps. !! The parameters are set here and not changed during the simulation. !! The initial states and initial guess for the input are defined. -SUBROUTINE Morison_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut, ErrStat, ErrMsg ) +!! A lot of the model setup has been done previously in Morison_ProcessMorisonGeometry, and stored in InitInp. +SUBROUTINE Morison_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut, errStat, errMsg ) !.................................................................................................................................. - TYPE(Morison_InitInputType), INTENT(INOUT) :: InitInp !< Input data for initialization routine !intent out because of MOVE_ALLOC - TYPE(Morison_InputType), INTENT( OUT) :: u !< An initial guess for the input; input mesh must be defined - TYPE(Morison_ParameterType), INTENT( OUT) :: p !< Parameters - TYPE(Morison_ContinuousStateType), INTENT( OUT) :: x !< Initial continuous states - TYPE(Morison_DiscreteStateType), INTENT( OUT) :: xd !< Initial discrete states - TYPE(Morison_ConstraintStateType), INTENT( OUT) :: z !< Initial guess of the constraint states - TYPE(Morison_OtherStateType), INTENT( OUT) :: OtherState !< Initial other states - TYPE(Morison_OutputType), INTENT( OUT) :: y !< Initial system outputs (outputs are not calculated; - !! only the output mesh is initialized) - TYPE(Morison_MiscVarType), INTENT( OUT) :: m !< Initial misc/optimization variables - REAL(DbKi), INTENT(INOUT) :: Interval !< Coupling interval in seconds: the rate that - !! (1) Morison_UpdateStates() is called in loose coupling & - !! (2) Morison_UpdateDiscState() is called in tight coupling. - !! Input is the suggested time from the glue code; - !! Output is the actual coupling interval that will be used - !! by the glue code. - TYPE(Morison_InitOutputType), INTENT( OUT) :: InitOut !< Output for initialization routine - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! TYPE(Morison_InitInputType) :: InitLocal ! Local version of the input data for the geometry processing routine -! INTEGER, ALLOCATABLE :: distribToNodeIndx(:) -! INTEGER, ALLOCATABLE :: lumpedToNodeIndx(:) - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - - - ! Initialize the NWTC Subroutine Library - - CALL NWTC_Init( ) - - - ! InitLocal = InitInp - p%WtrDens = InitInp%WtrDens - p%NumOuts = InitInp%NumOuts - p%NMOutputs = InitInp%NMOutputs ! Number of members to output [ >=0 and <10] - p%OutSwtch = InitInp%OutSwtch - ALLOCATE ( p%MOutLst(p%NMOutputs), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for MOutLst array.' - ErrStat = ErrID_Fatal - RETURN - END IF -IF (ALLOCATED(InitInp%MOutLst) ) & - p%MOutLst = InitInp%MOutLst ! Member output data - - p%NJOutputs = InitInp%NJOutputs ! Number of joints to output [ >=0 and <10] - - ALLOCATE ( p%JOutLst(p%NJOutputs), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for JOutLst array.' - ErrStat = ErrID_Fatal - RETURN - END IF -IF (ALLOCATED(InitInp%JOutLst) ) & - p%JOutLst = InitInp%JOutLst ! Joint output data - - - - - - p%NNodes = InitInp%NNodes - - ALLOCATE ( p%Nodes(p%NNodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for Nodes array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - p%Nodes = InitInp%Nodes - - - p%NStepWave= InitInp%NStepWave - - ALLOCATE ( p%WaveVel(0:p%NStepWave, p%NNodes, 3), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for wave velocities array.' - ErrStat = ErrID_Fatal - RETURN - END IF - p%WaveVel = InitInp%WaveVel - - ALLOCATE ( p%WaveAcc(0:p%NStepWave, p%NNodes, 3), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for wave accelerations array.' - ErrStat = ErrID_Fatal - RETURN - END IF - p%WaveAcc = InitInp%WaveAcc - - ALLOCATE ( p%WaveDynP(0:p%NStepWave, p%NNodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for wave dynamic pressure array.' - ErrStat = ErrID_Fatal - RETURN - END IF - p%WaveDynP = InitInp%WaveDynP - - - - ALLOCATE ( p%WaveTime(0:p%NStepWave), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for wave time array.' - ErrStat = ErrID_Fatal - RETURN - END IF - p%WaveTime = InitInp%WaveTime + TYPE(Morison_InitInputType), INTENT(INOUT) :: InitInp !< Input data for initialization routine !intent out because of MOVE_ALLOC + TYPE(Morison_InputType), INTENT( OUT) :: u !< An initial guess for the input; input mesh must be defined + TYPE(Morison_ParameterType), INTENT( OUT) :: p !< Parameters + TYPE(Morison_ContinuousStateType), INTENT( OUT) :: x !< Initial continuous states + TYPE(Morison_DiscreteStateType), INTENT( OUT) :: xd !< Initial discrete states + TYPE(Morison_ConstraintStateType), INTENT( OUT) :: z !< Initial guess of the constraint states + TYPE(Morison_OtherStateType), INTENT( OUT) :: OtherState !< Initial other states (this contains the Members array) + TYPE(Morison_OutputType), INTENT( OUT) :: y !< Initial system outputs (outputs are not calculated; + !! only the output mesh is initialized) + TYPE(Morison_MiscVarType), INTENT( OUT) :: m !< Initial misc/optimization variables + REAL(DbKi), INTENT(INOUT) :: Interval !< Coupling interval in seconds: the rate that + !! (1) Morison_UpdateStates() is called in loose coupling & + !! (2) Morison_UpdateDiscState() is called in tight coupling. + !! Input is the suggested time from the glue code; + !! Output is the actual coupling interval that will be used + !! by the glue code. + TYPE(Morison_InitOutputType), INTENT( OUT) :: InitOut !< Output for initialization routine + INTEGER(IntKi), INTENT( OUT) :: errStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: errMsg !< Error message if errStat /= ErrID_None + + TYPE(Morison_MemberType) :: member ! the current member + type(Morison_MemberInputType) :: inpMember ! current input file-based member + INTEGER :: N, i, j, count + REAL(ReKi) :: dl + REAL(ReKi) :: vec(3),v2D(3,1) + REAL(ReKi) :: phi ! member tilt angle + REAL(ReKi) :: beta ! member tilt heading + REAL(ReKi) :: cosPhi + REAL(ReKi) :: sinPhi + REAL(ReKi) :: tanPhi + REAL(ReKi) :: sinBeta + REAL(ReKi) :: cosBeta + REAL(ReKi) :: Za + REAL(ReKi) :: Zb + real(ReKi) :: memLength ! reference member length + real(ReKi) :: An(3), An_drag(3), Vn(3), I_n(3), Z0, sgn, Amag, Amag_drag, Vmag, Imag, Ir_MG_end, Il_MG_end, R_I(3,3), IRl_mat(3,3), tMG, MGdens, F_I(3), F_DP(3), af(3), VnDotAf + integer(IntKi) :: MemberEndIndx, ncommon + INTEGER, ALLOCATABLE :: commonNodeLst(:) + LOGICAL, ALLOCATABLE :: usedJointList(:) + integer(IntKi) :: errStat2 ! returns a non-zero value when an error occurs + CHARACTER(errMsgLen) :: errMsg2 ! Error message if errStat2 /= ErrID_None - CALL MOVE_ALLOC( InitInp%nodeInWater, p%nodeInWater ) + ! Initialize errStat + errStat = ErrID_None + errMsg = "" + + ! Initialize the NWTC Subroutine Library + CALL NWTC_Init( ) + + ! Define parameters here: + p%DT = Interval + p%WtrDens = InitInp%WtrDens + p%WtrDpth = InitInp%WtrDpth + p%Gravity = InitInp%Gravity + p%NNodes = InitInp%NNodes + p%NJoints = InitInp%NJoints + p%NStepWave = InitInp%NStepWave + p%NumOuts = InitInp%NumOuts + p%NMOutputs = InitInp%NMOutputs ! Number of members to output [ >=0 and <10] + p%OutSwtch = InitInp%OutSwtch + + ALLOCATE ( p%MOutLst(p%NMOutputs), STAT = errStat ) + IF ( errStat /= ErrID_None ) THEN + errMsg = ' Error allocating space for MOutLst array.' + errStat = ErrID_Fatal + RETURN + END IF + IF (ALLOCATED(InitInp%MOutLst) ) & + p%MOutLst = InitInp%MOutLst ! Member output data - ! Use the processed geometry information to create the distributed load mesh and associated marker parameters - - ! We are storing the parameters in the DistribMarkers data structure instead of trying to hold this information within the DistribMesh. But these two data structures - ! must always be in sync. For example, the 5th element of the DistribMarkers array must correspond to the 5th node in the DistribMesh data structure. - - CALL CreateDistributedMesh( InitInp%WtrDens, InitInp%Gravity, InitInp%MSL2SWL, InitInp%WtrDpth, InitInp%NStepWave, InitInp%WaveAcc, InitInp%WaveDynP, & - p%NNodes, p%Nodes, p%nodeInWater, InitInp%NElements, InitInp%Elements, & - p%NDistribMarkers, u%DistribMesh, y%DistribMesh, p%distribToNodeIndx, p%D_F_I, & - p%D_F_B, p%D_F_DP, p%D_F_MG, p%D_F_BF, p%D_AM_M, p%D_AM_MG, p%D_AM_F, p%D_dragConst, p%elementWaterState, & ! - InitOut%Morison_Rad, ErrStat, ErrMsg ) - - - !@mhall: D_F_BF must become a variable rather than a parameter! <<<< - - - IF ( ErrStat > ErrID_None ) RETURN - - - CALL CreateLumpedMesh( InitInp%WtrDens, InitInp%Gravity, InitInp%MSL2SWL, InitInp%WtrDpth, InitInp%NStepWave, InitInp%WaveDynP, InitInp%WaveAcc,p%NNodes, p%Nodes, InitInp%NElements, InitInp%Elements, & - p%NLumpedMarkers, u%LumpedMesh, y%LumpedMesh, p%lumpedToNodeIndx, p%L_An, & - p%L_F_B, p%L_F_I, p%L_F_BF, p%L_AM_M, p%L_dragConst, & - ErrStat, ErrMsg ) - IF ( ErrStat > ErrID_None ) RETURN - - - - ! CALL CreateSuperMesh( InitInp%NNodes, InitInp%Nodes, InitInp%NElements, InitInp%Elements, p%NSuperMarkers, p%SuperMarkers, InitOut%LumpedMesh, ErrStat, ErrMsg ) + p%NJOutputs = InitInp%NJOutputs ! Number of joints to output [ >=0 and <10] - - + ALLOCATE ( p%JOutLst(p%NJOutputs), STAT = errStat ) + IF ( errStat /= ErrID_None ) THEN + errMsg = ' Error allocating space for JOutLst array.' + errStat = ErrID_Fatal + RETURN + END IF + IF (ALLOCATED(InitInp%JOutLst) ) & + p%JOutLst = InitInp%JOutLst ! Joint output data + + ! ----------------------- set up the members ----------------------- + call SetupMembers( InitInp, p, m, errStat2, errMsg2 ) ; call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'Morison_Init' ) + if ( errStat >= AbortErrLev ) return + + !------------------------ set up joint (or joint-node) properties -- + do i = 1, InitInp%NJoints + InitInp%Nodes(i)%JAxCd = InitInp%AxialCoefs(InitInp%InpJoints(i)%JointAxIDIndx)%AxCd + InitInp%Nodes(i)%JAxCa = InitInp%AxialCoefs(InitInp%InpJoints(i)%JointAxIDIndx)%AxCa + InitInp%Nodes(i)%JAxCp = InitInp%AxialCoefs(InitInp%InpJoints(i)%JointAxIDIndx)%AxCp + InitInp%Nodes(i)%JAxCd = InitInp%AxialCoefs(InitInp%InpJoints(i)%JointAxIDIndx)%AxCd + InitInp%Nodes(i)%JAxCa = InitInp%AxialCoefs(InitInp%InpJoints(i)%JointAxIDIndx)%AxCa + InitInp%Nodes(i)%JAxCp = InitInp%AxialCoefs(InitInp%InpJoints(i)%JointAxIDIndx)%AxCp + ! Redundant work (these are already assigned to the member data arrays, + ! but is needed on the joint data because we report the tMG, and MGDensity at each Joint node in the Summary File + call SetNodeMG( InitInp%NMGDepths, InitInp%MGDepths, InitInp%Nodes(i), InitInp%Nodes(i)%tMG, InitInp%Nodes(i)%MGDensity ) + end do + + ! allocate and copy in node-based load and hydrodynamic arrays + call AllocateNodeLoadVariables(InitInp, p, m, p%NNodes, errStat, errMsg ) + call MOVE_ALLOC( InitInp%nodeInWater, p%nodeInWater ) + + + + ! Create the input and output meshes associated with loads at the nodes + CALL MeshCreate( BlankMesh = u%Mesh & + ,IOS = COMPONENT_INPUT & + ,Nnodes = p%NNodes & + ,errStat = errStat & + ,ErrMess = errMsg & + ,TranslationDisp = .TRUE. & + ,Orientation = .TRUE. & + ,TranslationVel = .TRUE. & + ,RotationVel = .TRUE. & + ,TranslationAcc = .TRUE. & + ,RotationAcc = .TRUE. ) + + IF ( errStat >= AbortErrLev ) RETURN + +!TODO: Do we still need this for visualization? How is it used? GJH 3/26/2020 Actually need a line mesh to properly visualize the members + !CALL AllocAry( Morison_Rad, numDistribMarkers, 'Morison_Rad', errStat, errMsg) + !IF ( errStat >= AbortErrLev ) RETURN + + + DO I=1,p%NNodes + + ! Create the node on the mesh + CALL MeshPositionNode (u%Mesh & + , i & + , InitInp%Nodes(I)%Position & ! this info comes from HydroDyn input file and the subroutine: Morison_GenerateSimulationNodes + , errStat & + , errMsg & + ) !, transpose(p%Nodes(I)%R_LToG) ) + IF ( errStat /= 0 ) RETURN + +!TODO: Do we still need this for visualization? How is it used? GJH 3/26/2020 Actually need a line mesh to properly visualize the members + ! Morison_Rad(count) = p%Nodes(I)%R ! set this for FAST visualization - ! Define parameters here: - - p%DT = Interval + + ! Create the mesh element + + CALL MeshConstructElement (u%Mesh & + , ELEMENT_POINT & + , errStat & + , errMsg & + , i & + ) + + END DO + CALL MeshCommit ( u%Mesh & + , errStat & + , errMsg ) + + IF ( errStat /= 0 ) THEN + RETURN + END IF + + ! Initialize the inputs + DO I=1,u%Mesh%Nnodes + u%Mesh%Orientation(:,:,I) = u%Mesh%RefOrientation(:,:,I) + END DO + + u%Mesh%TranslationDisp = 0.0 + u%Mesh%TranslationVel = 0.0 + u%Mesh%RotationVel = 0.0 + u%Mesh%TranslationAcc = 0.0 + u%Mesh%RotationAcc = 0.0 + + ! Duplicate the input mesh to create the output mesh + CALL MeshCopy ( SrcMesh = u%Mesh & + ,DestMesh = y%Mesh & + ,CtrlCode = MESH_SIBLING & + ,IOS = COMPONENT_OUTPUT & + ,errStat = errStat & + ,ErrMess = errMsg & + ,Force = .TRUE. & + ,Moment = .TRUE. ) + u%Mesh%RemapFlag = .TRUE. + y%Mesh%RemapFlag = .TRUE. ! Define initial system states here: - x%DummyContState = 0 - xd%DummyDiscState = 0 - z%DummyConstrState = 0 - OtherState%DummyOtherState = 0 - m%LastIndWave = 1 - - IF ( p%OutSwtch > 0 ) THEN - ALLOCATE ( m%D_F_D(3,y%DistribMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for D_F_D array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%D_F_D = 0.0_ReKi - ALLOCATE ( m%D_F_I(3,y%DistribMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for D_F_I array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%D_F_I = 0.0_ReKi - ALLOCATE ( m%D_F_B(6,y%DistribMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for D_F_B array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%D_F_B = 0.0_ReKi - ALLOCATE ( m%D_F_AM(6,y%DistribMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for D_F_AM array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%D_F_AM = 0.0_ReKi - ALLOCATE ( m%D_F_AM_M(6,y%DistribMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for D_F_AM_M array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%D_F_AM_M = 0.0_ReKi - ALLOCATE ( m%D_F_AM_MG(6,y%DistribMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for D_F_AM_MG array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%D_F_AM_MG = 0.0_ReKi - ALLOCATE ( m%D_F_AM_F(6,y%DistribMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for D_F_AM_F array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%D_F_AM_F = 0.0_ReKi - ALLOCATE ( m%D_FV(3,y%DistribMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for D_FV array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%D_FV = 0.0_ReKi - ALLOCATE ( m%D_FA(3,y%DistribMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for D_FA array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%D_FA = 0.0_ReKi - ALLOCATE ( m%D_FDynP(y%DistribMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for D_FDynP array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%D_FDynP = 0.0_ReKi - - ALLOCATE ( m%L_F_B(6,y%LumpedMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for L_F_B array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%L_F_B = 0.0_ReKi - ALLOCATE ( m%L_F_D(3,y%LumpedMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for L_F_D array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%L_F_D = 0.0_ReKi - ALLOCATE ( m%L_F_I(6,y%LumpedMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for L_F_I array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%L_F_I = 0.0_ReKi - !ALLOCATE ( m%L_F_DP(6,y%LumpedMesh%Nnodes), STAT = ErrStat ) - !IF ( ErrStat /= ErrID_None ) THEN - ! ErrMsg = ' Error allocating space for L_F_DP array.' - ! ErrStat = ErrID_Fatal - ! RETURN - !END IF - ALLOCATE ( m%L_FV(3,y%LumpedMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for L_FV array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%L_FV = 0.0_ReKi - ALLOCATE ( m%L_FA(3,y%LumpedMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for L_FA array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%L_FA = 0.0_ReKi - ALLOCATE ( m%L_FDynP(y%LumpedMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for L_FDynP array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%L_FDynP = 0.0_ReKi - ALLOCATE ( m%L_F_AM(6,y%LumpedMesh%Nnodes), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for L_F_AM array.' - ErrStat = ErrID_Fatal - RETURN - END IF - m%L_F_AM = 0.0_ReKi + x%DummyContState = 0 + xd%DummyDiscState = 0 + z%DummyConstrState = 0 + OtherState%DummyOtherState = 0 + m%LastIndWave = 1 + + ! IF ( p%OutSwtch > 0 ) THEN @mhall: I think the below need to be allocated in all cases + + + + ! allocate and initialize joint-specific arrays - ! Define initial guess for the system inputs here: + ALLOCATE ( commonNodeLst(10), STAT = errStat ) + IF ( errStat /= ErrID_None ) THEN + errMsg = ' Error allocating space for the commonNodeLst array.' + errStat = ErrID_Fatal + RETURN + END IF + commonNodeLst = -1 + + ALLOCATE ( usedJointList(p%NJoints), STAT = errStat ) + IF ( errStat /= ErrID_None ) THEN + errMsg = ' Error allocating space for the UsedJointList array.' + errStat = ErrID_Fatal + RETURN + END IF + usedJointList = .FALSE. + + ! loop through joints to calculate joint quantities (the joints are the first NJoints nodes) + + usedJointList = .FALSE. + commonNodeLst = -1 + !TODO: Error Handling + + + do i = 1,p%NJoints - ! u%DummyInput = 0 + An = 0.0 + Vn = 0.0 + I_n = 0.0 + MGdens = 0.0 + tMG = -999.0 + An_drag = 0.0 + + IF ( InitInp%InpJoints(i)%Position(3) >= -p%WtrDpth ) THEN + + ! loop through each member attached to the joint, getting the radius of its appropriate end + DO J = 1, InitInp%InpJoints(I)%NConnections + + ! identify attached member and which end to us + IF (InitInp%InpJoints(I)%ConnectionList(J) > 0) THEN ! set up for end node 1 + !TODO: Should not perform a copy here? A pointer to data would be better? + member = p%Members(InitInp%InpJoints(I)%ConnectionList(J)) + MemberEndIndx = 1 + ELSE + ! set up for end node N+1 + ! NOTE: %ConnectionList(J) is negative valued if InitInp%Morison%InpMembers(I)%MJointID2 == InitInp%Morison%InpJoints(J)%JointID. See HydroDynInput_ProcessInitData, members section + member = p%Members(-InitInp%InpJoints(I)%ConnectionList(J)) + MemberEndIndx = member%NElements + 1 + END IF + + ! Compute the signed area*outward facing normal of this member + sgn = 1.0 + + IF ( MemberEndIndx == 1 ) THEN + sgn = -1.0 ! Local coord sys points into member at starting node, so flip sign of local z vector + ELSE + sgn = 1.0 ! Local coord sys points out of member at ending node, so leave sign of local z vector + END IF + ! Account for reordering of what the original node for the end was -- This affects the sign of the An term which can pose a problem for members crossing the waterline + if (member%Flipped) sgn = -1.0 * sgn + + ! Compute the signed quantities for this member end (for drag regardless of PropPot value), and add them to the joint values + An_drag = An_drag + sgn* member%k*Pi*(member%RMG(MemberEndIndx))**2 ! area-weighted normal vector + + ! For the following quantities, the attached member cannot be modeled using WAMIT if we're to count it + IF (.NOT. member%PropPot) THEN + + ! Compute the signed quantities for this member end, and add them to the joint values + An = An + sgn* member%k*Pi*(member%RMG(MemberEndIndx))**2 ! area-weighted normal vector + Vn = Vn + sgn* member%k* (member%RMG(MemberEndIndx))**3 ! r^3-weighted normal vector used for mass + I_n=I_n + sgn* member%k*Pi*(member%RMG(MemberEndIndx))**4 ! r^4-weighted normal vector used for moments of inertia + if (tMG == -999.0) then + ! All member nodes at this joint will have the same MG thickness and density, so only do this once + tMG = member%tMG(MemberEndIndx) + MGdens = member%MGdensity(MemberEndIndx) + end if + END IF + + END DO !J = 1, InitInp%InpJoints(I)%NConnections + + p%An_End(:,i) = An_drag + Amag_drag = Dot_Product(An_drag ,An_drag) + Amag = Dot_Product(An ,An) + IF (EqualRealNos(Amag_drag, 0.0_ReKi)) THEN + p%DragConst_End(i) = 0.0 + ELSE + p%DragConst_End(i) = InitInp%Nodes(i)%JAxCd*p%WtrDens / ( 4.0_ReKi * Amag_drag ) + END IF + ! magnitudes of normal-weighted values + Amag = sqrt(Amag) + Vmag = sqrt(Dot_Product(Vn ,Vn)) + Imag = sqrt(Dot_Product(I_n,I_n)) + + ! Constant part of the external hydrodynamic added mass term + if ( Vmag > 0.0 ) then + v2D(:,1) = Vn + p%AM_End(:,:,i) = (InitInp%Nodes(I)%JAxCa*InitInp%WtrDens/ Vmag)*matmul(transpose(v2D), v2D) + end if + + ! Constant part of the external hydrodynamic dynamic pressure force + if ( Amag > 0.0 ) then + p%DP_Const_End(:,i) = -InitInp%Nodes(i)%JAxCp*An + endif + + ! marine growth mass/inertia magnitudes + p%Mass_MG_End(i) = MGdens * tMG * Amag + p%F_WMG_End(3,i) = -MGdens * tMG * Amag * InitInp%Gravity ! Z component of the directional force due to marine growth mass at joint + Ir_MG_end = 0.25 * MGdens * tMG * Imag ! radial moment of inertia magnitude + Il_MG_end = 0.5 * MGdens * tMG * Imag ! axial moment of inertia magnitude + + ! get rotation matrix for moment of inertia orientations + call RodrigMat(I_n, R_I, errStat, errMsg) - ! Define system output initializations (set up mesh) here: - + ! globally-oreinted moment of inertia matrix for joint + Irl_mat = 0.0 + Irl_mat(1,1) = Ir_MG_end + Irl_mat(2,2) = Ir_MG_end + Irl_mat(3,3) = Il_MG_end + + p%I_MG_End(:,:,i) = MatMul( MatMul(R_I, Irl_mat), Transpose(R_I) ) ! final moment of inertia matrix for node + + END IF ! InitInp%InpJoints(i)%Position(3) >= -p%WtrDpth + + END DO ! looping through nodes that are joints, i + + ! Define initial guess for the system inputs here: + ! u%DummyInput = 0 + ! Define system output initializations (set up mesh) here: ! Define initialization-routine output here: - ! Initialize the outputs - - CALL MrsnOUT_Init( InitInp, y, p, InitOut, ErrStat, ErrMsg ) - IF ( ErrStat > ErrID_None ) RETURN + ! Initialize the outputs + IF ( p%OutSwtch > 0) then !@mhall: moved this "if" to after allocations + + CALL MrsnOUT_Init( InitInp, y, p, InitOut, errStat, errMsg ) + IF ( errStat > AbortErrLev ) RETURN ! Determine if we need to perform output file handling IF ( p%OutSwtch == 1 .OR. p%OutSwtch == 3 ) THEN - CALL MrsnOUT_OpenOutput( Morison_ProgDesc%Name, TRIM(InitInp%OutRootName)//'.HD', p, InitOut, ErrStat, ErrMsg ) - IF ( ErrStat > ErrID_None ) RETURN + CALL MrsnOUT_OpenOutput( Morison_ProgDesc%Name, TRIM(InitInp%OutRootName)//'.HD', p, InitOut, errStat, errMsg ) + IF ( errStat > AbortErrLev ) RETURN END IF END IF + ! We will call CalcOutput to compute the loads for the initial reference position + ! Then we can use the computed load components in the Summary File + ! NOTE: Morison module has no states, otherwise we could no do this. GJH - ! Write Summary information now that everything has been initialized. - - CALL WriteSummaryFile( InitInp%UnSum, InitInp%MSL2SWL, InitInp%WtrDpth, InitInp%NNodes, InitInp%Nodes, InitInp%NElements, InitInp%Elements, p%NumOuts, p%OutParam, p%NMOutputs, p%MOutLst, p%distribToNodeIndx, p%NJOutputs, p%JOutLst, u%LumpedMesh, y%LumpedMesh,u%DistribMesh, y%DistribMesh, p%L_F_B, p%L_F_BF, p%D_F_B, p%D_F_BF, p%D_F_MG, InitInp%Gravity, ErrStat, ErrMsg ) !p%NDistribMarkers, distribMarkers, p%NLumpedMarkers, lumpedMarkers, - IF ( ErrStat > ErrID_None ) RETURN - - ! If you want to choose your own rate instead of using what the glue code suggests, tell the glue code the rate at which - ! this module must be called here: - - !Interval = p%DT + call Morison_CalcOutput(0.0_DbKi, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ) + + ! Write Summary information now that everything has been initialized. + CALL WriteSummaryFile( InitInp%UnSum, InitInp%Gravity, InitInp%MSL2SWL, InitInp%WtrDpth, InitInp%NJoints, InitInp%NNodes, InitInp%Nodes, p%NMembers, p%Members, & + p%NumOuts, p%OutParam, p%NMOutputs, p%MOutLst, p%NJOutputs, p%JOutLst, u%Mesh, y%Mesh, & + p, m, errStat, errMsg ) + IF ( errStat > AbortErrLev ) RETURN + !Contains: ! SUBROUTINE CleanUpInitOnErr ! IF (ALLOCATED(sw(1)%array)) DEALLOCATE(sw(1)%array, STAT=aviFail) @@ -4409,9 +2173,175 @@ SUBROUTINE Morison_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, In END SUBROUTINE Morison_Init +SUBROUTINE RodrigMat(a, R, errStat, errMsg) + ! calculates rotation matrix R to rotate unit vertical vector to direction of input vector a + + REAL(ReKi), INTENT ( IN ) :: a(3) ! input vector + REAL(ReKi), INTENT ( INOUT ) :: R(3,3) ! rotation matrix from Rodrigues's rotation formula + INTEGER(IntKi), INTENT( OUT) :: errStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: errMsg ! Error message if errStat /= ErrID_None + + REAL(ReKi) :: vec(3) ! scaled and adjusted input vector + REAL(ReKi) :: factor ! denomenator used for scaling + factor = Dot_Product(a,a) + if ( EqualRealNos(factor, 0.0_ReKi) ) then + !IF ((a(1) == 0) .AND. (a(2)==0)) THEN ! return identity if vertical + ! CALL EYE(R, errStat,errMsg) + ! IF (a(3) < 0) THEN + ! R = -R + ! END IF + ! + errStat = ErrID_Fatal + errMsg = 'RodrigMat encountered vector of zero length' + else IF ( EqualRealNos(a(1), 0.0_ReKi) .AND. EqualRealNos(a(2), 0.0_ReKi) ) THEN ! return identity if vertical + CALL EYE(R, errStat,errMsg) + IF (a(3) < 0) THEN + R = -R + END IF + else + vec = a/SQRT(factor) ! normalize a + vec(3) = vec(3) + 1 + + factor = 2.0/Dot_Product(vec, vec) + + R(1,1) = factor*vec(1)*vec(1) - 1 + R(1,2) = factor*vec(1)*vec(2) + R(1,3) = factor*vec(1)*vec(3) + R(2,1) = factor*vec(2)*vec(1) + R(2,2) = factor*vec(2)*vec(2) - 1 + R(2,3) = factor*vec(2)*vec(3) + R(3,1) = factor*vec(3)*vec(1) + R(3,2) = factor*vec(3)*vec(2) + R(3,3) = factor*vec(3)*vec(3) - 1 + end if + +END SUBROUTINE RodrigMat + + +FUNCTION GetAlpha(R1,R2) + ! calculates relative center of volume location for a (tapered) cylindrical element + real(ReKi) :: GetAlpha + REAL(ReKi), INTENT ( IN ) :: R1 ! interior radius of element at node point + REAL(ReKi), INTENT ( IN ) :: R2 ! interior radius of other end of part-element + + + GetAlpha = (R1*R1 + 2.0*R1*R2 + 3.0*R2*R2)/4.0/(R1*R1 + R1*R2 + R2*R2) + + +END FUNCTION GetAlpha + + +SUBROUTINE AllocateNodeLoadVariables(InitInp, p, m, NNodes, errStat, errMsg ) + TYPE(Morison_InitInputType), INTENT(IN ) :: InitInp ! Initialization inputs + TYPE(Morison_ParameterType), INTENT(INOUT) :: p ! parameter variables + TYPE(Morison_MiscVarType), INTENT(INOUT) :: m ! Misc/optimization variables + INTEGER(IntKi), INTENT(IN ) :: NNodes ! number of nodes in node list + INTEGER(IntKi), INTENT( OUT) :: errStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: errMsg ! Error message if errStat /= ErrID_None + integer(IntKi) :: errStat2 ! returns a non-zero value when an error occurs + CHARACTER(errMsgLen) :: errMsg2 ! Error message if errStat2 /= ErrID_None + character(*), parameter :: routineName = 'AllocateNodeLoadVariables' + + ! Initialize errStat + + errStat = ErrID_None + errMsg = "" + + call AllocAry( m%nodeInWater , NNodes , 'm%nodeInWater' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( m%vrel , 3, NNodes , 'm%vrel' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + !call AllocAry( m%F_D , 6, NNodes , 'm%F_D' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + !call AllocAry( m%F_A , 6, NNodes , 'm%F_A' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + !call AllocAry( m%F_B , 6, NNodes , 'm%F_B' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + !call AllocAry( m%F_BF , 6, NNodes , 'm%F_BF' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + !call AllocAry( m%F_I , 6, NNodes , 'm%F_I' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + !call AllocAry( m%F_If , 6, NNodes , 'm%F_If' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + !call AllocAry( m%F_WMG , 6, NNodes , 'm%F_WMG' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + !call AllocAry( m%F_IMG , 6, NNodes , 'm%F_IMG' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( m%FV , 3, NNodes , 'm%FV' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( m%FA , 3, NNodes , 'm%FA' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( m%FDynP , NNodes , 'm%FDynP' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( p%An_End , 3, p%NJoints, 'p%An_End' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( p%DragConst_End, p%NJoints, 'p%DragConst_End', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( m%F_I_End , 3, p%NJoints, 'm%F_I_End' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( m%F_BF_End , 6, p%NJoints, 'm%F_BF_End' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( m%F_A_End , 3, p%NJoints, 'm%F_A_End' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( m%F_D_End , 3, p%NJoints, 'm%F_D_End' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( m%F_B_End , 6, p%NJoints, 'm%F_B_End' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( m%F_IMG_End , 6, p%NJoints, 'm%F_IMG_End' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( p%I_MG_End , 3, 3, p%NJoints, 'p%I_MG_End' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( p%F_WMG_End , 3, p%NJoints, 'p%F_WMG_End' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( p%Mass_MG_End , p%NJoints, 'p%Mass_MG_End' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( p%AM_End , 3, 3, p%NJoints, 'p%AM_End' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + call AllocAry( p%DP_Const_End , 3, p%NJoints, 'p%DP_Const_End' , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, routineName) + if (errStat == ErrID_Fatal) return + + m%nodeInWater = 0 + m%vrel = 0.0_ReKi + !m%F_D = 0.0_ReKi + !m%F_A = 0.0_ReKi + !m%F_B = 0.0 + !m%F_BF = 0.0 + !m%F_I = 0.0 + !m%F_If = 0.0 + !m%F_WMG = 0.0 + !m%F_IMG = 0.0 + m%FV = 0.0_ReKi + m%FA = 0.0_ReKi + m%FDynP = 0.0_ReKi + p%An_End = 0.0 + p%DragConst_End = 0.0 + m%F_I_End = 0.0 + m%F_BF_End = 0.0 + m%F_A_End = 0.0 + m%F_D_End = 0.0 + m%F_B_End = 0.0 + m%F_IMG_End = 0.0 + p%DP_Const_End = 0.0 + p%I_MG_End = 0.0 + p%Mass_MG_End = 0.0 + p%F_WMG_End = 0.0 + p%AM_End = 0.0 + + allocate( p%WaveVel(0:p%NStepWave, p%NNodes, 3), STAT = errStat ) + IF ( errStat /= ErrID_None ) THEN + errMsg = ' Error allocating space for wave velocities array.' + errStat = ErrID_Fatal + RETURN + END IF + p%WaveVel = InitInp%WaveVel + + allocate( p%WaveAcc(0:p%NStepWave, p%NNodes, 3), STAT = errStat ) + IF ( errStat /= ErrID_None ) THEN + errMsg = ' Error allocating space for wave accelerations array.' + errStat = ErrID_Fatal + RETURN + END IF + p%WaveAcc = InitInp%WaveAcc + + allocate( p%WaveDynP(0:p%NStepWave, p%NNodes), STAT = errStat ) + IF ( errStat /= ErrID_None ) THEN + errMsg = ' Error allocating space for wave dynamic pressure array.' + errStat = ErrID_Fatal + RETURN + END IF + p%WaveDynP = InitInp%WaveDynP + + allocate( p%WaveTime(0:p%NStepWave), STAT = errStat ) + IF ( errStat /= ErrID_None ) THEN + errMsg = ' Error allocating space for wave time array.' + errStat = ErrID_Fatal + RETURN + END IF + p%WaveTime = InitInp%WaveTime + + +END SUBROUTINE AllocateNodeLoadVariables + + + !---------------------------------------------------------------------------------------------------------------------------------- !> This routine is called at the end of the simulation. -SUBROUTINE Morison_End( u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) +SUBROUTINE Morison_End( u, p, x, xd, z, OtherState, y, m, errStat, errMsg ) !.................................................................................................................................. TYPE(Morison_InputType), INTENT(INOUT) :: u !< System inputs @@ -4422,15 +2352,15 @@ SUBROUTINE Morison_End( u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) TYPE(Morison_OtherStateType), INTENT(INOUT) :: OtherState !< Other states TYPE(Morison_OutputType), INTENT(INOUT) :: y !< System outputs TYPE(Morison_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + INTEGER(IntKi), INTENT( OUT) :: errStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: errMsg !< Error message if errStat /= ErrID_None - ! Initialize ErrStat + ! Initialize errStat - ErrStat = ErrID_None - ErrMsg = "" + errStat = ErrID_None + errMsg = "" ! Place any last minute operations or calculations here: @@ -4442,33 +2372,33 @@ SUBROUTINE Morison_End( u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) ! Destroy the input data: - CALL Morison_DestroyInput( u, ErrStat, ErrMsg ) + CALL Morison_DestroyInput( u, errStat, errMsg ) ! Determine if we need to close the output file IF ( p%OutSwtch == 1 .OR. p%OutSwtch == 3 ) THEN - CALL MrsnOut_CloseOutput( p, ErrStat, ErrMsg ) + CALL MrsnOut_CloseOutput( p, errStat, errMsg ) END IF ! Destroy the parameter data: - CALL Morison_DestroyParam( p, ErrStat, ErrMsg ) + CALL Morison_DestroyParam( p, errStat, errMsg ) ! Destroy the state data: - CALL Morison_DestroyContState( x, ErrStat, ErrMsg ) - CALL Morison_DestroyDiscState( xd, ErrStat, ErrMsg ) - CALL Morison_DestroyConstrState( z, ErrStat, ErrMsg ) - CALL Morison_DestroyOtherState( OtherState, ErrStat, ErrMsg ) + CALL Morison_DestroyContState( x, errStat, errMsg ) + CALL Morison_DestroyDiscState( xd, errStat, errMsg ) + CALL Morison_DestroyConstrState( z, errStat, errMsg ) + CALL Morison_DestroyOtherState( OtherState, errStat, errMsg ) - CALL Morison_DestroyMisc( m, ErrStat, ErrMsg ) + CALL Morison_DestroyMisc( m, errStat, errMsg ) ! Destroy the output data: - CALL Morison_DestroyOutput( y, ErrStat, ErrMsg ) + CALL Morison_DestroyOutput( y, errStat, errMsg ) @@ -4477,7 +2407,7 @@ END SUBROUTINE Morison_End !---------------------------------------------------------------------------------------------------------------------------------- !> This is a loose coupling routine for solving constraint states, integrating continuous states, and updating discrete and other !! states. Continuous, constraint, discrete, and other states are updated to values at t + Interval. -SUBROUTINE Morison_UpdateStates( Time, u, p, x, xd, z, OtherState, m, ErrStat, ErrMsg ) +SUBROUTINE Morison_UpdateStates( Time, u, p, x, xd, z, OtherState, m, errStat, errMsg ) !.................................................................................................................................. REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds @@ -4492,195 +2422,828 @@ SUBROUTINE Morison_UpdateStates( Time, u, p, x, xd, z, OtherState, m, ErrStat, E TYPE(Morison_OtherStateType), INTENT(INOUT) :: OtherState !< Input: Other states at Time; !! Output: Other states at Time + Interval TYPE(Morison_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + INTEGER(IntKi), INTENT( OUT) :: errStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: errMsg !< Error message if errStat /= ErrID_None ! Local variables - INTEGER(IntKi) :: ErrStat2 ! Error status of the operation (occurs after initial error) - CHARACTER(ErrMsgLen) :: ErrMsg2 ! Error message if ErrStat2 /= ErrID_None + INTEGER(IntKi) :: errStat2 ! Error status of the operation (occurs after initial error) + CHARACTER(errMsgLen) :: errMsg2 ! Error message if errStat2 /= ErrID_None - ! Initialize ErrStat + ! Initialize errStat - ErrStat = ErrID_None - ErrMsg = "" + errStat = ErrID_None + errMsg = "" END SUBROUTINE Morison_UpdateStates - -!---------------------------------------------------------------------------------------------------------------------------------- -!> Routine for computing outputs, used in both loose and tight coupling. -SUBROUTINE Morison_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) -!.................................................................................................................................. - +!> This routine is similar to InterpWrappedStpReal, except it returns only the slope for the interpolation. +!! By returning the slope based on Time, we don't have to calculate this for every variable (Yary) we want to interpolate. +!! NOTE: p%WaveTime (and most arrays here) start with index of 0 instead of 1, so we will subtract 1 from "normal" interpolation +!! schemes. +FUNCTION GetInterpolationSlope(Time, p, m, IntWrapIndx) RESULT( InterpSlope ) REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds - TYPE(Morison_InputType), INTENT(IN ) :: u !< Inputs at Time TYPE(Morison_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(Morison_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time - TYPE(Morison_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at Time - TYPE(Morison_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at Time - TYPE(Morison_OtherStateType), INTENT(IN ) :: OtherState !< Other states at Time - TYPE(Morison_OutputType), INTENT(INOUT) :: y !< Outputs computed at Time (Input only so that mesh con- - !! nectivity information does not have to be recalculated) TYPE(Morison_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - REAL(ReKi) :: F_D(6), F_DP(6), D_F_I(3), kvec(3), v(3), vf(3), vrel(3), vmag - INTEGER :: I, J, K, nodeIndx - REAL(ReKi) :: elementWaterState - REAL(ReKi) :: AllOuts(MaxMrsnOutputs) ! TODO: think about adding to OtherState - REAL(ReKi) :: qdotdot(6) ,qdotdot2(3) ! The structural acceleration of a mesh node - !REAL(ReKi) :: accel_fluid(6) ! Acceleration of fluid at the mesh node - REAL(ReKi) :: dragFactor ! The lumped drag factor - REAL(ReKi) :: AnProd ! Dot product of the directional area of the joint - REAL(ReKi) :: F_B(6) - REAL(ReKi) :: C(3,3) - REAL(ReKi) :: sgn - REAL(ReKi) :: D_AM_M(6,6) - REAL(ReKi) :: nodeInWater - REAL(ReKi) :: D_dragConst ! The distributed drag factor - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - - - ! Compute outputs here: + INTEGER, OPTIONAL, INTENT( OUT) :: IntWrapIndx + + REAL(SiKi) :: Time_SiKi + REAL(SiKi) :: TimeMod + REAL(ReKi) :: InterpSlope + + Time_SiKi = REAL(Time, SiKi) + TimeMod = MOD(Time_SiKi, p%WaveTime(p%NStepWave)) !p%WaveTime starts at index 0, so it has p%NStepWave+1 elements + IF ( TimeMod <= p%WaveTime(1) ) THEN !second element + m%LastIndWave = 0 + END IF - ! We need to attach the distributed drag force (D_F_D), distributed inertial force (D_F_I), and distributed dynamic pressure force (D_F_DP) to the Misc type so that we don't need to - ! allocate their data storage at each time step! If we could make them static local variables (like in C) then we could avoid adding them to the OtherState datatype. - ! The same is true for the lumped drag (L_F_D) and the lumped dynamic pressure (L_F_DP) - - DO J = 1, y%DistribMesh%Nnodes - - ! Obtain the node index because WaveVel, WaveAcc, and WaveDynP are defined in the node indexing scheme, not the markers - nodeIndx = p%distribToNodeIndx(J) - - ! Determine in or out of water status for the element which this node is a part of. - ! NOTE: This will find the closest WaveTime index (wvIndx) which is has waveTime(wvIndx) > = Time. If WaveDT = DT then waveTime(wvIndx) will equal Time - ! For WaveMod = 6 or WaveMod = 5 WaveDT must equal DT for the returned value of elementWaterState to be meaningful, for other WaveMod, - ! elementWaterState is the same for all time for a given node, J. - elementWaterState = REAL( InterpWrappedStpInt( REAL(Time, SiKi), p%WaveTime(:), p%elementWaterState(:,J), m%LastIndWave, p%NStepWave + 1 ), ReKi ) - - - ! Determine the dynamic pressure at the marker - m%D_FDynP(J) = InterpWrappedStpReal ( REAL(Time, SiKi), p%WaveTime(:), p%WaveDynP(:,nodeIndx), & - m%LastIndWave, p%NStepWave + 1 ) - - - DO I=1,3 - ! Determine the fluid acceleration and velocity at the marker - m%D_FA(I,J) = InterpWrappedStpReal ( REAL(Time, SiKi), p%WaveTime(:), p%WaveAcc(:,nodeIndx,I), & - m%LastIndWave, p%NStepWave + 1 ) - m%D_FV(I,J) = InterpWrappedStpReal ( REAL(Time, SiKi), p%WaveTime(:), p%WaveVel(:,nodeIndx,I), & - m%LastIndWave, p%NStepWave + 1 ) - - vrel(I) = m%D_FV(I,J) - u%DistribMesh%TranslationVel(I,J) - - m%D_F_I(I,J) = elementWaterState * InterpWrappedStpReal ( REAL(Time, SiKi), p%WaveTime(:), p%D_F_I(:,I,J), & - m%LastIndWave, p%NStepWave + 1 ) - END DO - - ! (k x vrel x k) - kvec = p%Nodes(nodeIndx)%R_LToG(:,3) - v = vrel - Dot_Product(kvec,vrel)*kvec - vmag = sqrt( v(1)*v(1) + v(2)*v(2) + v(3)*v(3) ) - - - ! Distributed added mass loads - ! need to multiply by elementInWater value to zero out loads when out of water - qdotdot2(1) = elementWaterState *u%DistribMesh%TranslationAcc(1,J) - qdotdot2(2) = elementWaterState *u%DistribMesh%TranslationAcc(2,J) - qdotdot2(3) = elementWaterState *u%DistribMesh%TranslationAcc(3,J) - ! calculated the added mass forces (moments are zero) - m%D_F_AM_M(1:3,J) = -matmul( p%D_AM_M (:,:,J) , qdotdot2 ) !bjj: these lines take up a lot of time. are the matrices sparse? + IF ( TimeMod <= p%WaveTime(0) ) THEN + m%LastIndWave = 0 + InterpSlope = 0.0_ReKi ! returns values at m%LastIndWave + IF(PRESENT(IntWrapIndx)) IntWrapIndx = 0 + ELSE IF ( TimeMod >= p%WaveTime(p%NStepWave) ) THEN + m%LastIndWave = p%NStepWave-1 + InterpSlope = 1.0_ReKi ! returns values at p%NStepWave + IF(PRESENT(IntWrapIndx)) IntWrapIndx = p%NStepWave + ELSE + m%LastIndWave = MAX( MIN( m%LastIndWave, p%NStepWave-1 ), 0 ) + + DO + + IF ( TimeMod < p%WaveTime(m%LastIndWave) ) THEN + + m%LastIndWave = m%LastIndWave - 1 + + ELSE IF ( TimeMod >= p%WaveTime(m%LastIndWave+1) ) THEN + + m%LastIndWave = m%LastIndWave + 1 - DO I=1,6 - IF (I < 4 ) THEN - ! We are now combining the dynamic pressure term into the inertia term - m%D_F_AM_MG(I,J) = -p%D_AM_MG(J)*u%DistribMesh%TranslationAcc(I,J) - m%D_F_AM_F(:,J) = -p%D_AM_F(J)*u%DistribMesh%TranslationAcc(I,J) - m%D_F_AM(I,J) = m%D_F_AM_M(I,J) + m%D_F_AM_MG(I,J) + m%D_F_AM_F(I,J) - m%D_F_D(I,J) = elementWaterState * vmag*v(I) * p%D_dragConst(J) - m%D_F_B(I,J) = elementWaterState * p%D_F_B(I,J) - y%DistribMesh%Force(I,J) = m%D_F_AM(I,J) + m%D_F_D(I,J) + m%D_F_I(I,J) + m%D_F_B(I,J) + p%D_F_MG(I,J) + p%D_F_BF(I,J) ELSE - m%D_F_B(I,J) = elementWaterState * p%D_F_B(I,J) - y%DistribMesh%Moment(I-3,J) = m%D_F_B(I,J) + p%D_F_BF(I,J) + IF(PRESENT(IntWrapIndx)) IntWrapIndx = m%LastIndWave + + InterpSlope = ( TimeMod - p%WaveTime(m%LastIndWave) )/( p%WaveTime(m%LastIndWave+1) - p%WaveTime(m%LastIndWave) ) + RETURN ! stop checking DO loop END IF - END DO ! DO I - + + END DO + + END IF + +END FUNCTION GetInterpolationSlope +!> Use in conjunction with GetInterpolationSlope, to replace InterpWrappedStpReal here. +FUNCTION InterpolateWithSlope(InterpSlope, Ind, YAry) + REAL(ReKi), INTENT(IN) :: InterpSlope + INTEGER(IntKi), INTENT(IN ) :: Ind !< Misc/optimization variables + REAL(SiKi), INTENT(IN) :: YAry(0:) + REAL(ReKi) :: InterpolateWithSlope + + InterpolateWithSlope = ( YAry(Ind+1) - YAry(Ind) )*InterpSlope + YAry(Ind) + +END FUNCTION InterpolateWithSlope +!> Use in conjunction with GetInterpolationSlope, to replace InterpWrappedStpReal here. +FUNCTION InterpolateWithSlopeR(InterpSlope, Ind, YAry) + REAL(ReKi), INTENT(IN) :: InterpSlope + INTEGER(IntKi), INTENT(IN ) :: Ind !< Misc/optimization variables + REAL(ReKi), INTENT(IN) :: YAry(0:) + REAL(ReKi) :: InterpolateWithSlopeR + + InterpolateWithSlopeR = ( YAry(Ind+1) - YAry(Ind) )*InterpSlope + YAry(Ind) + +END FUNCTION InterpolateWithSlopeR +!---------------------------------------------------------------------------------------------------------------------------------- +!> Routine for computing outputs, used in both loose and tight coupling. +SUBROUTINE Morison_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ) +!.................................................................................................................................. + + REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds + TYPE(Morison_InputType), INTENT(IN ) :: u !< Inputs at Time + TYPE(Morison_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(Morison_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time + TYPE(Morison_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at Time + TYPE(Morison_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at Time + TYPE(Morison_OtherStateType), INTENT(IN ) :: OtherState !< Other states at Time + TYPE(Morison_OutputType), INTENT(INOUT) :: y !< Outputs computed at Time (Input only so that mesh con- + !! nectivity information does not have to be recalculated) + TYPE(Morison_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables + INTEGER(IntKi), INTENT( OUT) :: errStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: errMsg !< Error message if errStat /= ErrID_None + + ! Local variables + + INTEGER(IntKi) :: errStat2 ! Error status of the operation (occurs after initial error) + CHARACTER(errMsgLen) :: errMsg2 ! Error message if errStat2 /= ErrID_None + + REAL(ReKi) :: F_DP(6), kvec(3), v(3), vf(3), vrel(3), vmag + INTEGER :: I, J, K, nodeIndx, IntWrapIndx + REAL(ReKi) :: AllOuts(MaxMrsnOutputs) + REAL(ReKi) :: qdotdot(6) ,qdotdot2(3) ! The structural acceleration of a mesh node + !REAL(ReKi) :: accel_fluid(6) ! Acceleration of fluid at the mesh node + REAL(ReKi) :: dragFactor ! The lumped drag factor + REAL(ReKi) :: AnProd ! Dot product of the directional area of the joint + REAL(ReKi) :: C(3,3) + REAL(ReKi) :: sgn + REAL(ReKi) :: D_AM_M(6,6) + REAL(ReKi) :: nodeInWater + REAL(ReKi) :: D_dragConst ! The distributed drag factor + REAL(ReKi) :: InterpolationSlope + + + + TYPE(Morison_MemberType) :: mem ! the current member + INTEGER :: N ! Number of elements within a given member + REAL(ReKi) :: dl ! Element length within a given member, m + REAL(ReKi) :: vec(3) ! Vector pointing from a member's 1st node to its last node + REAL(ReKi) :: phi, phi1, phi2 ! member tilt angle + REAL(ReKi) :: beta ! member tilt heading + real(ReKi) :: vecLen ! distance between member end nodes (joints) [this should never be zero but we test for it just in case] + REAL(ReKi) :: cosPhi, cosPhi1, cosPhi2 + REAL(ReKi) :: sinPhi, sinPhi1, sinPhi2 + REAL(ReKi) :: tanPhi + REAL(ReKi) :: sinBeta, sinBeta1, sinBeta2 + REAL(ReKi) :: cosBeta, cosBeta1, cosBeta2 + real(ReKi) :: CMatrix(3,3), CTrans(3,3) ! Direction cosine matrix for element, and its transpose + REAL(ReKi) :: z1 + REAL(ReKi) :: z2 + REAL(ReKi) :: r1 + REAL(ReKi) :: r2 + real(ReKi) :: p1(3), p2(3) + REAL(ReKi) :: dRdl_mg ! shorthand for taper including marine growth of element i + REAL(ReKi) :: Rmid + REAL(ReKi) :: RmidMG + REAL(ReKi) :: Rmidin + REAL(ReKi) :: Lmid + real(ReKi) :: g ! gravity constant + REAL(ReKi) :: h0 ! distances along cylinder centerline from point 1 to the waterplane + real(ReKi) :: k_hat(3), k_hat1(3), k_hat2(3) ! Elemental unit vector pointing from 1st node to 2nd node of the element + REAL(ReKi) :: rh ! radius of cylinder at point where its centerline crosses the waterplane + REAL(ReKi) :: l1 ! distance from cone end to bottom node + REAL(ReKi) :: Vs ! segment submerged volume + REAL(ReKi) :: a0 ! waterplane ellipse shape + REAL(ReKi) :: b0 + REAL(ReKi) :: cr ! centroid of segment submerged volume relative to its lower node + REAL(ReKi) :: cl + REAL(ReKi) :: cx + REAL(ReKi) :: cz + REAL(ReKi) :: pwr ! exponent for buoyancy node distribution smoothing + REAL(ReKi) :: alpha ! final load distribution factor for element + REAL(ReKi) :: Fb !buoyant force + REAL(ReKi) :: Fr !radial component of buoyant force + REAL(ReKi) :: Fl !axial component of buoyant force + REAL(ReKi) :: Moment !moment induced about the center of the cylinder's bottom face + REAL(ReKi) :: BuoyF(3) ! buoyancy force vector aligned with an element + REAL(ReKi) :: BuoyM(3) ! buoyancy moment vector aligned with an element + integer(IntKi) :: im ! counter + real(ReKi) :: a_s1(3) + real(ReKi) :: alpha_s1(3) + real(ReKi) :: omega_s1(3) + real(ReKi) :: a_s2(3) + real(ReKi) :: alpha_s2(3) + real(ReKi) :: omega_s2(3) + real(ReKi) :: pos1(3), pos2(3) + real(ReKi) :: Imat(3,3) + real(ReKi) :: iArm(3), iTerm(3), Ioffset, h_c, dRdl_p, dRdl_pp, f_hydro(3), Am(3,3), lstar, deltal + real(ReKi) :: C_1, C_2, a0b0, z1d, z2d, h + real(ReKi) :: F_WMG(6), F_IMG(6), F_If(6), F_A(6), F_I(6), F_D(6), F_B1(6), F_B2(6) + + ! Initialize errStat + + errStat = ErrID_None + errMsg = "" + Imat = 0.0_ReKi + g = p%Gravity + + InterpolationSlope = GetInterpolationSlope(Time, p, m, IntWrapIndx) + + !=============================================================================================== + ! Calculate the fluid kinematics at all mesh nodes and store for use in the equations below + + do j = 1, p%NNodes + m%nodeInWater(j) = REAL( p%nodeInWater(IntWrapIndx,j), ReKi ) + + ! Determine the dynamic pressure at the node + m%FDynP(j) = InterpolateWithSlope(InterpolationSlope, m%LastIndWave, p%WaveDynP(:,j)) + do i=1,3 + ! Determine the fluid acceleration and velocity and relative structural velocity at the node + m%FA(i,j) = InterpolateWithSlope(InterpolationSlope, m%LastIndWave, p%WaveAcc(:,j,i)) + + m%FV(i,j) = InterpolateWithSlope(InterpolationSlope, m%LastIndWave, p%WaveVel(:,j,i)) + m%vrel(i,j) = m%FV(i,j) - u%Mesh%TranslationVel(i,j) + end do + end do + + ! ============================================================================================== + ! Calculate instantaneous loads on each member except for the hydrodynamic loads on member ends. + ! This covers aspects of the load calculations previously in CreateDistributedMesh. + + ! Zero out previous time-steps loads (these are loads which are computed at the member-level and summed onto a node, + ! so they need to be zeroed out before the summations happen) + !m%F_WMG = 0.0_ReKi + !m%F_IMG = 0.0_ReKi + m%F_BF_End= 0.0_ReKi + !m%F_If = 0.0_ReKi + !m%F_D = 0.0_ReKi + !m%F_A = 0.0_ReKi + !m%F_I = 0.0_ReKi + !m%F_B = 0.0_ReKi + !m%F_BF = 0.0_ReKi + m%F_B_End = 0.0_ReKi + y%Mesh%Force = 0.0_ReKi + y%Mesh%Moment = 0.0_ReKi + F_WMG(1) = 0.0_ReKi + F_WMG(2) = 0.0_ReKi + + ! Loop through each member + DO im = 1, p%NMembers + N = p%Members(im)%NElements + mem = p%Members(im) !@mhall: does this have much overhead? + + !zero member loads + m%memberLoads(im)%F_B = 0.0_ReKi + m%memberLoads(im)%F_BF = 0.0_ReKi + m%memberLoads(im)%F_D = 0.0_ReKi + m%memberLoads(im)%F_A = 0.0_ReKi + m%memberLoads(im)%F_I = 0.0_ReKi + m%memberLoads(im)%F_WMG = 0.0_ReKi + m%memberLoads(im)%F_IMG = 0.0_ReKi + m%memberLoads(im)%F_If = 0.0_ReKi + + DO i =1,N ! loop through member elements + + ! calculate isntantaneous incline angle and heading, and related trig values + ! the first and last NodeIndx values point to the corresponding Joint nodes idices which are at the start of the Mesh + pos1 = u%Mesh%TranslationDisp(:, mem%NodeIndx(i)) + u%Mesh%Position(:, mem%NodeIndx(i)) + pos2 = u%Mesh%TranslationDisp(:, mem%NodeIndx(i+1)) + u%Mesh%Position(:, mem%NodeIndx(i+1)) + + + call GetOrientationAngles( pos1, pos2, phi, sinPhi, cosPhi, tanPhi, sinBeta, cosBeta, k_hat, errStat2, errMsg2 ) + call Morison_DirCosMtrx( pos1, pos2, CMatrix ) + CTrans = transpose(CMatrix) + ! save some commonly used variables + dl = mem%dl + z1 = pos1(3) ! get node z locations from input mesh + z2 = pos2(3) + r1 = mem%RMG(i ) ! outer radius element nodes including marine growth + r2 = mem%RMG(i+1) + dRdl_mg = mem%dRdl_mg(i) ! mass of element including marine growth + a_s1 = u%Mesh%TranslationAcc(:, mem%NodeIndx(i )) + alpha_s1= u%Mesh%RotationAcc (:, mem%NodeIndx(i )) + omega_s1= u%Mesh%RotationVel (:, mem%NodeIndx(i )) + a_s2 = u%Mesh%TranslationAcc(:, mem%NodeIndx(i+1)) + alpha_s2= u%Mesh%RotationAcc (:, mem%NodeIndx(i+1)) + omega_s2= u%Mesh%RotationVel (:, mem%NodeIndx(i+1)) + + if ( .not. mem%PropPot ) then ! Member is NOT modeled with Potential Flow Theory + ! should i_floor theshold be applied to below calculations to avoid wasting time on computing zero-valued things? <<<<< + ! should lumped half-element coefficients get combined at initialization? <<< + + ! ------------------ marine growth: Sides: Section 4.1.2 -------------------- + + ! lower node + !m%F_WMG(3, mem%NodeIndx(i )) = m%F_WMG(3, mem%NodeIndx(i )) - mem%m_mg_l(i)*g ! weight force : Note: this is a constant + !m%F_WMG(4, mem%NodeIndx(i )) = m%F_WMG(4, mem%NodeIndx(i )) - mem%m_mg_l(i)*g * mem%h_cmg_l(i)* sinPhi * sinBeta! weight force + !m%F_WMG(5, mem%NodeIndx(i )) = m%F_WMG(5, mem%NodeIndx(i )) + mem%m_mg_l(i)*g * mem%h_cmg_l(i)* sinPhi * cosBeta! weight force + + F_WMG(3) = - mem%m_mg_l(i)*g ! weight force : Note: this is a constant + F_WMG(4) = - mem%m_mg_l(i)*g * mem%h_cmg_l(i)* sinPhi * sinBeta! weight force + F_WMG(5) = mem%m_mg_l(i)*g * mem%h_cmg_l(i)* sinPhi * cosBeta! weight force + m%memberLoads(im)%F_WMG(:,i) = m%memberLoads(im)%F_WMG(:,i) + F_WMG + y%Mesh%Force (:,mem%NodeIndx(i)) = y%Mesh%Force (:,mem%NodeIndx(i)) + F_WMG(1:3) + y%Mesh%Moment(:,mem%NodeIndx(i)) = y%Mesh%Moment(:,mem%NodeIndx(i)) + F_WMG(4:6) + + ! upper node + !m%F_WMG(3, mem%NodeIndx(i+1)) = m%F_WMG(3, mem%NodeIndx(i+1)) - mem%m_mg_u(i)*g ! weight force : Note: this is a constant + !m%F_WMG(4, mem%NodeIndx(i+1)) = m%F_WMG(4, mem%NodeIndx(i+1)) - mem%m_mg_u(i)*g * mem%h_cmg_u(i)* sinPhi * sinBeta! weight force + !m%F_WMG(5, mem%NodeIndx(i+1)) = m%F_WMG(5, mem%NodeIndx(i+1)) + mem%m_mg_u(i)*g * mem%h_cmg_u(i)* sinPhi * cosBeta! weight force + F_WMG(3) = - mem%m_mg_u(i)*g ! weight force : Note: this is a constant + F_WMG(4) = - mem%m_mg_u(i)*g * mem%h_cmg_u(i)* sinPhi * sinBeta! weight force + F_WMG(5) = mem%m_mg_u(i)*g * mem%h_cmg_u(i)* sinPhi * cosBeta! weight force + m%memberLoads(im)%F_WMG(:,i+1) = m%memberLoads(im)%F_WMG(:,i+1) + F_WMG + y%Mesh%Force (:,mem%NodeIndx(i+1)) = y%Mesh%Force (:,mem%NodeIndx(i+1)) + F_WMG(1:3) + y%Mesh%Moment(:,mem%NodeIndx(i+1)) = y%Mesh%Moment(:,mem%NodeIndx(i+1)) + F_WMG(4:6) + + ! lower node + Ioffset = mem%h_cmg_l(i)*mem%h_cmg_l(i)*mem%m_mg_l(i) + Imat(1,1) = mem%I_rmg_l(i) - Ioffset + Imat(2,2) = mem%I_rmg_l(i) - Ioffset + Imat(3,3) = mem%I_lmg_l(i) - Ioffset + Imat = matmul(matmul(CMatrix, Imat), CTrans) + iArm = mem%h_cmg_l(i) * k_hat + iTerm = ( -a_s1 - cross_product(omega_s1, cross_product(omega_s1,iArm )) - cross_product(alpha_s1,iArm) ) * mem%m_mg_l(i) + !m%F_IMG(1:3, mem%NodeIndx(i )) = m%F_IMG(1:3, mem%NodeIndx(i )) + iTerm + !m%F_IMG(4:6, mem%NodeIndx(i )) = m%F_IMG(4:6, mem%NodeIndx(i )) & + ! - cross_product(a_s1 * mem%m_mg_l(i), mem%h_cmg_l(i) * k_hat) & + ! + matmul(Imat, alpha_s1) & + ! - cross_product(omega_s1,matmul(Imat,omega_s1)) + F_IMG(1:3) = iTerm + F_IMG(4:6) = - cross_product(a_s1 * mem%m_mg_l(i), mem%h_cmg_l(i) * k_hat) + matmul(Imat, alpha_s1) & + - cross_product(omega_s1,matmul(Imat,omega_s1)) + m%memberLoads(im)%F_IMG(:,i) = m%memberLoads(im)%F_IMG(:,i) + F_IMG + y%Mesh%Force (:,mem%NodeIndx(i)) = y%Mesh%Force (:,mem%NodeIndx(i)) + F_IMG(1:3) + y%Mesh%Moment(:,mem%NodeIndx(i)) = y%Mesh%Moment(:,mem%NodeIndx(i)) + F_IMG(4:6) + + ! upper node + Ioffset = mem%h_cmg_u(i)*mem%h_cmg_u(i)*mem%m_mg_u(i) + Imat(1,1) = mem%I_rmg_u(i) - Ioffset + Imat(2,2) = mem%I_rmg_u(i) - Ioffset + Imat(3,3) = mem%I_lmg_u(i) - Ioffset + Imat = matmul(matmul(CMatrix, Imat), CTrans) + iArm = mem%h_cmg_u(i) * k_hat + iTerm = ( -a_s2 - cross_product(omega_s2, cross_product(omega_s2,iArm )) - cross_product(alpha_s2,iArm) ) * mem%m_mg_u(i) + !m%F_IMG(1:3, mem%NodeIndx(i+1)) = m%F_IMG(1:3, mem%NodeIndx(i+1)) + iTerm + !m%F_IMG(4:6, mem%NodeIndx(i+1)) = m%F_IMG(4:6, mem%NodeIndx(i+1)) & + ! - cross_product(a_s2 * mem%m_mg_u(i), mem%h_cmg_u(i) * k_hat) & + ! + matmul(Imat, alpha_s2) & + ! - cross_product(omega_s2,matmul(Imat,omega_s2)) + F_IMG(1:3) = iTerm + F_IMG(4:6) = - cross_product(a_s2 * mem%m_mg_u(i), mem%h_cmg_u(i) * k_hat) + matmul(Imat, alpha_s2) & + - cross_product(omega_s2,matmul(Imat,omega_s2)) + m%memberLoads(im)%F_IMG(:,i+1) = m%memberLoads(im)%F_IMG(:,i+1) + F_IMG + y%Mesh%Force (:,mem%NodeIndx(i+1)) = y%Mesh%Force (:,mem%NodeIndx(i+1)) + F_IMG(1:3) + y%Mesh%Moment(:,mem%NodeIndx(i+1)) = y%Mesh%Moment(:,mem%NodeIndx(i+1)) + F_IMG(4:6) + + ! ------------------- buoyancy loads: sides: Sections 3.1 and 3.2 ------------------------ + +!TODO: What about elements which are buried in the seabed? This doesn't seem to be tested for + if (z1 < 0) then ! if segment is at least partially submerged ... + + + if (z1*z2 <= 0) then ! special calculation if the slice is partially submerged + + ! Check that this is not the 1st element of the member + if ( i == 1 ) then + call SeterrStat(ErrID_Fatal, 'The lowest element of a Morison member has become partially submerged! This is not allowed. Please review your model and create a discretization such that even with displacements, the lowest element of a member does not become partially submerged.', errStat, errMsg, 'Morison_CalcOutput' ) + return + end if + + h0 = -z1/cosPhi ! distances along element centerline from point 1 to the waterplane + + + if (abs(dRdl_mg) < 0.0001) then ! untapered cylinder case + + Vs = Pi*r1*r1*h0 ! volume of total submerged portion + if ( EqualRealNos(Vs, 0.0_ReKi) ) then + cx = 0.0_ReKi ! Avoid singularity, but continue to provide the correct solution + else + cr = 0.25*r1*r1*tanPhi/h0 + cl = 0.5*h0 + 0.125*r1*r1*tanPhi*tanPhi/h0 + cx = cr*cosPhi + cl*sinPhi + end if + + !alpha0 = 0.5*h0/dl ! force distribution between end nodes + + else ! inclined tapered cylinder case (note I've renamed r0 to rh here!!) + !=================== + !Per plan equations + ! NOTE: Variable changes of Plan vs Code + !--------------------------------------------------- + ! V Vs + ! a_h a0 + ! b_h b0 + ! x_c cx + ! h h0 + ! r1 r_MG,i + ! r_c cr + ! h_c cl + ! NOTE: a0 and b0 always appear as a0b0, never separately. + rh = r1 + h0*dRdl_mg ! radius of element at point where its centerline crosses the waterplane + C_1 = 1.0_ReKi - dRdl_mg**2 * tanPhi**2 + ! waterplane ellipse shape + b0 = rh/sqrt(C_1) + a0 = rh/((C_1)*cosPhi) ! simplified from what's in ConicalCalcs.ipynb + a0b0 = a0*b0 + C_2 = a0b0*rh*cosPhi - r1**3 + cl = (0.75*a0b0*r1**2*cosPhi + 0.75*r1**4*C_1 + r1*C_1*C_2) / (dRdl_mg*C_1*C_2) + cr = (0.75*a0b0*dRdl_mg*rh**2*sinPhi)/(C_1*C_2) + cx = cr*cosPhi + cl*sinPhi + Vs = pi*(a0b0*rh*cosPhi - r1**3)/(3.0*dRdl_mg) + + ! End per plan equations + !=================== + + !rh = r1 + h0*dRdl_mg ! radius of element at point where its centerline crosses the waterplane + !l1 = r1/dRdl_mg ! distance from cone end to bottom node + ! + !! waterplane ellipse shape + !b0 = rh/sqrt(1 - dRdl_mg**2 * tanPhi**2) + !a0 = rh/((1 - dRdl_mg**2*tanPhi**2)*cosPhi) ! simplified from what's in ConicalCalcs.ipynb + ! + !! segment submerged volume + !!Vs = pi*(a0*b0*rh*cosPhi - l1**3*dRdl_mg**3)/(3*dRdl_mg) !Original code + !Vs = pi*(a0*b0*rh*cosPhi - r1**3)/(3*dRdl_mg) !Plan doc + ! + !! centroid of segment submerged volume (relative to bottom node) + !cx = -0.25*(3*a0*b0*rh*rh*(dRdl_mg**2 + 1)*cosPhi + 3.0*l1**4*dRdl_mg**4*(dRdl_mg**2*tanPhi**2 - 1) + 4*l1*dRdl_mg*(dRdl_mg**2*tanPhi**2 - 1)*(a0*b0*rh*cosPhi - 1.0*l1**3*dRdl_mg**3))*sin(phi)/(dRdl_mg*(dRdl_mg**2*tanPhi**2 - 1)*(a0*b0*rh*cosPhi - l1**3*dRdl_mg**3)) + + !alpha0 = (r1*r1 + 2*r1*r2 + 3*r2**2)/4/(r1*r1 + r1*r2 + r2**2) ! this can be precomputed + + end if + + pwr = 3 + alpha = (1.0-mem%alpha(i))*z1**pwr/(-mem%alpha(i)*z2**pwr + (1.0-mem%alpha(i))*z1**pwr) + + Fb = Vs*p%WtrDens*g !buoyant force + Fr = -Fb*sinPhi !radial component of buoyant force + Fl = Fb*cosPhi !axial component of buoyant force + Moment = -Fb*cx !This was matt's code !moment induced about the center of the cylinder's bottom face + + ! calculate (imaginary) bottom plate forces/moment to subtract from displacement-based values + Fl = Fl + p%WtrDens*g*z1* Pi *r1*r1 + Moment = Moment + p%WtrDens*g* sinPhi * Pi/4.0*r1**4 + + + ! reduce taper-based moment to remove (not double count) radial force distribution to each node + Moment = Moment + Fr*(1.0_ReKi-alpha)*dl + !call DistributeElementLoads(Fl, Fr, Moment, sinPhi, cosPhi, sinBeta, cosBeta, alpha, m%F_B(:, mem%NodeIndx(i)), m%F_B(:, mem%NodeIndx(i-1))) + call DistributeElementLoads(Fl, Fr, Moment, sinPhi, cosPhi, sinBeta, cosBeta, alpha, F_B1, F_B2) + m%memberLoads(im)%F_B(:, i) = m%memberLoads(im)%F_B(:, i) + F_B1 ! alpha + m%memberLoads(im)%F_B(:, i-1) = m%memberLoads(im)%F_B(:, i-1) + F_B2 ! 1-alpha + y%Mesh%Force (:,mem%NodeIndx(i )) = y%Mesh%Force (:,mem%NodeIndx(i )) + F_B1(1:3) + y%Mesh%Moment(:,mem%NodeIndx(i )) = y%Mesh%Moment(:,mem%NodeIndx(i )) + F_B1(4:6) + y%Mesh%Force (:,mem%NodeIndx(i-1)) = y%Mesh%Force (:,mem%NodeIndx(i-1)) + F_B2(1:3) + y%Mesh%Moment(:,mem%NodeIndx(i-1)) = y%Mesh%Moment(:,mem%NodeIndx(i-1)) + F_B2(4:6) + else ! normal, fully submerged case + + Fl = -2.0*Pi*dRdl_mg*p%WtrDens*g*dl*( z1*r1 + 0.5*(z1*dRdl_mg + r1*cosPhi)*dl + 1.0/3.0*(dRdl_mg*cosPhi*dl*dl) ) ! from CylinderCalculationsR1.ipynb + + Fr = -Pi*p%WtrDens*g*dl*(r1*r1 + dRdl_mg*r1*dl + (dRdl_mg**2*dl**2)/3.0)*sinPhi ! from CylinderCalculationsR1.ipynb + Moment = -Pi*dl*g*p%WtrDens*(3.0*dl**3*dRdl_mg**4 + 3.0*dl**3*dRdl_mg**2 + 12.0*dl**2*dRdl_mg**3*r1 + 8.0*dl**2*dRdl_mg*r1 + 18.0*dl*dRdl_mg**2*r1*r1 + 6.0*dl*r1*r1 + 12.0*dRdl_mg*r1**3)*sinPhi/12.0 ! latest from CylinderCalculationsR1.ipynb + + ! precomputed as mem%alpha(i) ... alpha0 = (r1*r1 + 2*r1*r2 + 3*r2**2)/4/(r1*r1 + r1*r2 + r2**2) + !TODO: Review the below alpha eqn, GJH + z1d = -min(0.0_ReKi,z1) + z2d = -min(0.0_ReKi,z2) + + pwr = 3 + alpha = mem%alpha(i)*z2d**pwr/(mem%alpha(i)*z2d**pwr+(1-mem%alpha(i))*z1d**pwr) + + + ! reduce moment to remove (not double count) radial force distribution to each node + Moment = Moment - Fr*alpha*dl + ! TODO: Should the order be, i, i+1 GJH + !call DistributeElementLoads(Fl, Fr, Moment, sinPhi, cosPhi, sinBeta, cosBeta, alpha, m%F_B(:, mem%NodeIndx(i+1)), m%F_B(:, mem%NodeIndx(i))) + call DistributeElementLoads(Fl, Fr, Moment, sinPhi, cosPhi, sinBeta, cosBeta, alpha, F_B1, F_B2) + m%memberLoads(im)%F_B(:,i+1) = m%memberLoads(im)%F_B(:,i+1) + F_B1 ! alpha + m%memberLoads(im)%F_B(:, i) = m%memberLoads(im)%F_B(:, i) + F_B2 ! 1-alpha + y%Mesh%Force (:,mem%NodeIndx(i )) = y%Mesh%Force (:,mem%NodeIndx(i )) + F_B2(1:3) + y%Mesh%Moment(:,mem%NodeIndx(i )) = y%Mesh%Moment(:,mem%NodeIndx(i )) + F_B2(4:6) + y%Mesh%Force (:,mem%NodeIndx(i+1)) = y%Mesh%Force (:,mem%NodeIndx(i+1)) + F_B1(1:3) + y%Mesh%Moment(:,mem%NodeIndx(i+1)) = y%Mesh%Moment(:,mem%NodeIndx(i+1)) + F_B1(4:6) + end if ! submergence cases + + end if ! element at least partially submerged + + end if ! NOT Modeled with Potential flow theory + + ! ------------------ flooded ballast inertia: sides: Section 6.1.1 : Always compute regardless of PropPot setting --------------------- + + ! lower node + Ioffset = mem%h_cfb_l(i)*mem%h_cfb_l(i)*mem%m_fb_l(i) + Imat(1,1) = mem%I_rfb_l(i) - Ioffset + Imat(2,2) = mem%I_rfb_l(i) - Ioffset + Imat(3,3) = mem%I_lfb_l(i) - Ioffset + iArm = mem%h_cfb_l(i) * k_hat + iTerm = ( -a_s1 - cross_product(omega_s1, cross_product(omega_s1,iArm )) - cross_product(alpha_s1,iArm) ) * mem%m_fb_l(i) + !m%F_If(1:3, mem%NodeIndx(i )) = m%F_If(1:3, mem%NodeIndx(i )) + iTerm + !m%F_If(4:6, mem%NodeIndx(i )) = m%F_If(4:6, mem%NodeIndx(i )) & + ! - cross_product(a_s1 * mem%m_fb_l(i), mem%h_cfb_l(i) * k_hat) & + ! + matmul(Imat, alpha_s1) & + ! - cross_product(omega_s1,matmul(Imat,omega_s1)) + F_If(1:3) = iTerm + F_If(4:6) = - cross_product(a_s1 * mem%m_fb_l(i), mem%h_cfb_l(i) * k_hat) + matmul(Imat, alpha_s1) & + - cross_product(omega_s1,matmul(Imat,omega_s1)) + m%memberLoads(im)%F_If(:,i) = m%memberLoads(im)%F_If(:,i) + F_If + y%Mesh%Force (:,mem%NodeIndx(i)) = y%Mesh%Force (:,mem%NodeIndx(i)) + F_If(1:3) + y%Mesh%Moment(:,mem%NodeIndx(i)) = y%Mesh%Moment(:,mem%NodeIndx(i)) + F_If(4:6) + + ! upper node + Ioffset = mem%h_cfb_u(i)*mem%h_cfb_u(i)*mem%m_fb_u(i) + Imat(1,1) = mem%I_rfb_u(i) - Ioffset + Imat(2,2) = mem%I_rfb_u(i) - Ioffset + Imat(3,3) = mem%I_lfb_u(i) - Ioffset + iArm = mem%h_cfb_u(i) * k_hat + iTerm = ( -a_s2 - cross_product(omega_s2, cross_product(omega_s2,iArm )) - cross_product(alpha_s2,iArm) ) * mem%m_fb_u(i) + !m%F_If(1:3, mem%NodeIndx(i+1)) = m%F_If(1:3, mem%NodeIndx(i+1)) + iTerm + !m%F_If(4:6, mem%NodeIndx(i+1)) = m%F_If(4:6, mem%NodeIndx(i+1)) & + ! - cross_product(a_s2 * mem%m_fb_u(i), mem%h_cfb_u(i) * k_hat) & + ! + matmul(Imat, alpha_s2) & + ! - cross_product(omega_s2,matmul(Imat,omega_s2)) + F_If(1:3) = iTerm + F_If(4:6) = - cross_product(a_s2 * mem%m_fb_u(i), mem%h_cfb_u(i) * k_hat) + matmul(Imat, alpha_s2) & + - cross_product(omega_s2,matmul(Imat,omega_s2)) + m%memberLoads(im)%F_If(:,i+1) = m%memberLoads(im)%F_If(:,i+1) + F_If + y%Mesh%Force (:,mem%NodeIndx(i+1)) = y%Mesh%Force (:,mem%NodeIndx(i+1)) + F_If(1:3) + y%Mesh%Moment(:,mem%NodeIndx(i+1)) = y%Mesh%Moment(:,mem%NodeIndx(i+1)) + F_If(4:6) + + ! ------------------ flooded ballast weight : sides : Section 5.1.2 & 5.2.2 : Always compute regardless of PropPot setting --------------------- + + ! NOTE: For memfloodstatus and floodstatus: 0 = fully buried or not ballasted, 1 = fully flooded, 2 = partially flooded + + ! fully filled elements + if (mem%floodstatus(i) == 1) then + + ! Compute lstar + if ( mem%memfloodstatus == 2) then + ! partially flooded MEMBER + lstar = dl*(i-1) - mem%l_fill + elseif (cosPhi >= 0.0 ) then + lstar = dl*(i-N-1) + else + lstar = dl*(i-1) + end if + Fl =TwoPi * mem%dRdl_in(i) * mem%FillDens * p%gravity * dl *( -( mem%Rin(i) + 0.5* mem%dRdl_in(i)*dl )*mem%z_overfill + & + ( lstar*mem%Rin(i) + 0.5*(lstar*mem%dRdl_in(i) + mem%Rin(i) )*dl + mem%dRdl_in(i)*dl**2/3.0 )*cosphi ) + + ! forces and moment in tilted coordinates about node i + !Fl = mem%Cfl_fb(i)*cosPhi + Fr = mem%Cfr_fb(i)*sinPhi + Moment = mem%CM0_fb(i)*sinPhi - Fr*mem%alpha_fb_star(i)*dl + + ! calculate full vector and distribute to nodes + !call DistributeElementLoads(Fl, Fr, Moment, sinPhi, cosPhi, sinBeta, cosBeta, (1-mem%alpha_fb_star(i)), m%F_BF(:, mem%NodeIndx(i)), m%F_BF(:, mem%NodeIndx(i+1))) + call DistributeElementLoads(Fl, Fr, Moment, sinPhi, cosPhi, sinBeta, cosBeta, (1-mem%alpha_fb_star(i)), F_B1, F_B2) + m%memberLoads(im)%F_BF(:, i) = m%memberLoads(im)%F_BF(:, i) + F_B2 ! 1-alpha + m%memberLoads(im)%F_BF(:, i+1) = m%memberLoads(im)%F_BF(:, i+1) + F_B1 ! alpha + y%Mesh%Force (:,mem%NodeIndx(i )) = y%Mesh%Force (:,mem%NodeIndx(i )) + F_B2(1:3) + y%Mesh%Moment(:,mem%NodeIndx(i )) = y%Mesh%Moment(:,mem%NodeIndx(i )) + F_B2(4:6) + y%Mesh%Force (:,mem%NodeIndx(i+1)) = y%Mesh%Force (:,mem%NodeIndx(i+1)) + F_B1(1:3) + y%Mesh%Moment(:,mem%NodeIndx(i+1)) = y%Mesh%Moment(:,mem%NodeIndx(i+1)) + F_B1(4:6) + + ! partially filled element + else if (mem%floodstatus(i) == 2) then + + ! forces and moment in tilted coordinates about node i + Fl = mem%Cfl_fb(i)*cosPhi + Fr = mem%Cfr_fb(i)*sinPhi + Moment = mem%CM0_fb(i)*sinPhi + Fr*(1 - mem%alpha_fb_star(i))*dl + + ! calculate full vector and distribute to nodes + !call DistributeElementLoads(Fl, Fr, Moment, sinPhi, cosPhi, sinBeta, cosBeta, mem%alpha_fb_star(i), m%F_BF(:, mem%NodeIndx(i)), m%F_BF(:, mem%NodeIndx(i-1))) + call DistributeElementLoads(Fl, Fr, Moment, sinPhi, cosPhi, sinBeta, cosBeta, mem%alpha_fb_star(i), F_B1, F_B2) + m%memberLoads(im)%F_BF(:, i) = m%memberLoads(im)%F_BF(:, i) + F_B1 ! alpha + m%memberLoads(im)%F_BF(:, i-1) = m%memberLoads(im)%F_BF(:, i-1) + F_B2 ! 1- alpha + y%Mesh%Force (:,mem%NodeIndx(i )) = y%Mesh%Force (:,mem%NodeIndx(i )) + F_B1(1:3) + y%Mesh%Moment(:,mem%NodeIndx(i )) = y%Mesh%Moment(:,mem%NodeIndx(i )) + F_B1(4:6) + y%Mesh%Force (:,mem%NodeIndx(i-1)) = y%Mesh%Force (:,mem%NodeIndx(i-1)) + F_B2(1:3) + y%Mesh%Moment(:,mem%NodeIndx(i-1)) = y%Mesh%Moment(:,mem%NodeIndx(i-1)) + F_B2(4:6) + + ! no load for unflooded element or element fully below seabed + + end if + + - ENDDO + + END DO ! i =1,N ! loop through member elements + + + ! External Hydrodynamic Side Loads + ! NOTE: All geometry-related calculations are based on the undisplaced configuration of the structure + + DO i =1,N+1 ! loop through member nodes + z1 = u%Mesh%Position(3, mem%NodeIndx(i)) + if ( i > mem%i_floor .and. z1 <= 0.0 ) then ! node is above (or at? TODO: check) seabed and below or at free-surface) + ! TODO: Note that for computational efficiency, we could precompute h_c and deltal for each element when we are NOT using wave stretching + ! We would still need to test at time marching for nodes just below the free surface because that uses the current locations not the reference locations + ! see table in Section 7.1.1 + if ( i == 1 ) then + deltal = mem%dl/2.0_ReKi + h_c = mem%dl/4.0_ReKi + elseif (i == N+1) then + deltal = mem%dl/2.0_ReKi + h_c = -mem%dl/4.0_ReKi + elseif ( mem%i_floor == i+1 ) then ! This node is the upper node of an element which crosses the seabed + deltal = mem%dl/2.0_ReKi - mem%h_floor ! TODO: h_floor is negative valued, should we be subrtracting it from dl/2? GJH + h_c = 0.5_ReKi*(mem%dl/2.0_ReKi + mem%h_floor) + else + pos1 = u%Mesh%Position(:, mem%NodeIndx(i)) + pos2 = u%Mesh%Position(:, mem%NodeIndx(i+1)) + if (pos1(3) <= 0.0 .and. 0.0 < pos2(3) ) then ! This node is just below the free surface !TODO: Needs to be augmented for wave stretching + !TODO: Fix this one + pos1 = u%Mesh%Position(:, mem%NodeIndx(i)) ! use reference position for following equation + h = ( pos1(3) ) / mem%cosPhi_ref !TODO: Needs to be augmented for wave stretching + deltal = mem%dl/2.0 + h + h_c = 0.5*(h-mem%dl/2.0) + else + ! This node is a fully submerged interior node + deltal = mem%dl + h_c = 0.0_ReKi + end if + + end if + + if (i == 1) then + dRdl_p = abs(mem%dRdl_mg(i)) + dRdl_pp = mem%dRdl_mg(i) + elseif ( i > 1 .and. i < (N+1)) then + dRdl_p = 0.5*( abs(mem%dRdl_mg(i-1)) + abs(mem%dRdl_mg(i)) ) + dRdl_pp = 0.5*( mem%dRdl_mg(i-1) + mem%dRdl_mg(i) ) + else + dRdl_p = abs(mem%dRdl_mg(N)) + dRdl_pp = mem%dRdl_mg(N) + end if + + ! ------------------- hydrodynamic drag loads: sides: Section 7.1.2 ------------------------ + vec = matmul( mem%Ak,m%vrel(:,mem%NodeIndx(i)) ) + f_hydro = mem%Cd(i)*p%WtrDens*mem%RMG(i)*TwoNorm(vec)*vec + & + 0.5*mem%AxCd(i)*p%WtrDens*pi*mem%RMG(i)*dRdl_p * matmul( dot_product( mem%k, m%vrel(:,mem%NodeIndx(i)) )*mem%kkt, m%vrel(:,mem%NodeIndx(i)) ) +! call LumpDistrHydroLoads( f_hydro, mem%k, deltal, h_c, m%F_D(:, mem%NodeIndx(i)) ) + call LumpDistrHydroLoads( f_hydro, mem%k, deltal, h_c, m%memberLoads(im)%F_D(:, i) ) + y%Mesh%Force (:,mem%NodeIndx(i)) = y%Mesh%Force (:,mem%NodeIndx(i)) + m%memberLoads(im)%F_D(1:3, i) + y%Mesh%Moment(:,mem%NodeIndx(i)) = y%Mesh%Moment(:,mem%NodeIndx(i)) + m%memberLoads(im)%F_D(4:6, i) + + if ( .not. mem%PropPot ) then + ! ------------------- hydrodynamic added mass loads: sides: Section 7.1.3 ------------------------ + Am = mem%Ca(i)*p%WtrDens*pi*mem%RMG(i)*mem%RMG(i)*mem%Ak + 2.0*mem%AxCa(i)*p%WtrDens*pi*mem%RMG(i)*mem%RMG(i)*dRdl_p*mem%kkt + f_hydro = -matmul( Am, u%Mesh%TranslationAcc(:,mem%NodeIndx(i)) ) + !call LumpDistrHydroLoads( f_hydro, mem%k, deltal, h_c, m%F_A(:, mem%NodeIndx(i)) ) + call LumpDistrHydroLoads( f_hydro, mem%k, deltal, h_c, m%memberLoads(im)%F_A(:, i) ) + y%Mesh%Force (:,mem%NodeIndx(i)) = y%Mesh%Force (:,mem%NodeIndx(i)) + m%memberLoads(im)%F_A(1:3, i) + y%Mesh%Moment(:,mem%NodeIndx(i)) = y%Mesh%Moment(:,mem%NodeIndx(i)) + m%memberLoads(im)%F_A(4:6, i) + + ! ------------------- hydrodynamic inertia loads: sides: Section 7.1.4 ------------------------ + f_hydro=(mem%Ca(i)+mem%Cp(i))*p%WtrDens*pi*mem%RMG(i)*mem%RMG(i) * matmul( mem%Ak, m%FA(:,mem%NodeIndx(i)) ) + & + 2.0*mem%AxCa(i)*p%WtrDens*pi*mem%RMG(i)*mem%RMG(i)*dRdl_p * matmul( mem%kkt, m%FA(:,mem%NodeIndx(i)) ) + & + 2.0*m%FDynP(mem%NodeIndx(i))*mem%AxCp(i)*pi*mem%RMG(i)*dRdl_pp*mem%k + !call LumpDistrHydroLoads( f_hydro, mem%k, deltal, h_c, m%F_I(:, mem%NodeIndx(i)) ) + call LumpDistrHydroLoads( f_hydro, mem%k, deltal, h_c, m%memberLoads(im)%F_I(:, i) ) + y%Mesh%Force (:,mem%NodeIndx(i)) = y%Mesh%Force (:,mem%NodeIndx(i)) + m%memberLoads(im)%F_I(1:3, i) + y%Mesh%Moment(:,mem%NodeIndx(i)) = y%Mesh%Moment(:,mem%NodeIndx(i)) + m%memberLoads(im)%F_I(4:6, i) + end if + end if ! ( i > mem%i_floor .and. Zi <= 0.0 ) + + END DO ! i =1,N+1 ! loop through member nodes + + + ! Any end plate loads that are modeled on a per-member basis + + ! reassign convenience variables to correspond to member ends + + pos1 = u%Mesh%TranslationDisp(:, mem%NodeIndx(1)) + u%Mesh%Position(:, mem%NodeIndx(1)) + pos2 = u%Mesh%TranslationDisp(:, mem%NodeIndx(2)) + u%Mesh%Position(:, mem%NodeIndx(2)) + z1 = pos1(3) + + call GetOrientationAngles( pos1, pos2, phi1, sinPhi1, cosPhi1, tanPhi, sinBeta1, cosBeta1, k_hat1, errStat2, errMsg2 ) + if ( N == 1 ) then ! Only one element in member + sinPhi2 = sinPhi1 + cosPhi2 = cosPhi1 + sinBeta2 = sinBeta1 + cosBeta2 = cosBeta1 + else + pos1 = u%Mesh%TranslationDisp(:, mem%NodeIndx(N)) + u%Mesh%Position(:, mem%NodeIndx(N)) + pos2 = u%Mesh%TranslationDisp(:, mem%NodeIndx(N+1)) + u%Mesh%Position(:, mem%NodeIndx(N+1)) + call GetOrientationAngles( pos1, pos2, phi2, sinPhi2, cosPhi2, tanPhi, sinBeta2, cosBeta2, k_hat2, errStat2, errMsg2 ) + end if + pos2 = u%Mesh%TranslationDisp(:, mem%NodeIndx(N+1)) + u%Mesh%Position(:, mem%NodeIndx(N+1)) + z2 = pos2(3) + + ! Check the member does not exhibit any of the following conditions + if (.not. mem%PropPot) then + if ( abs(z2) < abs(mem%Rmg(N+1)*sinPhi2) ) then + call SetErrStat(ErrID_Fatal, 'The upper end-plate of a member must not cross the water plane. This is not true for Member ID '//trim(num2lstr(mem%MemberID)), errStat, errMsg, 'Morison_CalcOutput' ) + end if + if ( abs(z1) < abs(mem%Rmg(1)*sinPhi1) ) then + call SetErrStat(ErrID_Fatal, 'The lower end-plate of a member must not cross the water plane. This is not true for Member ID '//trim(num2lstr(mem%MemberID)), errStat, errMsg, 'Morison_CalcOutput' ) + end if + end if + +! TODO: Do the equations below still work if z1 > z2 ? + !TODO, should not have to test seabed crossing in time-marching loop + + + if ( mem%i_floor == 0 ) then ! both ends are above seabed + !--- Water ballast buoyancy --- + ! if member is fully flooded + if (mem%memfloodstatus == 1) then + !if (mem%z_overfill >= 0) then + Fl = -mem%FillDens * g * pi *mem%Rin( 1)**2* (mem%z_overfill + max(z2-z1, 0.0_ReKi)) + Moment = mem%FillDens * g * pi *0.25*mem%Rin( 1)**4*sinPhi + call AddEndLoad(Fl, Moment, sinPhi1, cosPhi1, sinBeta1, cosBeta1, m%F_BF_End(:, mem%NodeIndx(1))) + + Fl = mem%FillDens * g * pi *mem%Rin(N+1)**2* (mem%z_overfill + max(z1-z2, 0.0_ReKi)) + Moment = -mem%FillDens * g * pi *0.25*mem%Rin(N+1)**4*sinPhi + call AddEndLoad(Fl, Moment, sinPhi2, cosPhi2, sinBeta2, cosBeta2, m%F_BF_End(:, mem%NodeIndx(N+1))) + + ! if member is partially flooded + else if (mem%l_fill > 0) then + Fl = -mem%FillDens * g * pi *mem%Rin(1)**2*mem%l_fill*cosPhi + Moment = mem%FillDens * g * pi *0.25*mem%Rin(1)**4*sinPhi + call AddEndLoad(Fl, Moment, sinPhi1, cosPhi1, sinBeta1, cosBeta1, m%F_BF_End(:, mem%NodeIndx(1))) + else + ! no load if member is not flooded at all + end if + + elseif ( mem%i_floor < mem%NElements+1 ) then ! upper node is still above the seabed, but lower node is below seabed + !if (mem%z_overfill >= 0) then + if (mem%memfloodstatus == 1) then + Fl = mem%FillDens * g * pi *mem%Rin(N+1)**2* (mem%z_overfill + max(z1-z2, 0.0_ReKi)) + Moment = -mem%FillDens * g * pi *0.25*mem%Rin(N+1)**4*sinPhi + call AddEndLoad(Fl, Moment, sinPhi2, cosPhi2, sinBeta2, cosBeta2, m%F_BF_End(:, mem%NodeIndx(N+1))) + end if + + else + ! no loads because both end nodes are below seabed + end if + + ! --- no inertia loads from water ballast modeled on ends + + ! --- external buoyancy loads: ends --- + + if ( .not. mem%PropPot ) then + pos1 = u%Mesh%TranslationDisp(:, mem%NodeIndx(1)) + u%Mesh%Position(:, mem%NodeIndx(1)) + pos2 = u%Mesh%TranslationDisp(:, mem%NodeIndx(N+1)) + u%Mesh%Position(:, mem%NodeIndx(N+1)) + z1 = pos1(3) + z2 = pos2(3) + if (mem%i_floor == 0) then ! both ends above or at seabed + if (z2<= 0.0_ReKi) then + ! Compute loads on both ends + Fl = -p%WtrDens * g * pi *mem%RMG(1)**2*z1 + Moment = -p%WtrDens * g * pi *0.25*mem%RMG(1)**4*sinPhi + call AddEndLoad(Fl, Moment, sinPhi1, cosPhi1, sinBeta1, cosBeta1, m%F_B_End(:, mem%NodeIndx(1))) + Fl = p%WtrDens * g * pi *mem%RMG(N+1)**2*z2 + Moment = p%WtrDens * g * pi *0.25*mem%RMG(N+1)**4*sinPhi + call AddEndLoad(Fl, Moment, sinPhi2, cosPhi2, sinBeta2, cosBeta2, m%F_B_End(:, mem%NodeIndx(N+1))) + elseif ( z1< 0.0_ReKi ) then + ! Compute loads only on lower end + Fl = -p%WtrDens * g * pi *mem%RMG(1)**2*z1 + Moment = -p%WtrDens * g * pi *0.25*mem%RMG(1)**4*sinPhi + call AddEndLoad(Fl, Moment, sinPhi1, cosPhi1, sinBeta1, cosBeta1, m%F_B_End(:, mem%NodeIndx(1))) + else + ! Entire member is above the still water line + end if + + ! elseif ( (mem%i_floor < mem%NElements) .and. (z2<= 0.0_ReKi) ) then ! The member crosses the seabed line so only the upper end could have bouyancy effects, if at or below free surface + elseif ( (mem%doEndBuoyancy) .and. (z2<= 0.0_ReKi) ) then ! The member crosses the seabed line so only the upper end could have bouyancy effects, if at or below free surface + ! Only compute the buoyancy contribution from the upper end + Fl = p%WtrDens * g * pi *mem%RMG(N+1)**2*z2 + Moment = p%WtrDens * g * pi *0.25*mem%RMG(N+1)**4*sinPhi + call AddEndLoad(Fl, Moment, sinPhi2, cosPhi2, sinBeta2, cosBeta2, m%F_B_End(:, mem%NodeIndx(N+1))) + else + ! entire member is buried below the seabed + end if + + end if ! PropPot + + end do ! im - looping through members + + !do j = 1, p%NNodes + ! ! Sum side load components onto output mesh + ! DO i=1,6 + ! IF (i < 4 ) THEN + ! y%Mesh%Force(I,J) = m%F_D(I,J) + m%F_A(I,J) + m%F_I(I,J) + m%F_B(I,J) + m%F_BF(I,J) + m%F_If(i,j) + m%F_WMG(i,j) + m%F_IMG(i,j) + ! ELSE + ! y%Mesh%Moment(I-3,J) = m%F_D(I,J) + m%F_A(I,J) + m%F_I(I,J) + m%F_B(I,J) + m%F_BF(I,J) + m%F_If(i,j) + m%F_WMG(i,j) + m%F_IMG(i,j) + ! END IF + ! END DO ! + !end do + + ! --- Hydrodynamic drag loads: joints ! NOTE: All wave kinematics have already been zeroed out above the SWL or instantaneous wave height (for WaveStMod > 0), so loads derived from the kinematics will be correct ! without the use of a nodeInWater value, but other loads need to be multiplied by nodeInWater to zero them out above the SWL or instantaneous wave height. - DO J = 1, y%LumpedMesh%Nnodes + DO J = 1, p%NJoints ! Obtain the node index because WaveVel, WaveAcc, and WaveDynP are defined in the node indexing scheme, not the markers - nodeIndx = p%lumpedToNodeIndx(J) - nodeInWater = REAL( InterpWrappedStpInt( REAL(Time, SiKi), p%WaveTime(:), p%nodeInWater(:,nodeIndx), m%LastIndWave, p%NStepWave + 1 ), ReKi ) - ! Determine the dynamic pressure at the marker - m%L_FDynP(J) = InterpWrappedStpReal ( REAL(Time, SiKi), p%WaveTime(:), p%WaveDynP(:,nodeIndx), & - m%LastIndWave, p%NStepWave + 1 ) + ! Compute the dot product of the relative velocity vector with the directional Area of the Joint + vmag = m%nodeInWater(j) * ( m%vrel(1,j)*p%An_End(1,J) + m%vrel(2,j)*p%An_End(2,J) + m%vrel(3,j)*p%An_End(3,J) ) - DO I=1,3 - ! Determine the fluid acceleration and velocity at the marker - m%L_FA(I,J) = InterpWrappedStpReal ( REAL(Time, SiKi), p%WaveTime(:), p%WaveAcc(:,nodeIndx,I), & - m%LastIndWave, p%NStepWave + 1 ) - - m%L_FV(I,J) = InterpWrappedStpReal ( REAL(Time, SiKi), p%WaveTime(:), p%WaveVel(:,nodeIndx,I), & - m%LastIndWave, p%NStepWave + 1 ) - vrel(I) = m%L_FV(I,J) - u%LumpedMesh%TranslationVel(I,J) - END DO + !NOTE: The PropPot values are only for members, and when the p%AM_End, p%DP_Const_End, p%Mass_MG_End, and p%I_MG_End are computed at init, + ! contributions to these values are added only if the member connecting to the joint is NOT modeled with potential flow theory + ! However, the p%An_End term used data from ALL members attached to a node, regardless of the PropPot setting. + ! Lumped added mass loads + qdotdot = reshape((/u%Mesh%TranslationAcc(:,J),u%Mesh%RotationAcc(:,J)/),(/6/)) + m%F_A_End(:,J) = m%nodeInWater(j) * matmul( p%AM_End(:,:,J) , ( - qdotdot(1:3)) ) - - ! Compute the dot product of the relative velocity vector with the directional Area of the Joint - vmag = nodeInWater * ( vrel(1)*p%L_An(1,J) + vrel(2)*p%L_An(2,J) + vrel(3)*p%L_An(3,J) ) - AnProd = p%L_An(1,J)**2 + p%L_An(2,J)**2 + p%L_An(3,J)**2 - IF (EqualRealNos(AnProd, 0.0_ReKi)) THEN - dragFactor = 0.0 - ELSE - dragFactor = p%Nodes(nodeIndx)%JAxCd*p%WtrDens*abs(vmag)*vmag / ( 4.0_ReKi * AnProd ) - END IF + ! TODO: The original code did not multiply by nodeInWater, but should we? GJH + m%F_I_End(:,J) = (p%DP_Const_End(:,j) * m%FDynP(j) + matmul(p%AM_End(:,:,j),m%FA(:,j))) - - ! Lumped added mass loads - qdotdot = reshape((/u%LumpedMesh%TranslationAcc(:,J),u%LumpedMesh%RotationAcc(:,J)/),(/6/)) - m%L_F_AM(:,J) = matmul( p%L_AM_M(:,:,J) , ( - qdotdot) ) - DO I=1,3 - m%L_F_AM(I,J) = nodeInWater * m%L_F_AM(I,J) ! Note that the rotational components are zero because L_AM_M is populated with only the upper-left 3x3 - END DO + ! Marine growth inertia: ends: Section 4.2.2 + m%F_IMG_End(1:3,j) = -m%nodeInWater(j) * p%Mass_MG_End(j)*qdotdot(1:3) + m%F_IMG_End(4:6,j) = -m%nodeInWater(j) * (matmul(p%I_MG_End(:,:,j),qdotdot(4:6)) - cross_product(u%Mesh%RotationVel(:,J),matmul(p%I_MG_End(:,:,j),u%Mesh%RotationVel(:,J)))) DO I=1,6 ! We are now combining the dynamic pressure term into the inertia term - m%L_F_I(I,J) = InterpWrappedStpReal ( REAL(Time, SiKi), p%WaveTime(:), p%L_F_I(:,I,J), & - m%LastIndWave, p%NStepWave + 1 ) + IF (I < 4 ) THEN - - m%L_F_D(I,J) = p%L_An(I,J)*dragFactor - m%L_F_B(I,J) = nodeInWater*p%L_F_B(I,J) - y%LumpedMesh%Force(I,J) = m%L_F_AM(I,J) + m%L_F_D(I,J) + m%L_F_B(I,J) + m%L_F_I(I,J) + p%L_F_BF(I,J) + + + m%F_D_End(i,j) = p%An_End(i,j)*p%DragConst_End(j)*abs(vmag)*vmag ! Note: vmag is zero if node is not in the water + y%Mesh%Force(i,j) = y%Mesh%Force(i,j) + m%F_D_End(i,j) + m%F_I_End(i,j) + p%F_WMG_End(i,j) + m%F_B_End(i,j) + m%F_BF_End(i,j) + m%F_A_End(i,j) + m%F_IMG_End(i,j) ELSE - m%L_F_B(I,J) = nodeInWater*p%L_F_B(I,J) - y%LumpedMesh%Moment(I-3,J) = m%L_F_AM(I,J) + m%L_F_B(I,J) + p%L_F_BF(I,J) + y%Mesh%Moment(i-3,j) = y%Mesh%Moment(i-3,j) + m%F_B_End(i,j) + m%F_BF_End(i,j) + m%F_IMG_End(i,j) END IF - - - END DO - ENDDO + END DO ! I=1,6 + ENDDO ! J = 1, p%NJoints ! OutSwtch determines whether or not to actually output results via the WriteOutput array ! 1 = Morison will generate an output file of its own. 2 = the caller will handle the outputs, but @@ -4690,7 +3253,7 @@ SUBROUTINE Morison_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, IF ( p%OutSwtch > 0 ) THEN ! Map calculated results into the AllOuts Array - CALL MrsnOut_MapOutputs(Time, y, p, u, m, AllOuts, ErrStat, ErrMsg) + CALL MrsnOut_MapOutputs(Time, y, p, u, m, AllOuts, errStat, errMsg) ! Put the output data in the WriteOutput array @@ -4705,17 +3268,109 @@ SUBROUTINE Morison_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, ! Generate output into the output file IF ( p%OutSwtch == 1 .OR. p%OutSwtch == 3 ) THEN - CALL MrsnOut_WriteOutputs( p%UnOutFile, Time, y, p, ErrStat, ErrMsg ) + CALL MrsnOut_WriteOutputs( p%UnOutFile, Time, y, p, errStat, errMsg ) END IF END IF END SUBROUTINE Morison_CalcOutput +subroutine LumpDistrHydroLoads( f_hydro, k_hat, dl, h_c, lumpedLoad ) + real(ReKi), intent(in ) :: f_hydro(3) + real(ReKi), intent(in ) :: k_hat(3) + real(ReKi), intent(in ) :: dl + real(ReKi), intent(in ) :: h_c + real(ReKi), intent(inout) :: lumpedLoad(6) + !lumpedLoad(1:3) = lumpedLoad(1:3) + f_hydro*dl + !lumpedLoad(4:6) = lumpedLoad(4:6) + cross_product(k_hat*h_c, f_hydro)*dl + lumpedLoad(1:3) = f_hydro*dl + lumpedLoad(4:6) = cross_product(k_hat*h_c, f_hydro)*dl +end subroutine LumpDistrHydroLoads + +! Takes loads on node i in element tilted frame and converts to 6DOF loads at node i and adjacent node +SUBROUTINE DistributeElementLoads(Fl, Fr, M, sinPhi, cosPhi, SinBeta, cosBeta, alpha, F1, F2) + + REAL(ReKi), INTENT ( IN ) :: Fl ! (N) axial load about node i + REAL(ReKi), INTENT ( IN ) :: Fr ! (N) radial load about node i in direction of tilt + REAL(ReKi), INTENT ( IN ) :: M ! (N-m) radial moment about node i, positive in direction of tilt angle + REAL(ReKi), INTENT ( IN ) :: sinPhi ! trig functions of tilt angle + REAL(ReKi), INTENT ( IN ) :: cosPhi + REAL(ReKi), INTENT ( IN ) :: sinBeta ! trig functions of heading of tilt + REAL(ReKi), INTENT ( IN ) :: cosBeta + REAL(ReKi), INTENT ( IN ) :: alpha ! fraction of load staying with node i (1-alpha goes to other node) + + REAL(ReKi), INTENT ( OUT ) :: F1(6) ! (N, Nm) force/moment vector for node i + REAL(ReKi), INTENT ( OUT ) :: F2(6) ! (N, Nm) force/moment vector for the other node (whether i+1, or i-1) + + + !F1(1) = F1(1) + cosBeta*(Fl*sinPhi + Fr*cosPhi)*alpha + !F1(2) = F1(2) - sinBeta*(Fl*sinPhi + Fr*cosPhi)*alpha + !F1(3) = F1(3) + (Fl*cosPhi - Fr*sinPhi)*alpha + !F1(4) = F1(4) + sinBeta * M *alpha + !F1(5) = F1(5) + cosBeta * M *alpha + !!F1(6) = F1(6) + 0.0 + ! + !F2(1) = F2(1) + cosBeta*(Fl*sinPhi + Fr*cosPhi)*(1-alpha) + !F2(2) = F2(2) - sinBeta*(Fl*sinPhi + Fr*cosPhi)*(1-alpha) + !F2(3) = F2(3) + (Fl*cosPhi - Fr*sinPhi)*(1-alpha) + !F2(4) = F2(4) + sinBeta * M *(1-alpha) + !F2(5) = F2(5) + cosBeta * M *(1-alpha) + !!F2(6) = F2(6) + 0.0 + + F1(1) = cosBeta*(Fl*sinPhi + Fr*cosPhi)*alpha + F1(2) = sinBeta*(Fl*sinPhi + Fr*cosPhi)*alpha + F1(3) = (Fl*cosPhi - Fr*sinPhi)*alpha + F1(4) = -sinBeta * M *alpha + F1(5) = cosBeta * M *alpha + F1(6) = 0.0 + + F2(1) = cosBeta*(Fl*sinPhi + Fr*cosPhi)*(1-alpha) + F2(2) = sinBeta*(Fl*sinPhi + Fr*cosPhi)*(1-alpha) + F2(3) = (Fl*cosPhi - Fr*sinPhi)*(1-alpha) + F2(4) = -sinBeta * M *(1-alpha) + F2(5) = cosBeta * M *(1-alpha) + F2(6) = 0.0 + + !F1(1) = cosBeta*(-Fl*sinPhi + Fr*cosPhi)*alpha + !F1(2) = sinBeta*(-Fl*sinPhi + Fr*cosPhi)*alpha + !F1(3) = (Fl*cosPhi + Fr*sinPhi)*alpha + !F1(4) = -sinBeta * M *alpha + !F1(5) = cosBeta * M *alpha + !F1(6) = 0.0 + ! + !F2(1) = cosBeta*(-Fl*sinPhi + Fr*cosPhi)*(1-alpha) + !F2(2) = sinBeta*(-Fl*sinPhi + Fr*cosPhi)*(1-alpha) + !F2(3) = (Fl*cosPhi + Fr*sinPhi)*(1-alpha) + !F2(4) = -sinBeta * M *(1-alpha) + !F2(5) = cosBeta * M *(1-alpha) + !F2(6) = 0.0 + +END SUBROUTINE DistributeElementLoads + + +! Takes loads on end node i and converts to 6DOF loads, adding to the nodes existing loads +SUBROUTINE AddEndLoad(Fl, M, sinPhi, cosPhi, SinBeta, cosBeta, Fi) + + REAL(ReKi), INTENT ( IN ) :: Fl ! (N) axial load about node i + REAL(ReKi), INTENT ( IN ) :: M ! (N-m) radial moment about node i, positive in direction of tilt angle + REAL(ReKi), INTENT ( IN ) :: sinPhi ! trig functions of tilt angle + REAL(ReKi), INTENT ( IN ) :: cosPhi + REAL(ReKi), INTENT ( IN ) :: sinBeta ! trig functions of heading of tilt + REAL(ReKi), INTENT ( IN ) :: cosBeta + REAL(ReKi), INTENT ( INOUT ) :: Fi(6) ! (N, Nm) force/moment vector for end node i + + Fi(1) = Fi(1) + Fl*sinPhi*cosBeta + Fi(2) = Fi(2) + Fl*sinPhi*sinBeta + Fi(3) = Fi(3) + Fl*cosPhi + Fi(4) = Fi(4) - M*sinBeta + Fi(5) = Fi(5) + M*cosBeta + +END SUBROUTINE AddEndLoad + !---------------------------------------------------------------------------------------------------------------------------------- !> Tight coupling routine for computing derivatives of continuous states -SUBROUTINE Morison_CalcContStateDeriv( Time, u, p, x, xd, z, OtherState, m, dxdt, ErrStat, ErrMsg ) +SUBROUTINE Morison_CalcContStateDeriv( Time, u, p, x, xd, z, OtherState, m, dxdt, errStat, errMsg ) !.................................................................................................................................. REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds @@ -4727,14 +3382,14 @@ SUBROUTINE Morison_CalcContStateDeriv( Time, u, p, x, xd, z, OtherState, m, dxdt TYPE(Morison_OtherStateType), INTENT(IN ) :: OtherState !< Other states at Time TYPE(Morison_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables TYPE(Morison_ContinuousStateType), INTENT( OUT) :: dxdt !< Continuous state derivatives at Time - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + INTEGER(IntKi), INTENT( OUT) :: errStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: errMsg !< Error message if errStat /= ErrID_None - ! Initialize ErrStat + ! Initialize errStat - ErrStat = ErrID_None - ErrMsg = "" + errStat = ErrID_None + errMsg = "" ! Compute the first time derivatives of the continuous states here: @@ -4745,7 +3400,7 @@ SUBROUTINE Morison_CalcContStateDeriv( Time, u, p, x, xd, z, OtherState, m, dxdt END SUBROUTINE Morison_CalcContStateDeriv !---------------------------------------------------------------------------------------------------------------------------------- !> Tight coupling routine for updating discrete states -SUBROUTINE Morison_UpdateDiscState( Time, u, p, x, xd, z, OtherState, m, ErrStat, ErrMsg ) +SUBROUTINE Morison_UpdateDiscState( Time, u, p, x, xd, z, OtherState, m, errStat, errMsg ) !.................................................................................................................................. REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds @@ -4757,14 +3412,14 @@ SUBROUTINE Morison_UpdateDiscState( Time, u, p, x, xd, z, OtherState, m, ErrStat TYPE(Morison_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at Time TYPE(Morison_OtherStateType), INTENT(IN ) :: OtherState !< Other states at Time TYPE(Morison_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + INTEGER(IntKi), INTENT( OUT) :: errStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: errMsg !< Error message if errStat /= ErrID_None - ! Initialize ErrStat + ! Initialize errStat - ErrStat = ErrID_None - ErrMsg = "" + errStat = ErrID_None + errMsg = "" ! Update discrete states here: @@ -4774,7 +3429,7 @@ SUBROUTINE Morison_UpdateDiscState( Time, u, p, x, xd, z, OtherState, m, ErrStat END SUBROUTINE Morison_UpdateDiscState !---------------------------------------------------------------------------------------------------------------------------------- !> Tight coupling routine for solving for the residual of the constraint state equations -SUBROUTINE Morison_CalcConstrStateResidual( Time, u, p, x, xd, z, OtherState, m, z_residual, ErrStat, ErrMsg ) +SUBROUTINE Morison_CalcConstrStateResidual( Time, u, p, x, xd, z, OtherState, m, z_residual, errStat, errMsg ) !.................................................................................................................................. REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds @@ -4787,14 +3442,14 @@ SUBROUTINE Morison_CalcConstrStateResidual( Time, u, p, x, xd, z, OtherState, m, TYPE(Morison_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables TYPE(Morison_ConstraintStateType), INTENT( OUT) :: z_residual !< Residual of the constraint state equations using !! the input values described above - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + INTEGER(IntKi), INTENT( OUT) :: errStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: errMsg !< Error message if errStat /= ErrID_None - ! Initialize ErrStat + ! Initialize errStat - ErrStat = ErrID_None - ErrMsg = "" + errStat = ErrID_None + errMsg = "" ! Solve for the constraint states here: diff --git a/modules/hydrodyn/src/Morison.txt b/modules/hydrodyn/src/Morison.txt index 5326fb452c..2837ece0b8 100644 --- a/modules/hydrodyn/src/Morison.txt +++ b/modules/hydrodyn/src/Morison.txt @@ -15,204 +15,223 @@ include Registry_NWTC_Library.txt # # -param Morison/Morison unused INTEGER MaxMrsnOutputs - 4032 - "" - -typedef Morison/Morison Morison_JointType INTEGER JointID - - - "" - -typedef ^ ^ ReKi JointPos {3} - - "" - -typedef ^ ^ INTEGER JointAxID - - - "" - -typedef ^ ^ INTEGER JointAxIDIndx - - - "" - -typedef ^ ^ INTEGER JointOvrlp - - - "" - -typedef ^ ^ INTEGER NConnections - - - "" - -typedef ^ ^ INTEGER ConnectionList {10} - - "" - -typedef Morison/Morison Morison_MemberPropType INTEGER PropSetID - - - "" - -typedef ^ ^ ReKi PropD - - - "" - -typedef ^ ^ ReKi PropThck - - - "" - -typedef Morison/Morison Morison_FilledGroupType INTEGER FillNumM - - - "" - -typedef ^ ^ INTEGER FillMList {:} - - "" - -typedef ^ ^ ReKi FillFSLoc - - - "" - -typedef ^ ^ CHARACTER(80) FillDensChr - - - "" - -typedef ^ ^ ReKi FillDens - - - "" - -typedef Morison/Morison Morison_CoefDpths ReKi Dpth - - - "" - -typedef ^ ^ ReKi DpthCd - - - "" - -typedef ^ ^ ReKi DpthCdMG - - - "" - -typedef ^ ^ ReKi DpthCa - - - "" - -typedef ^ ^ ReKi DpthCaMG - - - "" - -typedef ^ ^ ReKi DpthCp - - - "" - -typedef ^ ^ ReKi DpthCpMG - - - "" - -typedef ^ ^ ReKi DpthAxCa - - - "" - -typedef ^ ^ ReKi DpthAxCaMG - - - "" - -typedef ^ ^ ReKi DpthAxCp - - - "" - -typedef ^ ^ ReKi DpthAxCpMG - - - "" - -typedef Morison/Morison Morison_AxialCoefType INTEGER AxCoefID - - - "" - -typedef ^ ^ ReKi AxCd - - - "" - -typedef ^ ^ ReKi AxCa - - - "" - -typedef ^ ^ ReKi AxCp - - - "" - -typedef Morison/Morison Morison_MemberInputType INTEGER MemberID - - - "" - -typedef ^ ^ INTEGER MJointID1 - - - "" - -typedef ^ ^ INTEGER MJointID2 - - - "" - -typedef ^ ^ INTEGER MJointID1Indx - - - "" - -typedef ^ ^ INTEGER MJointID2Indx - - - "" - -typedef ^ ^ INTEGER MPropSetID1 - - - "" - -typedef ^ ^ INTEGER MPropSetID2 - - - "" - -typedef ^ ^ INTEGER MPropSetID1Indx - - - "" - -typedef ^ ^ INTEGER MPropSetID2Indx - - - "" - -typedef ^ ^ ReKi MDivSize - - - "" - -typedef ^ ^ INTEGER MCoefMod - - - "" - -typedef ^ ^ INTEGER MmbrCoefIDIndx - - - "" - -typedef ^ ^ INTEGER MmbrFilledIDIndx - - - "" - -typedef ^ ^ LOGICAL PropPot - - - "" - -#typedef ^ ^ INTEGER MGSplitState - - - "" - -#typedef ^ ^ INTEGER WtrSplitState - - - "" - -typedef ^ ^ INTEGER NumSplits - - - "" - -typedef ^ ^ ReKi Splits {5} - - "" - -typedef ^ ^ ReKi R_LToG {3}{3} - - "" - -typedef Morison/Morison Morison_NodeType INTEGER NodeType - - - "" - -typedef ^ ^ INTEGER JointIndx - - - "" - -typedef ^ ^ ReKi JointPos {3} - - "" - +param Morison/Morison unused INTEGER MaxMrsnOutputs - 4599 - "Total number of possible Morison module output channels" - +typedef ^ Morison_JointType INTEGER JointID - - - "User-specified integer ID for the given joint" - +typedef ^ ^ ReKi Position {3} - - "Undisplaced location of the joint in the platform coordinate system" m +typedef ^ ^ INTEGER JointAxID - - - "Axial ID (found in the user-supplied Axial Coefficients Table) for this joint: used to determine axial coefs" - +typedef ^ ^ INTEGER JointAxIDIndx - - - "The index into the Axial Coefs arrays corresponding to the above Axial ID" - +typedef ^ ^ INTEGER JointOvrlp - - - "Joint overlap code [Unused" - +typedef ^ ^ INTEGER NConnections - - - "Number of members connecting to this joint" - +typedef ^ ^ INTEGER ConnectionList {10} - - "List of Members connected to this joint. The member index is what is stored, not the Member ID" - +typedef ^ Morison_MemberPropType INTEGER PropSetID - - - "User-specified integer ID for this group of properties" - +typedef ^ ^ ReKi PropD - - - "Diameter" m +typedef ^ ^ ReKi PropThck - - - "Wall thickness" m +typedef ^ Morison_FilledGroupType INTEGER FillNumM - - - "Number of members in the Fill Group" - +typedef ^ ^ INTEGER FillMList {:} - - "List of Member IDs for the members in this fill group" - +typedef ^ ^ ReKi FillFSLoc - - - "The free-surface location (in Z) for this fill group" m +typedef ^ ^ CHARACTER(80) FillDensChr - - - "String version of the Fill density [can be DEFAULT which sets the fill density to WtrDens]" kg/m^3 +typedef ^ ^ ReKi FillDens - - - "Numerical fill density" kg/m^3 +typedef ^ Morison_CoefDpths ReKi Dpth - - - "Depth location for these depth-based hydrodynamic coefs" m +typedef ^ ^ ReKi DpthCd - - - "Depth-based drag coef" - +typedef ^ ^ ReKi DpthCdMG - - - "Depth-based drag coef for marine growth" - +typedef ^ ^ ReKi DpthCa - - - "Depth-based Ca" - +typedef ^ ^ ReKi DpthCaMG - - - "Depth-based Ca for marine growth" - +typedef ^ ^ ReKi DpthCp - - - "Depth-based Cp" - +typedef ^ ^ ReKi DpthCpMG - - - "Depth-based Cp for marine growth" - +typedef ^ ^ ReKi DpthAxCd - - - "Depth-based Axial Cd" - +typedef ^ ^ ReKi DpthAxCdMG - - - "Depth-based Axial Cd for marine growth" - +typedef ^ ^ ReKi DpthAxCa - - - "Depth-based Axial Ca" - +typedef ^ ^ ReKi DpthAxCaMG - - - "Depth-based Axial Ca for marine growth" - +typedef ^ ^ ReKi DpthAxCp - - - "Depth-based Axial Cp" - +typedef ^ ^ ReKi DpthAxCpMG - - - "Depth-based Axial Cp for marine growth" - +typedef ^ Morison_AxialCoefType INTEGER AxCoefID - - - "User-supplied integer ID for this set of Axial coefs" - +typedef ^ ^ ReKi AxCd - - - "Axial Cd" - +typedef ^ ^ ReKi AxCa - - - "Axial Ca" - +typedef ^ ^ ReKi AxCp - - - "Axial Cp" - +# +typedef ^ Morison_MemberInputType INTEGER MemberID - - - "User-supplied integer ID for this member" - +typedef ^ ^ INTEGER NodeIndx {:} - - "Index of each of the member's nodes in the master node list" - +typedef ^ ^ INTEGER MJointID1 - - - "Joint ID for start of member" - +typedef ^ ^ INTEGER MJointID2 - - - "Joint ID for end of member" - +typedef ^ ^ INTEGER MJointID1Indx - - - "Index into the joint table for the start of this member" - +typedef ^ ^ INTEGER MJointID2Indx - - - "Index into the joint table for the end of this member" - +typedef ^ ^ INTEGER MPropSetID1 - - - "Property set ID for the start of this member" - +typedef ^ ^ INTEGER MPropSetID2 - - - "Property set ID for the end of this member" - +typedef ^ ^ INTEGER MPropSetID1Indx - - - "Index into the Property table for the start of this member" - +typedef ^ ^ INTEGER MPropSetID2Indx - - - "Index into the Property table for the end of this member" - +typedef ^ ^ ReKi MDivSize - - - "User-specified desired member discretization size for the final element" m +typedef ^ ^ INTEGER MCoefMod - - - "Which coef. model is being used for this member [1=simple, 2=depth-based, 3=member-based]" - +typedef ^ ^ INTEGER MmbrCoefIDIndx - - - "Index into the appropriate coefs table for this member's properties" - +typedef ^ ^ INTEGER MmbrFilledIDIndx - - - "Index into the filled group table if this is a filled member" - +typedef ^ ^ LOGICAL PropPot - - - "Flag T/F for whether the member is modeled with potential flow theory" - +typedef ^ ^ INTEGER NElements - - - "number of elements in this member" - +typedef ^ ^ ReKi RefLength - - - "the reference total length for this member" m +typedef ^ ^ ReKi dl - - - "the reference element length for this member (may be less than MDivSize to achieve uniform element lengths)" m +# +typedef ^ Morison_NodeType INTEGER JointIndx - - - "Joint index from the user joint table that this node corresponds to. If the software created this node, index is set to -1" - +typedef ^ ^ ReKi Position {3} - - "Position of the node in global coordinates" m typedef ^ ^ INTEGER JointOvrlp - - - "" - typedef ^ ^ INTEGER JointAxIDIndx - - - "" - -typedef ^ ^ INTEGER NConnections - - - "" - -typedef ^ ^ INTEGER ConnectionList {10} - - "" - -typedef ^ ^ INTEGER NConnectPreSplit - - - "" - -typedef ^ ^ ReKi Cd - - - "" - -typedef ^ ^ ReKi CdMG - - - "" - -typedef ^ ^ ReKi Ca - - - "" - -typedef ^ ^ ReKi CaMG - - - "" - -typedef ^ ^ ReKi Cp - - - "" - -typedef ^ ^ ReKi CpMG - - - "" - -typedef ^ ^ ReKi JAxCd - - - "" - -typedef ^ ^ ReKi JAxCa - - - "" - -typedef ^ ^ ReKi JAxCp - - - "" - -typedef ^ ^ ReKi AxCa - - - "" - -typedef ^ ^ ReKi AxCp - - - "" - -typedef ^ ^ ReKi AxCaMG - - - "" - -typedef ^ ^ ReKi AxCpMG - - - "" - -typedef ^ ^ ReKi R - - - "" - -typedef ^ ^ ReKi t - - - "" - -typedef ^ ^ ReKi tMG - - - "" - -typedef ^ ^ ReKi dRdz - - - "" - -typedef ^ ^ ReKi MGdensity - - - "" - -typedef ^ ^ ReKi FillFSLoc - - - "" - -typedef ^ ^ LOGICAL FillFlag - - - "" - -typedef ^ ^ ReKi FillDensity - - - "" - -typedef ^ ^ INTEGER InpMbrIndx - - - "" - -typedef ^ ^ ReKi InpMbrDist - - - "" - -typedef ^ ^ LOGICAL PropPot - - - "" - -typedef ^ ^ ReKi R_LToG {3}{3} - - "" - -typedef Morison/Morison Morison_MemberType INTEGER Node1Indx - - - "" - -typedef ^ ^ INTEGER Node2Indx - - - "" - -typedef ^ ^ ReKi R1 - - - "" - -typedef ^ ^ ReKi t1 - - - "" - -typedef ^ ^ ReKi R2 - - - "" - -typedef ^ ^ ReKi t2 - - - "" - -typedef ^ ^ ReKi Cd1 - - - "" - -typedef ^ ^ ReKi CdMG1 - - - "" - -typedef ^ ^ ReKi Ca1 - - - "" - -typedef ^ ^ ReKi CaMG1 - - - "" - -typedef ^ ^ ReKi Cp1 - - - "" - -typedef ^ ^ ReKi CpMG1 - - - "" - -typedef ^ ^ ReKi AxCa1 - - - "" - -typedef ^ ^ ReKi AxCaMG1 - - - "" - -typedef ^ ^ ReKi AxCp1 - - - "" - -typedef ^ ^ ReKi AxCpMG1 - - - "" - -typedef ^ ^ ReKi Cd2 - - - "" - -typedef ^ ^ ReKi CdMG2 - - - "" - -typedef ^ ^ ReKi Ca2 - - - "" - -typedef ^ ^ ReKi CaMG2 - - - "" - -typedef ^ ^ ReKi Cp2 - - - "" - -typedef ^ ^ ReKi CpMG2 - - - "" - -typedef ^ ^ ReKi AxCa2 - - - "" - -typedef ^ ^ ReKi AxCaMG2 - - - "" - -typedef ^ ^ ReKi AxCp2 - - - "" - -typedef ^ ^ ReKi AxCpMG2 - - - "" - -typedef ^ ^ ReKi InpMbrDist1 - - - "" - -typedef ^ ^ ReKi InpMbrDist2 - - - "" - -typedef ^ ^ ReKi InpMbrLen - - - "" - -typedef ^ ^ INTEGER InpMbrIndx - - - "" - -typedef ^ ^ ReKi R_LToG {3}{3} - - "" - -#typedef ^ ^ INTEGER MGSplitState - - - "" - -#typedef ^ ^ INTEGER WtrSplitState - - - "" - -typedef ^ ^ INTEGER NumSplits - - - "" - -typedef ^ ^ ReKi Splits {5} - - "" - -typedef ^ ^ ReKi MGvolume - - - "" - -typedef ^ ^ ReKi MDivSize - - - "" - -typedef ^ ^ INTEGER MCoefMod - - - "" - -typedef ^ ^ INTEGER MmbrCoefIDIndx - - - "" - -typedef ^ ^ INTEGER MmbrFilledIDIndx - - - "" - -typedef ^ ^ ReKi FillFSLoc - - - "" - -typedef ^ ^ ReKi FillDens - - - "" - -typedef ^ ^ ReKi F_Bouy {6} - - "" - -typedef ^ ^ ReKi F_DP {6} - - "" - -typedef ^ ^ LOGICAL PropPot - - - "" - -typedef Morison/Morison Morison_CoefMembers INTEGER MemberID - - - "" - -typedef ^ ^ ReKi MemberCd1 - - - "" - -typedef ^ ^ ReKi MemberCd2 - - - "" - -typedef ^ ^ ReKi MemberCdMG1 - - - "" - -typedef ^ ^ ReKi MemberCdMG2 - - - "" - -typedef ^ ^ ReKi MemberCa1 - - - "" - -typedef ^ ^ ReKi MemberCa2 - - - "" - -typedef ^ ^ ReKi MemberCaMG1 - - - "" - -typedef ^ ^ ReKi MemberCaMG2 - - - "" - -typedef ^ ^ ReKi MemberCp1 - - - "" - -typedef ^ ^ ReKi MemberCp2 - - - "" - -typedef ^ ^ ReKi MemberCpMG1 - - - "" - -typedef ^ ^ ReKi MemberCpMG2 - - - "" - -typedef ^ ^ ReKi MemberAxCa1 - - - "" - -typedef ^ ^ ReKi MemberAxCa2 - - - "" - -typedef ^ ^ ReKi MemberAxCaMG1 - - - "" - -typedef ^ ^ ReKi MemberAxCaMG2 - - - "" - -typedef ^ ^ ReKi MemberAxCp1 - - - "" - -typedef ^ ^ ReKi MemberAxCp2 - - - "" - -typedef ^ ^ ReKi MemberAxCpMG1 - - - "" - -typedef ^ ^ ReKi MemberAxCpMG2 - - - "" - -typedef Morison/Morison Morison_MGDepthsType ReKi MGDpth - - - "" - -typedef ^ ^ ReKi MGThck - - - "" - -typedef ^ ^ ReKi MGDens - - - "" - -typedef Morison/Morison Morison_MOutput INTEGER MemberID - - - "" - -typedef ^ ^ INTEGER NOutLoc - - - "" - -typedef ^ ^ ReKi NodeLocs {:} - - "" - -typedef ^ ^ INTEGER MemberIDIndx - - - "" - -typedef ^ ^ INTEGER Marker1 {:} - - "" - -typedef ^ ^ INTEGER Marker2 {:} - - "" - -typedef ^ ^ ReKi s {:} - - "" - -typedef Morison/Morison Morison_JOutput INTEGER JointID - - - "" - -typedef ^ ^ INTEGER JointIDIndx - - - "" - -typedef ^ ^ INTEGER NumMarkers - - - "" - -typedef ^ ^ INTEGER Markers {10} - - "" - +typedef ^ ^ INTEGER NConnections - - - "Number of elements connecting to this node" - +typedef ^ ^ INTEGER ConnectionList {10} - - "Indices of all the members connected to this node (positive if end 1, negative if end 2)" - +typedef ^ ^ ReKi JAxCd - - - "Nodal lumped (joint) axial Cd" - +typedef ^ ^ ReKi JAxCa - - - "Nodal lumped (joint) axial Cp" - +typedef ^ ^ ReKi JAxCp - - - "Nodal lumped (joint) axial Ca" - +typedef ^ ^ ReKi FillDensity - - - "Fill fluid density" kg/m^3 +typedef ^ ^ ReKi tMG - - - "Nodal thickness with marine growth " m +typedef ^ ^ ReKi MGdensity - - - "Nodal density of marine growth" kg/m^3 +# +typedef ^ Morison_MemberType INTEGER NodeIndx {:} - - "Index of each of the member's nodes in the master node list" - +typedef ^ ^ INTEGER MemberID - - - "User-supplied integer ID for this member" - +typedef ^ ^ INTEGER NElements - - - "number of elements in this member" - +typedef ^ ^ ReKi RefLength - - - "the reference total length for this member" m +typedef ^ ^ ReKi cosPhi_ref - - - "the reference cosine of the inclination angle of the member" - +typedef ^ ^ ReKi dl - - - "the reference element length for this member (may be less than MDivSize to achieve uniform element lengths)" m +typedef ^ ^ ReKi k {3} - - "unit vector of the member's orientation (may be changed to per-element once additional flexibility is accounted for in HydroDyn)" m +typedef ^ ^ ReKi kkt {3}{3} - - "matrix of matmul(k_hat, transpose(k_hat)" - +typedef ^ ^ ReKi Ak {3}{3} - - "matrix of I - kkt" - +typedef ^ ^ ReKi R {:} - - "outer member radius at each node" m +typedef ^ ^ ReKi RMG {:} - - "radius at each node including marine growth" m +typedef ^ ^ ReKi Rin {:} - - "inner member radius at node, equivalent to radius of water ballast at this node if filled" m +typedef ^ ^ ReKi tMG {:} - - "Nodal thickness with marine growth (of member at node location)" m +typedef ^ ^ ReKi MGdensity {:} - - "Nodal density of marine growth" kg/m^3 +typedef ^ ^ ReKi dRdl_mg {:} - - "taper dr/dl of outer surface including marine growth of each element" - +typedef ^ ^ ReKi dRdl_in {:} - - "taper dr/dl of interior surface of each element" - +typedef ^ ^ ReKi Vinner - - - "Member volume without marine growth" m^3 +typedef ^ ^ ReKi Vouter - - - "Member volume including marine growth" m^3 +typedef ^ ^ ReKi Vballast - - - "Member ballast volume" m^3 +typedef ^ ^ ReKi Vsubmerged - - - "Submerged volume corresponding to portion of Member in the water" m^3 +typedef ^ ^ ReKi l_fill - - - "fill length along member axis from start node 1" m +typedef ^ ^ ReKi h_fill - - - "fill length of partially flooded element" m +typedef ^ ^ ReKi z_overfill - - - "if member is fully filled, the head height of the fill pressure at the end node N+1. Zero if member is partially filled." m +typedef ^ ^ ReKi h_floor - - - "the distance from the node to the seabed along the member axis (negative value)" m +typedef ^ ^ INTEGER i_floor - - - "the number of the element that pierces the seabed (zero if the member doesn't pierce it)" - +typedef ^ ^ LOGICAL doEndBuoyancy - - - "compute the end plate effect for the hightest node of this member" - +typedef ^ ^ INTEGER memfloodstatus - - - "Member-level flooded status for each elemen: 0 unflooded or fully below seabed, 2 partially flooded, 1 fully flooded " - +typedef ^ ^ INTEGER floodstatus {:} - - "flooded status for each element: 0 unflooded or fully below seabed, 1 fully flooded, 2 partially flooded" - +typedef ^ ^ ReKi alpha {:} - - "relative volume centroid of each element including marine growth, from node i to node i+1" - +typedef ^ ^ ReKi alpha_fb {:} - - "relative volume centroid of each element's flooded ballast, from node i to node i+1" - +typedef ^ ^ ReKi alpha_fb_star {:} - - "load distribution factor for each element after adjusting alpha_fb for node reference depths" - +typedef ^ ^ ReKi Cd {:} - - "Member Cd at each node" - +typedef ^ ^ ReKi Ca {:} - - "Member Ca at each node" - +typedef ^ ^ ReKi Cp {:} - - "Member Cp at each node" - +typedef ^ ^ ReKi AxCd {:} - - "Member axial Cd at each node" - +typedef ^ ^ ReKi AxCa {:} - - "Member axial Ca at each node" - +typedef ^ ^ ReKi AxCp {:} - - "Member axial Cp at each node" - +typedef ^ ^ ReKi m_fb_l {:} - - "mass of flooded ballast in lower portion of each element" kg +typedef ^ ^ ReKi m_fb_u {:} - - "mass of flooded ballast in upper portion of each element" kg +typedef ^ ^ ReKi h_cfb_l {:} - - "distance to flooded ballast centroid from node point in lower portion of each element" m +typedef ^ ^ ReKi h_cfb_u {:} - - "distance to flooded ballast centroid from node point in upper portion of each element" m +typedef ^ ^ ReKi I_lfb_l {:} - - "axial moment of inertia of flooded ballast in lower portion of each element" kg-m^2 +typedef ^ ^ ReKi I_lfb_u {:} - - "axial moment of inertia of flooded ballast in upper portion of each element" kg-m^2 +typedef ^ ^ ReKi I_rfb_l {:} - - "radial moment of inertia of flooded ballast in lower portion of each element" kg-m^2 +typedef ^ ^ ReKi I_rfb_u {:} - - "radial moment of inertia of flooded ballast in upper portion of each element" kg-m^2 +typedef ^ ^ ReKi m_mg_l {:} - - "mass of marine growth in lower portion of each element" kg +typedef ^ ^ ReKi m_mg_u {:} - - "mass of marine growth in upper portion of each element" kg +typedef ^ ^ ReKi h_cmg_l {:} - - "distance to marine growth centroid from node point in lower portion of each element" m +typedef ^ ^ ReKi h_cmg_u {:} - - "distance to marine growth centroid from node point in upper portion of each element" m +typedef ^ ^ ReKi I_lmg_l {:} - - "axial moment of inertia of marine growth in lower portion of each element" kg-m^2 +typedef ^ ^ ReKi I_lmg_u {:} - - "axial moment of inertia of marine growth in upper portion of each element" kg-m^2 +typedef ^ ^ ReKi I_rmg_l {:} - - "radial moment of inertia of marine growth in lower portion of each element" kg-m^2 +typedef ^ ^ ReKi I_rmg_u {:} - - "radial moment of inertia of flooded ballast in upper portion of each element" kg-m^2 +typedef ^ ^ ReKi Cfl_fb {:} - - "axial force constant due to flooded ballast, for each element" N +typedef ^ ^ ReKi Cfr_fb {:} - - "radial force constant due to flooded ballast, for each element" N +typedef ^ ^ ReKi CM0_fb {:} - - "moment constant due to flooded ballast, for each element about lower node" Nm +typedef ^ ^ ReKi MGvolume - - - "Volume of marine growth material for this member/element" m^3 +typedef ^ ^ ReKi MDivSize - - - "User-requested final element length (actual length may vary from this request)" m +typedef ^ ^ INTEGER MCoefMod - - - "Coefs model for member: 1 = simple, 2 =depth, 3 = member-based " - +typedef ^ ^ INTEGER MmbrCoefIDIndx - - - "If MCoefMod=3, then this is the index for the member's coefs in the master Member Coefs Table" - +typedef ^ ^ INTEGER MmbrFilledIDIndx - - - "If this member is part of a fill group, this is the index into the master fill group table, if not = -1" - +typedef ^ ^ ReKi FillFSLoc - - - "Z-location of the filled free-surface" m +typedef ^ ^ ReKi FillDens - - - "Filled fluid density" kg/m^3 +typedef ^ ^ LOGICAL PropPot - - - "Is this element/member modeled with potential flow theory T/F" - +typedef ^ ^ LOGICAL Flipped - - - "Was the member flipped in a reordering event? Need to know this to get the correct normal vector to the ends" - +# +typedef ^ Morison_MemberLoads ReKi F_D {:}{:} - - "Member-based (side-effects) Nodal viscous drag loads at time t" - +typedef ^ ^ ReKi F_I {:}{:} - - "Member-based (side-effects) Nodal inertial loads at time t" - +typedef ^ ^ ReKi F_A {:}{:} - - "Member-based (side-effects) Nodal added mass loads at time t" - +typedef ^ ^ ReKi F_B {:}{:} - - "Member-based (side-effects) Nodal buoyancy loads" - +typedef ^ ^ ReKi F_BF {:}{:} - - "Member-based (side-effects) Nodal flooded ballast weight/buoyancy loads" - +typedef ^ ^ ReKi F_If {:}{:} - - "Member-based (side-effects) Nodal flooded ballast inertia loads" - +typedef ^ ^ ReKi F_WMG {:}{:} - - "Member-based (side-effects) Nodal marine growth weight loads" - +typedef ^ ^ ReKi F_IMG {:}{:} - - "Member-based (side-effects) Nodal marine growth inertia loads" - +typedef ^ ^ ReKi FV {:}{:} - - "Fluid velocity at line element node at time t, which may not correspond to the WaveTime array of times" - +typedef ^ ^ ReKi FA {:}{:} - - "Fluid acceleration at line element node at time t, which may not correspond to the WaveTime array of times" - +typedef ^ ^ ReKi F_DP {:}{:} - - "Lumped dynamic pressure loads at time t, which may not correspond to the WaveTime array of times" - +# +typedef ^ Morison_CoefMembers INTEGER MemberID - - - "User-specified integer id for the Member-based coefs" - +typedef ^ ^ ReKi MemberCd1 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberCd2 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberCdMG1 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberCdMG2 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberCa1 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberCa2 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberCaMG1 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberCaMG2 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberCp1 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberCp2 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberCpMG1 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberCpMG2 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberAxCd1 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberAxCd2 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberAxCdMG1 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberAxCdMG2 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberAxCa1 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberAxCa2 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberAxCaMG1 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberAxCaMG2 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberAxCp1 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberAxCp2 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberAxCpMG1 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ ^ ReKi MemberAxCpMG2 - - - "Member-based coefs, see above descriptions for meanings (1 = start, 2=end)" - +typedef ^ Morison_MGDepthsType ReKi MGDpth - - - "Marine growth depth location for these properties" m +typedef ^ ^ ReKi MGThck - - - "Marine growth thickness" m +typedef ^ ^ ReKi MGDens - - - "Marine growth density" kg/m^3 +typedef ^ Morison_MOutput INTEGER MemberID - - - "Member ID for requested output" - +typedef ^ ^ INTEGER NOutLoc - - - "The number of requested output locations" - +typedef ^ ^ ReKi NodeLocs {:} - - "Normalized locations along user-specified member for the outputs" - +typedef ^ ^ INTEGER MemberIDIndx - - - "Index for member in the master list" - +typedef ^ ^ INTEGER MeshIndx1 {:} - - "Index of node in Mesh for the start of the member element" - +typedef ^ ^ INTEGER MeshIndx2 {:} - - "Index of node in Mesh for the end of the member element" - +typedef ^ ^ INTEGER MemberIndx1 {:} - - "Index of Member nodes for the start of the member element" - +typedef ^ ^ INTEGER MemberIndx2 {:} - - "Index of Member nodes for the end of the member element" - +typedef ^ ^ ReKi s {:} - - "Linear interpolation factor between node1 and node2 for the output location" - +typedef ^ Morison_JOutput INTEGER JointID - - - "Joint ID for the requested output" - +typedef ^ ^ INTEGER JointIDIndx - - - "Joint index in the master list" - # ..... Initialization data ....................................................................................................... # Define inputs that the initialization routine may need here: # e.g., the name of the input file, the file root name,etc. # -typedef Morison/Morison InitInputType ReKi Gravity - - - "" - -typedef ^ ^ ReKi WtrDens - - - "" - -typedef ^ ^ ReKi WtrDpth - - - "" - -typedef ^ ^ ReKi MSL2SWL - - - "" - -typedef ^ ^ INTEGER NJoints - - - "" - -typedef ^ ^ INTEGER NNodes - - - "" - -typedef ^ ^ INTEGER TotalPossibleSuperMembers - - - "" - -typedef ^ ^ Morison_JointType InpJoints {:} - - "" - -typedef ^ ^ Morison_NodeType Nodes {:} - - "" - -typedef ^ ^ INTEGER NElements - - - "" - -typedef ^ ^ Morison_MemberType Elements {:} - - "" - -typedef ^ ^ INTEGER NAxCoefs - - - "" - -typedef ^ ^ Morison_AxialCoefType AxialCoefs {:} - - "" - -typedef ^ ^ INTEGER NPropSets - - - "" - -typedef ^ ^ Morison_MemberPropType MPropSets {:} - - "" - -typedef ^ ^ ReKi SimplCd - - - "" - -typedef ^ ^ ReKi SimplCdMG - - - "" - -typedef ^ ^ ReKi SimplCa - - - "" - -typedef ^ ^ ReKi SimplCaMG - - - "" - -typedef ^ ^ ReKi SimplCp - - - "" - -typedef ^ ^ ReKi SimplCpMG - - - "" - -typedef ^ ^ ReKi SimplAxCa - - - "" - -typedef ^ ^ ReKi SimplAxCaMG - - - "" - -typedef ^ ^ ReKi SimplAxCp - - - "" - -typedef ^ ^ ReKi SimplAxCpMG - - - "" - -typedef ^ ^ INTEGER NCoefDpth - - - "" - +typedef ^ InitInputType ReKi Gravity - - - "Gravity (scalar, positive-valued)" m/s^2 +typedef ^ ^ ReKi WtrDens - - - "Water density" kg/m^3 +typedef ^ ^ ReKi WtrDpth - - - "Water depth (positive-valued)" m +typedef ^ ^ ReKi MSL2SWL - - - "Mean Sea Level to Still Water Level offset" m +typedef ^ ^ INTEGER NJoints - - - "Number of user-specified joints" - +typedef ^ ^ INTEGER NNodes - - - "Total number of nodes in the final software model" - +typedef ^ ^ Morison_JointType InpJoints {:} - - "Array of user-specified joints" - +typedef ^ ^ Morison_NodeType Nodes {:} - - "Array of simulation node (some correspond to user-specified joints, others are created by software)" - +typedef ^ ^ INTEGER NAxCoefs - - - "Number of axial Coefs entries in input file table" - +typedef ^ ^ Morison_AxialCoefType AxialCoefs {:} - - "List of axial coefs" - +typedef ^ ^ INTEGER NPropSets - - - "Number of member property sets" - +typedef ^ ^ Morison_MemberPropType MPropSets {:} - - "List of Member property sets" - +typedef ^ ^ ReKi SimplCd - - - "Simple model drag coef" - +typedef ^ ^ ReKi SimplCdMG - - - "Simple model drag coef for marine growth" - +typedef ^ ^ ReKi SimplCa - - - "Simple model Ca" - +typedef ^ ^ ReKi SimplCaMG - - - "Simple model Ca for marine growth" - +typedef ^ ^ ReKi SimplCp - - - "Simple model Cp" - +typedef ^ ^ ReKi SimplCpMG - - - "Simple model Cp for marine growth" - +typedef ^ ^ ReKi SimplAxCd - - - "Simple model Axial Cd" - +typedef ^ ^ ReKi SimplAxCdMG - - - "Simple model Axial Cd for marine growth" - +typedef ^ ^ ReKi SimplAxCa - - - "Simple model Axial Ca" - +typedef ^ ^ ReKi SimplAxCaMG - - - "Simple model Axial Ca for marine growth" - +typedef ^ ^ ReKi SimplAxCp - - - "Simple model Axial Cp" - +typedef ^ ^ ReKi SimplAxCpMG - - - "Simple model Axial Cp for marine growth" - +typedef ^ ^ INTEGER NCoefDpth - - - "" - typedef ^ ^ Morison_CoefDpths CoefDpths {:} - - "" - typedef ^ ^ INTEGER NCoefMembers - - - "" - typedef ^ ^ Morison_CoefMembers CoefMembers {:} - - "" - -typedef ^ ^ INTEGER NMembers - - - "" - -typedef ^ ^ Morison_MemberInputType InpMembers {:} - - "" - +typedef ^ ^ INTEGER NMembers - - - "Number of user-specified members in the input file" - +typedef ^ ^ Morison_MemberInputType InpMembers {:} - - "Array of user-specified members" - typedef ^ ^ INTEGER NFillGroups - - - "" - typedef ^ ^ Morison_FilledGroupType FilledGroups {:} - - "" - typedef ^ ^ INTEGER NMGDepths - - - "" - @@ -241,11 +260,10 @@ typedef ^ ^ INTEGER # # Define outputs from the initialization routine here: # -typedef ^ InitOutputType MeshType DistribMesh - - - "" - -typedef ^ ^ MeshType LumpedMesh - - - "" - -typedef ^ ^ SiKi Morison_Rad {:} - - "radius of node (for FAST visualization)" (m) -typedef ^ ^ CHARACTER(ChanLen) WriteOutputHdr {:} - - "" - -typedef ^ ^ CHARACTER(ChanLen) WriteOutputUnt {:} - - "" - +#typedef ^ InitOutputType MeshType Mesh - - - "Unused?" - +#typedef ^ ^ SiKi Morison_Rad {:} - - "radius of node (for FAST visualization)" (m) +typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {:} - - "User-requested Output channel names" - +typedef ^ ^ CHARACTER(ChanLen) WriteOutputUnt {:} - - "" - # # # ..... States .................................................................................................................... @@ -256,7 +274,7 @@ typedef ^ ContinuousStateType SiKi # # Define discrete (nondifferentiable) states here: # -typedef ^ DiscreteStateType SiKi DummyDiscState - - - "" - +typedef ^ DiscreteStateType SiKi DummyDiscState - - - "Remove this variable if you have discrete states" - # # # Define constraint states here: @@ -270,25 +288,27 @@ typedef ^ OtherStateType IntKi # ..... 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 D_F_D {:}{:} - - "Distributed viscous drag loads" - -typedef ^ ^ ReKi D_F_I {:}{:} - - "Distributed inertial loads" - -typedef ^ ^ ReKi D_F_B {:}{:} - - "Distributed bounancy loads" - -#typedef ^ ^ ReKi D_F_DP {:}{:} - - "Distributed dynamic pressure loads" - -typedef ^ ^ ReKi D_F_AM {:}{:} - - "Distributed total added mass loads" - -typedef ^ ^ ReKi D_F_AM_M {:}{:} - - "Distributed member added mass loads" - -typedef ^ ^ ReKi D_F_AM_MG {:}{:} - - "Distributed marine growth added mass (weight) loads" - -typedef ^ ^ ReKi D_F_AM_F {:}{:} - - "Distributed added mass loads due to flooding/filled fluid" - -typedef ^ ^ ReKi D_FV {:}{:} - - "Fluid velocity at line element node" - -typedef ^ ^ ReKi D_FA {:}{:} - - "Fluid acceleration at line element node" - -typedef ^ ^ ReKi D_FDynP {:} - - "Fluid dynamic pressure at line element node" - -typedef ^ ^ ReKi L_F_B {:}{:} - - "" - -typedef ^ ^ ReKi L_F_D {:}{:} - - "Lumped viscous drag loads" - -typedef ^ ^ ReKi L_F_I {:}{:} - - "Lumped intertia loads" - -typedef ^ ^ ReKi L_F_DP {:}{:} - - "Lumped dynamic pressure loads" - -typedef ^ ^ ReKi L_F_AM {:}{:} - - "Lumped added mass loads" - -typedef ^ ^ ReKi L_FV {:}{:} - - "Fluid velocity at point element node" - -typedef ^ ^ ReKi L_FA {:}{:} - - "Fluid acceleration at point element node" - -typedef ^ ^ ReKi L_FDynP {:} - - "Fluid dynamic pressure at point element node" - +#typedef ^ MiscVarType ReKi F_D {:}{:} - - "Member-based (side-effects) Nodal viscous drag loads at time t" - +#typedef ^ ^ ReKi F_I {:}{:} - - "Member-based (side-effects) Nodal inertial loads at time t" - +#typedef ^ ^ ReKi F_A {:}{:} - - "Member-based (side-effects) Nodal added mass loads at time t" - +#typedef ^ ^ ReKi F_B {:}{:} - - "Member-based (side-effects) Nodal buoyancy loads" - +#typedef ^ ^ ReKi F_BF {:}{:} - - "Member-based (side-effects) Nodal flooded ballast weight/buoyancy loads" - +#typedef ^ ^ ReKi F_If {:}{:} - - "Member-based (side-effects) Nodal flooded ballast inertia loads" - +#typedef ^ ^ ReKi F_WMG {:}{:} - - "Member-based (side-effects) Nodal marine growth weight loads" - +#typedef ^ ^ ReKi F_IMG {:}{:} - - "Member-based (side-effects) Nodal marine growth inertia loads" - +#typedef ^ ^ ReKi F_DP {:}{:} - - "Lumped dynamic pressure loads at time t, which may not correspond to the WaveTime array of times" - +typedef ^ MiscVarType ReKi FV {:}{:} - - "Fluid velocity at line element node at time t, which may not correspond to the WaveTime array of times" - +typedef ^ ^ ReKi FA {:}{:} - - "Fluid acceleration at line element node at time t, which may not correspond to the WaveTime array of times" - +typedef ^ ^ ReKi FDynP {:} - - "Fluid dynamic pressure at line element node at time t, which may not correspond to the WaveTime array of times" - +typedef ^ ^ ReKi vrel {:}{:} - - "velocity of structural node relative to the water" m/s^2 +typedef ^ ^ INTEGER nodeInWater {:} - - "Logical flag indicating if the node at the given time step is in the water, and hence needs to have hydrodynamic forces calculated" - +typedef ^ ^ Morison_MemberLoads memberLoads {:} - - "Array (NMembers long) of member-based side-effects load contributions" - +typedef ^ ^ ReKi F_B_End {:}{:} - - "" - +typedef ^ ^ ReKi F_D_End {:}{:} - - "Lumped viscous drag loads at time t, which may not correspond to the WaveTime array of times" - +typedef ^ ^ ReKi F_I_End {:}{:} - - "Lumped intertia loads at time t, which may not correspond to the WaveTime array of times" - +typedef ^ ^ ReKi F_IMG_End {:}{:} - - "Joint marine growth intertia loads at time t, which may not correspond to the WaveTime array of times" - +typedef ^ ^ ReKi F_A_End {:}{:} - - "Lumped added mass loads at time t, which may not correspond to the WaveTime array of times" - +typedef ^ ^ ReKi F_BF_End {:}{:} - - "" - typedef ^ ^ INTEGER LastIndWave - - - "Last time index used in the wave kinematics arrays" - # ..... Parameters ................................................................................................................ @@ -296,37 +316,25 @@ typedef ^ ^ INTEGER # Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: # typedef ^ ParameterType DbKi DT - - - "Time step for continuous state integration & discrete state update" (sec) -typedef ^ ^ ReKi WtrDens - - - "" - +typedef ^ ^ ReKi Gravity - - - "Gravity (scalar, positive-valued)" m/s^2 +typedef ^ ^ ReKi WtrDens - - - "Water density" kg/m^3 +typedef ^ ^ ReKi WtrDpth - - - "Water depth (positive-valued)" m +typedef ^ ^ INTEGER NMembers - - - "number of members" - +typedef ^ ^ Morison_MemberType Members {:} - - "Array of Morison members used during simulation" - typedef ^ ^ INTEGER NNodes - - - "" - -typedef ^ ^ Morison_NodeType Nodes {:} - - "" - -typedef ^ ^ ReKi D_F_I {:}{:}{:} - - "" - -typedef ^ ^ ReKi D_F_DP {:}{:}{:} - - "" - -typedef ^ ^ ReKi D_dragConst {:} - - "" - -typedef ^ ^ ReKi L_An {:}{:} - - "" - -typedef ^ ^ ReKi L_F_B {:}{:} - - "" - -typedef ^ ^ ReKi L_F_I {:}{:}{:} - - "" - -typedef ^ ^ ReKi L_F_DP {:}{:}{:} - - "" - -typedef ^ ^ ReKi L_F_BF {:}{:} - - "" - -typedef ^ ^ ReKi L_AM_M {:}{:}{:} - - "" - -typedef ^ ^ ReKi L_dragConst {:} - - "" - -typedef ^ ^ INTEGER NDistribMarkers - - - "" - -#typedef ^ ^ Morison_NodeType DistribMarkers {:} - - "" - -typedef ^ ^ INTEGER distribToNodeIndx {:} - - "" - -typedef ^ ^ INTEGER NLumpedMarkers - - - "" - -typedef ^ ^ INTEGER lumpedToNodeIndx {:} - - "" - +typedef ^ ^ INTEGER NJoints - - - "Number of user-specified joints" - +typedef ^ ^ ReKi I_MG_End {:}{:}{:} - - "Inertial matrix associated with marine growth mass at joint" - +typedef ^ ^ ReKi An_End {:}{:} - - "directional area vector of each joint" m^2 +typedef ^ ^ ReKi DragConst_End {:} - - "" - +typedef ^ ^ ReKi F_WMG_End {:}{:} - - "Joint marine growth weight loads, constant for all t" N +typedef ^ ^ ReKi DP_Const_End {:}{:} - - "Constant part of Joint dynamic pressure term" N +typedef ^ ^ ReKi Mass_MG_End {:} - - "Joint marine growth mass" kg +typedef ^ ^ ReKi AM_End {:}{:}{:} - - "3x3 Joint added mass matrix, constant for all t" N typedef ^ ^ SiKi WaveVel {:}{:}{:} - - "" - typedef ^ ^ SiKi WaveAcc {:}{:}{:} - - "" - typedef ^ ^ SiKi WaveDynP {:}{:} - - "" - -typedef ^ ^ SiKi WaveTime {:} - - "" - -typedef ^ ^ INTEGER elementWaterState {:}{:} - - "State indicating if the element a node is attached to at the given time step is in the water [0], above the water [1], or in the seabed [2]" - -typedef ^ ^ INTEGER elementFillState {:} - - "State indicating if the element a node is attached to is in the filled fluid [0], above the fluid [1], or in the seabed [2]" - +typedef ^ ^ SiKi WaveTime {:} - - "Times for which the wave kinematics are pre-computed" s typedef ^ ^ INTEGER nodeInWater {:}{:} - - "Logical flag indicating if the node at the given time step is in the water, and hence needs to have hydrodynamic forces calculated" - -typedef ^ ^ ReKi D_F_B {:}{:} - - "Distributed buoyancy loads" - -typedef ^ ^ ReKi D_F_BF {:}{:} - - "Distributed filled buoyancy loads" - -typedef ^ ^ ReKi D_F_MG {:}{:} - - "Distributed marine growth loads" - -typedef ^ ^ ReKi D_AM_M {:}{:}{:} - - "Distributed member added mass matrix" - -typedef ^ ^ ReKi D_AM_MG {:} - - "Distributed marine growth added mass matrix (weight)" - -typedef ^ ^ ReKi D_AM_F {:} - - "Distributed added mass matrix due to flooding/filled fluid" - typedef ^ ^ INTEGER NStepWave - - - "" - typedef ^ ^ INTEGER NMOutputs - - - "" - typedef ^ ^ Morison_MOutput MOutLst {:} - - "" - @@ -345,12 +353,10 @@ typedef ^ ^ CHARACTER(C # ..... Inputs .................................................................................................................... # Define inputs that are contained on the mesh here: # -typedef ^ InputType MeshType DistribMesh - - - "Distributed Loads Meshed input data" - -typedef ^ ^ MeshType LumpedMesh - - - "Lumped Loads Meshed input data" - +typedef ^ InputType MeshType Mesh - - - "Kinematics of each node input mesh" - # # # ..... Outputs ................................................................................................................... # Define outputs that are contained on the mesh here: -typedef ^ OutputType MeshType DistribMesh - - - "Distributed Loads Meshed output data" - -typedef ^ ^ MeshType LumpedMesh - - - "Lumped Loads Meshed output data" - +typedef ^ OutputType MeshType Mesh - - - "Loads on each node output mesh" - typedef ^ ^ ReKi WriteOutput {:} - - "" - diff --git a/modules/hydrodyn/src/Morison_Output.f90 b/modules/hydrodyn/src/Morison_Output.f90 index f859a3a556..8c8a2b2caf 100644 --- a/modules/hydrodyn/src/Morison_Output.f90 +++ b/modules/hydrodyn/src/Morison_Output.f90 @@ -48,13 +48,12 @@ MODULE Morison_Output ! (2) Array y%AllOuts() must be dimensioned to the value of the largest output parameter ! Time: + INTEGER(IntKi), PARAMETER :: Time = 0 - INTEGER(IntKi), PARAMETER :: Time = 0 + ! Member-level Wave Kinematics : - ! Category: - - INTEGER(IntKi), PARAMETER :: M1N1Axi = 1 + INTEGER(IntKi), PARAMETER :: M1N1Axi = 1 INTEGER(IntKi), PARAMETER :: M1N2Axi = 2 INTEGER(IntKi), PARAMETER :: M1N3Axi = 3 INTEGER(IntKi), PARAMETER :: M1N4Axi = 4 @@ -1109,7 +1108,7 @@ MODULE Morison_Output INTEGER(IntKi), PARAMETER :: M9N9STAzi = 1053 - ! Category: + ! Morison Element Loads: INTEGER(IntKi), PARAMETER :: M1N1FDxi = 1054 INTEGER(IntKi), PARAMETER :: M1N2FDxi = 1055 @@ -2812,1293 +2811,1859 @@ MODULE Morison_Output INTEGER(IntKi), PARAMETER :: M9N7FMGzi = 2752 INTEGER(IntKi), PARAMETER :: M9N8FMGzi = 2753 INTEGER(IntKi), PARAMETER :: M9N9FMGzi = 2754 - INTEGER(IntKi), PARAMETER :: M1N1FAMxi = 2755 - INTEGER(IntKi), PARAMETER :: M1N2FAMxi = 2756 - INTEGER(IntKi), PARAMETER :: M1N3FAMxi = 2757 - INTEGER(IntKi), PARAMETER :: M1N4FAMxi = 2758 - INTEGER(IntKi), PARAMETER :: M1N5FAMxi = 2759 - INTEGER(IntKi), PARAMETER :: M1N6FAMxi = 2760 - INTEGER(IntKi), PARAMETER :: M1N7FAMxi = 2761 - INTEGER(IntKi), PARAMETER :: M1N8FAMxi = 2762 - INTEGER(IntKi), PARAMETER :: M1N9FAMxi = 2763 - INTEGER(IntKi), PARAMETER :: M2N1FAMxi = 2764 - INTEGER(IntKi), PARAMETER :: M2N2FAMxi = 2765 - INTEGER(IntKi), PARAMETER :: M2N3FAMxi = 2766 - INTEGER(IntKi), PARAMETER :: M2N4FAMxi = 2767 - INTEGER(IntKi), PARAMETER :: M2N5FAMxi = 2768 - INTEGER(IntKi), PARAMETER :: M2N6FAMxi = 2769 - INTEGER(IntKi), PARAMETER :: M2N7FAMxi = 2770 - INTEGER(IntKi), PARAMETER :: M2N8FAMxi = 2771 - INTEGER(IntKi), PARAMETER :: M2N9FAMxi = 2772 - INTEGER(IntKi), PARAMETER :: M3N1FAMxi = 2773 - INTEGER(IntKi), PARAMETER :: M3N2FAMxi = 2774 - INTEGER(IntKi), PARAMETER :: M3N3FAMxi = 2775 - INTEGER(IntKi), PARAMETER :: M3N4FAMxi = 2776 - INTEGER(IntKi), PARAMETER :: M3N5FAMxi = 2777 - INTEGER(IntKi), PARAMETER :: M3N6FAMxi = 2778 - INTEGER(IntKi), PARAMETER :: M3N7FAMxi = 2779 - INTEGER(IntKi), PARAMETER :: M3N8FAMxi = 2780 - INTEGER(IntKi), PARAMETER :: M3N9FAMxi = 2781 - INTEGER(IntKi), PARAMETER :: M4N1FAMxi = 2782 - INTEGER(IntKi), PARAMETER :: M4N2FAMxi = 2783 - INTEGER(IntKi), PARAMETER :: M4N3FAMxi = 2784 - INTEGER(IntKi), PARAMETER :: M4N4FAMxi = 2785 - INTEGER(IntKi), PARAMETER :: M4N5FAMxi = 2786 - INTEGER(IntKi), PARAMETER :: M4N6FAMxi = 2787 - INTEGER(IntKi), PARAMETER :: M4N7FAMxi = 2788 - INTEGER(IntKi), PARAMETER :: M4N8FAMxi = 2789 - INTEGER(IntKi), PARAMETER :: M4N9FAMxi = 2790 - INTEGER(IntKi), PARAMETER :: M5N1FAMxi = 2791 - INTEGER(IntKi), PARAMETER :: M5N2FAMxi = 2792 - INTEGER(IntKi), PARAMETER :: M5N3FAMxi = 2793 - INTEGER(IntKi), PARAMETER :: M5N4FAMxi = 2794 - INTEGER(IntKi), PARAMETER :: M5N5FAMxi = 2795 - INTEGER(IntKi), PARAMETER :: M5N6FAMxi = 2796 - INTEGER(IntKi), PARAMETER :: M5N7FAMxi = 2797 - INTEGER(IntKi), PARAMETER :: M5N8FAMxi = 2798 - INTEGER(IntKi), PARAMETER :: M5N9FAMxi = 2799 - INTEGER(IntKi), PARAMETER :: M6N1FAMxi = 2800 - INTEGER(IntKi), PARAMETER :: M6N2FAMxi = 2801 - INTEGER(IntKi), PARAMETER :: M6N3FAMxi = 2802 - INTEGER(IntKi), PARAMETER :: M6N4FAMxi = 2803 - INTEGER(IntKi), PARAMETER :: M6N5FAMxi = 2804 - INTEGER(IntKi), PARAMETER :: M6N6FAMxi = 2805 - INTEGER(IntKi), PARAMETER :: M6N7FAMxi = 2806 - INTEGER(IntKi), PARAMETER :: M6N8FAMxi = 2807 - INTEGER(IntKi), PARAMETER :: M6N9FAMxi = 2808 - INTEGER(IntKi), PARAMETER :: M7N1FAMxi = 2809 - INTEGER(IntKi), PARAMETER :: M7N2FAMxi = 2810 - INTEGER(IntKi), PARAMETER :: M7N3FAMxi = 2811 - INTEGER(IntKi), PARAMETER :: M7N4FAMxi = 2812 - INTEGER(IntKi), PARAMETER :: M7N5FAMxi = 2813 - INTEGER(IntKi), PARAMETER :: M7N6FAMxi = 2814 - INTEGER(IntKi), PARAMETER :: M7N7FAMxi = 2815 - INTEGER(IntKi), PARAMETER :: M7N8FAMxi = 2816 - INTEGER(IntKi), PARAMETER :: M7N9FAMxi = 2817 - INTEGER(IntKi), PARAMETER :: M8N1FAMxi = 2818 - INTEGER(IntKi), PARAMETER :: M8N2FAMxi = 2819 - INTEGER(IntKi), PARAMETER :: M8N3FAMxi = 2820 - INTEGER(IntKi), PARAMETER :: M8N4FAMxi = 2821 - INTEGER(IntKi), PARAMETER :: M8N5FAMxi = 2822 - INTEGER(IntKi), PARAMETER :: M8N6FAMxi = 2823 - INTEGER(IntKi), PARAMETER :: M8N7FAMxi = 2824 - INTEGER(IntKi), PARAMETER :: M8N8FAMxi = 2825 - INTEGER(IntKi), PARAMETER :: M8N9FAMxi = 2826 - INTEGER(IntKi), PARAMETER :: M9N1FAMxi = 2827 - INTEGER(IntKi), PARAMETER :: M9N2FAMxi = 2828 - INTEGER(IntKi), PARAMETER :: M9N3FAMxi = 2829 - INTEGER(IntKi), PARAMETER :: M9N4FAMxi = 2830 - INTEGER(IntKi), PARAMETER :: M9N5FAMxi = 2831 - INTEGER(IntKi), PARAMETER :: M9N6FAMxi = 2832 - INTEGER(IntKi), PARAMETER :: M9N7FAMxi = 2833 - INTEGER(IntKi), PARAMETER :: M9N8FAMxi = 2834 - INTEGER(IntKi), PARAMETER :: M9N9FAMxi = 2835 - INTEGER(IntKi), PARAMETER :: M1N1FAMyi = 2836 - INTEGER(IntKi), PARAMETER :: M1N2FAMyi = 2837 - INTEGER(IntKi), PARAMETER :: M1N3FAMyi = 2838 - INTEGER(IntKi), PARAMETER :: M1N4FAMyi = 2839 - INTEGER(IntKi), PARAMETER :: M1N5FAMyi = 2840 - INTEGER(IntKi), PARAMETER :: M1N6FAMyi = 2841 - INTEGER(IntKi), PARAMETER :: M1N7FAMyi = 2842 - INTEGER(IntKi), PARAMETER :: M1N8FAMyi = 2843 - INTEGER(IntKi), PARAMETER :: M1N9FAMyi = 2844 - INTEGER(IntKi), PARAMETER :: M2N1FAMyi = 2845 - INTEGER(IntKi), PARAMETER :: M2N2FAMyi = 2846 - INTEGER(IntKi), PARAMETER :: M2N3FAMyi = 2847 - INTEGER(IntKi), PARAMETER :: M2N4FAMyi = 2848 - INTEGER(IntKi), PARAMETER :: M2N5FAMyi = 2849 - INTEGER(IntKi), PARAMETER :: M2N6FAMyi = 2850 - INTEGER(IntKi), PARAMETER :: M2N7FAMyi = 2851 - INTEGER(IntKi), PARAMETER :: M2N8FAMyi = 2852 - INTEGER(IntKi), PARAMETER :: M2N9FAMyi = 2853 - INTEGER(IntKi), PARAMETER :: M3N1FAMyi = 2854 - INTEGER(IntKi), PARAMETER :: M3N2FAMyi = 2855 - INTEGER(IntKi), PARAMETER :: M3N3FAMyi = 2856 - INTEGER(IntKi), PARAMETER :: M3N4FAMyi = 2857 - INTEGER(IntKi), PARAMETER :: M3N5FAMyi = 2858 - INTEGER(IntKi), PARAMETER :: M3N6FAMyi = 2859 - INTEGER(IntKi), PARAMETER :: M3N7FAMyi = 2860 - INTEGER(IntKi), PARAMETER :: M3N8FAMyi = 2861 - INTEGER(IntKi), PARAMETER :: M3N9FAMyi = 2862 - INTEGER(IntKi), PARAMETER :: M4N1FAMyi = 2863 - INTEGER(IntKi), PARAMETER :: M4N2FAMyi = 2864 - INTEGER(IntKi), PARAMETER :: M4N3FAMyi = 2865 - INTEGER(IntKi), PARAMETER :: M4N4FAMyi = 2866 - INTEGER(IntKi), PARAMETER :: M4N5FAMyi = 2867 - INTEGER(IntKi), PARAMETER :: M4N6FAMyi = 2868 - INTEGER(IntKi), PARAMETER :: M4N7FAMyi = 2869 - INTEGER(IntKi), PARAMETER :: M4N8FAMyi = 2870 - INTEGER(IntKi), PARAMETER :: M4N9FAMyi = 2871 - INTEGER(IntKi), PARAMETER :: M5N1FAMyi = 2872 - INTEGER(IntKi), PARAMETER :: M5N2FAMyi = 2873 - INTEGER(IntKi), PARAMETER :: M5N3FAMyi = 2874 - INTEGER(IntKi), PARAMETER :: M5N4FAMyi = 2875 - INTEGER(IntKi), PARAMETER :: M5N5FAMyi = 2876 - INTEGER(IntKi), PARAMETER :: M5N6FAMyi = 2877 - INTEGER(IntKi), PARAMETER :: M5N7FAMyi = 2878 - INTEGER(IntKi), PARAMETER :: M5N8FAMyi = 2879 - INTEGER(IntKi), PARAMETER :: M5N9FAMyi = 2880 - INTEGER(IntKi), PARAMETER :: M6N1FAMyi = 2881 - INTEGER(IntKi), PARAMETER :: M6N2FAMyi = 2882 - INTEGER(IntKi), PARAMETER :: M6N3FAMyi = 2883 - INTEGER(IntKi), PARAMETER :: M6N4FAMyi = 2884 - INTEGER(IntKi), PARAMETER :: M6N5FAMyi = 2885 - INTEGER(IntKi), PARAMETER :: M6N6FAMyi = 2886 - INTEGER(IntKi), PARAMETER :: M6N7FAMyi = 2887 - INTEGER(IntKi), PARAMETER :: M6N8FAMyi = 2888 - INTEGER(IntKi), PARAMETER :: M6N9FAMyi = 2889 - INTEGER(IntKi), PARAMETER :: M7N1FAMyi = 2890 - INTEGER(IntKi), PARAMETER :: M7N2FAMyi = 2891 - INTEGER(IntKi), PARAMETER :: M7N3FAMyi = 2892 - INTEGER(IntKi), PARAMETER :: M7N4FAMyi = 2893 - INTEGER(IntKi), PARAMETER :: M7N5FAMyi = 2894 - INTEGER(IntKi), PARAMETER :: M7N6FAMyi = 2895 - INTEGER(IntKi), PARAMETER :: M7N7FAMyi = 2896 - INTEGER(IntKi), PARAMETER :: M7N8FAMyi = 2897 - INTEGER(IntKi), PARAMETER :: M7N9FAMyi = 2898 - INTEGER(IntKi), PARAMETER :: M8N1FAMyi = 2899 - INTEGER(IntKi), PARAMETER :: M8N2FAMyi = 2900 - INTEGER(IntKi), PARAMETER :: M8N3FAMyi = 2901 - INTEGER(IntKi), PARAMETER :: M8N4FAMyi = 2902 - INTEGER(IntKi), PARAMETER :: M8N5FAMyi = 2903 - INTEGER(IntKi), PARAMETER :: M8N6FAMyi = 2904 - INTEGER(IntKi), PARAMETER :: M8N7FAMyi = 2905 - INTEGER(IntKi), PARAMETER :: M8N8FAMyi = 2906 - INTEGER(IntKi), PARAMETER :: M8N9FAMyi = 2907 - INTEGER(IntKi), PARAMETER :: M9N1FAMyi = 2908 - INTEGER(IntKi), PARAMETER :: M9N2FAMyi = 2909 - INTEGER(IntKi), PARAMETER :: M9N3FAMyi = 2910 - INTEGER(IntKi), PARAMETER :: M9N4FAMyi = 2911 - INTEGER(IntKi), PARAMETER :: M9N5FAMyi = 2912 - INTEGER(IntKi), PARAMETER :: M9N6FAMyi = 2913 - INTEGER(IntKi), PARAMETER :: M9N7FAMyi = 2914 - INTEGER(IntKi), PARAMETER :: M9N8FAMyi = 2915 - INTEGER(IntKi), PARAMETER :: M9N9FAMyi = 2916 - INTEGER(IntKi), PARAMETER :: M1N1FAMzi = 2917 - INTEGER(IntKi), PARAMETER :: M1N2FAMzi = 2918 - INTEGER(IntKi), PARAMETER :: M1N3FAMzi = 2919 - INTEGER(IntKi), PARAMETER :: M1N4FAMzi = 2920 - INTEGER(IntKi), PARAMETER :: M1N5FAMzi = 2921 - INTEGER(IntKi), PARAMETER :: M1N6FAMzi = 2922 - INTEGER(IntKi), PARAMETER :: M1N7FAMzi = 2923 - INTEGER(IntKi), PARAMETER :: M1N8FAMzi = 2924 - INTEGER(IntKi), PARAMETER :: M1N9FAMzi = 2925 - INTEGER(IntKi), PARAMETER :: M2N1FAMzi = 2926 - INTEGER(IntKi), PARAMETER :: M2N2FAMzi = 2927 - INTEGER(IntKi), PARAMETER :: M2N3FAMzi = 2928 - INTEGER(IntKi), PARAMETER :: M2N4FAMzi = 2929 - INTEGER(IntKi), PARAMETER :: M2N5FAMzi = 2930 - INTEGER(IntKi), PARAMETER :: M2N6FAMzi = 2931 - INTEGER(IntKi), PARAMETER :: M2N7FAMzi = 2932 - INTEGER(IntKi), PARAMETER :: M2N8FAMzi = 2933 - INTEGER(IntKi), PARAMETER :: M2N9FAMzi = 2934 - INTEGER(IntKi), PARAMETER :: M3N1FAMzi = 2935 - INTEGER(IntKi), PARAMETER :: M3N2FAMzi = 2936 - INTEGER(IntKi), PARAMETER :: M3N3FAMzi = 2937 - INTEGER(IntKi), PARAMETER :: M3N4FAMzi = 2938 - INTEGER(IntKi), PARAMETER :: M3N5FAMzi = 2939 - INTEGER(IntKi), PARAMETER :: M3N6FAMzi = 2940 - INTEGER(IntKi), PARAMETER :: M3N7FAMzi = 2941 - INTEGER(IntKi), PARAMETER :: M3N8FAMzi = 2942 - INTEGER(IntKi), PARAMETER :: M3N9FAMzi = 2943 - INTEGER(IntKi), PARAMETER :: M4N1FAMzi = 2944 - INTEGER(IntKi), PARAMETER :: M4N2FAMzi = 2945 - INTEGER(IntKi), PARAMETER :: M4N3FAMzi = 2946 - INTEGER(IntKi), PARAMETER :: M4N4FAMzi = 2947 - INTEGER(IntKi), PARAMETER :: M4N5FAMzi = 2948 - INTEGER(IntKi), PARAMETER :: M4N6FAMzi = 2949 - INTEGER(IntKi), PARAMETER :: M4N7FAMzi = 2950 - INTEGER(IntKi), PARAMETER :: M4N8FAMzi = 2951 - INTEGER(IntKi), PARAMETER :: M4N9FAMzi = 2952 - INTEGER(IntKi), PARAMETER :: M5N1FAMzi = 2953 - INTEGER(IntKi), PARAMETER :: M5N2FAMzi = 2954 - INTEGER(IntKi), PARAMETER :: M5N3FAMzi = 2955 - INTEGER(IntKi), PARAMETER :: M5N4FAMzi = 2956 - INTEGER(IntKi), PARAMETER :: M5N5FAMzi = 2957 - INTEGER(IntKi), PARAMETER :: M5N6FAMzi = 2958 - INTEGER(IntKi), PARAMETER :: M5N7FAMzi = 2959 - INTEGER(IntKi), PARAMETER :: M5N8FAMzi = 2960 - INTEGER(IntKi), PARAMETER :: M5N9FAMzi = 2961 - INTEGER(IntKi), PARAMETER :: M6N1FAMzi = 2962 - INTEGER(IntKi), PARAMETER :: M6N2FAMzi = 2963 - INTEGER(IntKi), PARAMETER :: M6N3FAMzi = 2964 - INTEGER(IntKi), PARAMETER :: M6N4FAMzi = 2965 - INTEGER(IntKi), PARAMETER :: M6N5FAMzi = 2966 - INTEGER(IntKi), PARAMETER :: M6N6FAMzi = 2967 - INTEGER(IntKi), PARAMETER :: M6N7FAMzi = 2968 - INTEGER(IntKi), PARAMETER :: M6N8FAMzi = 2969 - INTEGER(IntKi), PARAMETER :: M6N9FAMzi = 2970 - INTEGER(IntKi), PARAMETER :: M7N1FAMzi = 2971 - INTEGER(IntKi), PARAMETER :: M7N2FAMzi = 2972 - INTEGER(IntKi), PARAMETER :: M7N3FAMzi = 2973 - INTEGER(IntKi), PARAMETER :: M7N4FAMzi = 2974 - INTEGER(IntKi), PARAMETER :: M7N5FAMzi = 2975 - INTEGER(IntKi), PARAMETER :: M7N6FAMzi = 2976 - INTEGER(IntKi), PARAMETER :: M7N7FAMzi = 2977 - INTEGER(IntKi), PARAMETER :: M7N8FAMzi = 2978 - INTEGER(IntKi), PARAMETER :: M7N9FAMzi = 2979 - INTEGER(IntKi), PARAMETER :: M8N1FAMzi = 2980 - INTEGER(IntKi), PARAMETER :: M8N2FAMzi = 2981 - INTEGER(IntKi), PARAMETER :: M8N3FAMzi = 2982 - INTEGER(IntKi), PARAMETER :: M8N4FAMzi = 2983 - INTEGER(IntKi), PARAMETER :: M8N5FAMzi = 2984 - INTEGER(IntKi), PARAMETER :: M8N6FAMzi = 2985 - INTEGER(IntKi), PARAMETER :: M8N7FAMzi = 2986 - INTEGER(IntKi), PARAMETER :: M8N8FAMzi = 2987 - INTEGER(IntKi), PARAMETER :: M8N9FAMzi = 2988 - INTEGER(IntKi), PARAMETER :: M9N1FAMzi = 2989 - INTEGER(IntKi), PARAMETER :: M9N2FAMzi = 2990 - INTEGER(IntKi), PARAMETER :: M9N3FAMzi = 2991 - INTEGER(IntKi), PARAMETER :: M9N4FAMzi = 2992 - INTEGER(IntKi), PARAMETER :: M9N5FAMzi = 2993 - INTEGER(IntKi), PARAMETER :: M9N6FAMzi = 2994 - INTEGER(IntKi), PARAMETER :: M9N7FAMzi = 2995 - INTEGER(IntKi), PARAMETER :: M9N8FAMzi = 2996 - INTEGER(IntKi), PARAMETER :: M9N9FAMzi = 2997 - INTEGER(IntKi), PARAMETER :: M1N1FAGxi = 2998 - INTEGER(IntKi), PARAMETER :: M1N2FAGxi = 2999 - INTEGER(IntKi), PARAMETER :: M1N3FAGxi = 3000 - INTEGER(IntKi), PARAMETER :: M1N4FAGxi = 3001 - INTEGER(IntKi), PARAMETER :: M1N5FAGxi = 3002 - INTEGER(IntKi), PARAMETER :: M1N6FAGxi = 3003 - INTEGER(IntKi), PARAMETER :: M1N7FAGxi = 3004 - INTEGER(IntKi), PARAMETER :: M1N8FAGxi = 3005 - INTEGER(IntKi), PARAMETER :: M1N9FAGxi = 3006 - INTEGER(IntKi), PARAMETER :: M2N1FAGxi = 3007 - INTEGER(IntKi), PARAMETER :: M2N2FAGxi = 3008 - INTEGER(IntKi), PARAMETER :: M2N3FAGxi = 3009 - INTEGER(IntKi), PARAMETER :: M2N4FAGxi = 3010 - INTEGER(IntKi), PARAMETER :: M2N5FAGxi = 3011 - INTEGER(IntKi), PARAMETER :: M2N6FAGxi = 3012 - INTEGER(IntKi), PARAMETER :: M2N7FAGxi = 3013 - INTEGER(IntKi), PARAMETER :: M2N8FAGxi = 3014 - INTEGER(IntKi), PARAMETER :: M2N9FAGxi = 3015 - INTEGER(IntKi), PARAMETER :: M3N1FAGxi = 3016 - INTEGER(IntKi), PARAMETER :: M3N2FAGxi = 3017 - INTEGER(IntKi), PARAMETER :: M3N3FAGxi = 3018 - INTEGER(IntKi), PARAMETER :: M3N4FAGxi = 3019 - INTEGER(IntKi), PARAMETER :: M3N5FAGxi = 3020 - INTEGER(IntKi), PARAMETER :: M3N6FAGxi = 3021 - INTEGER(IntKi), PARAMETER :: M3N7FAGxi = 3022 - INTEGER(IntKi), PARAMETER :: M3N8FAGxi = 3023 - INTEGER(IntKi), PARAMETER :: M3N9FAGxi = 3024 - INTEGER(IntKi), PARAMETER :: M4N1FAGxi = 3025 - INTEGER(IntKi), PARAMETER :: M4N2FAGxi = 3026 - INTEGER(IntKi), PARAMETER :: M4N3FAGxi = 3027 - INTEGER(IntKi), PARAMETER :: M4N4FAGxi = 3028 - INTEGER(IntKi), PARAMETER :: M4N5FAGxi = 3029 - INTEGER(IntKi), PARAMETER :: M4N6FAGxi = 3030 - INTEGER(IntKi), PARAMETER :: M4N7FAGxi = 3031 - INTEGER(IntKi), PARAMETER :: M4N8FAGxi = 3032 - INTEGER(IntKi), PARAMETER :: M4N9FAGxi = 3033 - INTEGER(IntKi), PARAMETER :: M5N1FAGxi = 3034 - INTEGER(IntKi), PARAMETER :: M5N2FAGxi = 3035 - INTEGER(IntKi), PARAMETER :: M5N3FAGxi = 3036 - INTEGER(IntKi), PARAMETER :: M5N4FAGxi = 3037 - INTEGER(IntKi), PARAMETER :: M5N5FAGxi = 3038 - INTEGER(IntKi), PARAMETER :: M5N6FAGxi = 3039 - INTEGER(IntKi), PARAMETER :: M5N7FAGxi = 3040 - INTEGER(IntKi), PARAMETER :: M5N8FAGxi = 3041 - INTEGER(IntKi), PARAMETER :: M5N9FAGxi = 3042 - INTEGER(IntKi), PARAMETER :: M6N1FAGxi = 3043 - INTEGER(IntKi), PARAMETER :: M6N2FAGxi = 3044 - INTEGER(IntKi), PARAMETER :: M6N3FAGxi = 3045 - INTEGER(IntKi), PARAMETER :: M6N4FAGxi = 3046 - INTEGER(IntKi), PARAMETER :: M6N5FAGxi = 3047 - INTEGER(IntKi), PARAMETER :: M6N6FAGxi = 3048 - INTEGER(IntKi), PARAMETER :: M6N7FAGxi = 3049 - INTEGER(IntKi), PARAMETER :: M6N8FAGxi = 3050 - INTEGER(IntKi), PARAMETER :: M6N9FAGxi = 3051 - INTEGER(IntKi), PARAMETER :: M7N1FAGxi = 3052 - INTEGER(IntKi), PARAMETER :: M7N2FAGxi = 3053 - INTEGER(IntKi), PARAMETER :: M7N3FAGxi = 3054 - INTEGER(IntKi), PARAMETER :: M7N4FAGxi = 3055 - INTEGER(IntKi), PARAMETER :: M7N5FAGxi = 3056 - INTEGER(IntKi), PARAMETER :: M7N6FAGxi = 3057 - INTEGER(IntKi), PARAMETER :: M7N7FAGxi = 3058 - INTEGER(IntKi), PARAMETER :: M7N8FAGxi = 3059 - INTEGER(IntKi), PARAMETER :: M7N9FAGxi = 3060 - INTEGER(IntKi), PARAMETER :: M8N1FAGxi = 3061 - INTEGER(IntKi), PARAMETER :: M8N2FAGxi = 3062 - INTEGER(IntKi), PARAMETER :: M8N3FAGxi = 3063 - INTEGER(IntKi), PARAMETER :: M8N4FAGxi = 3064 - INTEGER(IntKi), PARAMETER :: M8N5FAGxi = 3065 - INTEGER(IntKi), PARAMETER :: M8N6FAGxi = 3066 - INTEGER(IntKi), PARAMETER :: M8N7FAGxi = 3067 - INTEGER(IntKi), PARAMETER :: M8N8FAGxi = 3068 - INTEGER(IntKi), PARAMETER :: M8N9FAGxi = 3069 - INTEGER(IntKi), PARAMETER :: M9N1FAGxi = 3070 - INTEGER(IntKi), PARAMETER :: M9N2FAGxi = 3071 - INTEGER(IntKi), PARAMETER :: M9N3FAGxi = 3072 - INTEGER(IntKi), PARAMETER :: M9N4FAGxi = 3073 - INTEGER(IntKi), PARAMETER :: M9N5FAGxi = 3074 - INTEGER(IntKi), PARAMETER :: M9N6FAGxi = 3075 - INTEGER(IntKi), PARAMETER :: M9N7FAGxi = 3076 - INTEGER(IntKi), PARAMETER :: M9N8FAGxi = 3077 - INTEGER(IntKi), PARAMETER :: M9N9FAGxi = 3078 - INTEGER(IntKi), PARAMETER :: M1N1FAGyi = 3079 - INTEGER(IntKi), PARAMETER :: M1N2FAGyi = 3080 - INTEGER(IntKi), PARAMETER :: M1N3FAGyi = 3081 - INTEGER(IntKi), PARAMETER :: M1N4FAGyi = 3082 - INTEGER(IntKi), PARAMETER :: M1N5FAGyi = 3083 - INTEGER(IntKi), PARAMETER :: M1N6FAGyi = 3084 - INTEGER(IntKi), PARAMETER :: M1N7FAGyi = 3085 - INTEGER(IntKi), PARAMETER :: M1N8FAGyi = 3086 - INTEGER(IntKi), PARAMETER :: M1N9FAGyi = 3087 - INTEGER(IntKi), PARAMETER :: M2N1FAGyi = 3088 - INTEGER(IntKi), PARAMETER :: M2N2FAGyi = 3089 - INTEGER(IntKi), PARAMETER :: M2N3FAGyi = 3090 - INTEGER(IntKi), PARAMETER :: M2N4FAGyi = 3091 - INTEGER(IntKi), PARAMETER :: M2N5FAGyi = 3092 - INTEGER(IntKi), PARAMETER :: M2N6FAGyi = 3093 - INTEGER(IntKi), PARAMETER :: M2N7FAGyi = 3094 - INTEGER(IntKi), PARAMETER :: M2N8FAGyi = 3095 - INTEGER(IntKi), PARAMETER :: M2N9FAGyi = 3096 - INTEGER(IntKi), PARAMETER :: M3N1FAGyi = 3097 - INTEGER(IntKi), PARAMETER :: M3N2FAGyi = 3098 - INTEGER(IntKi), PARAMETER :: M3N3FAGyi = 3099 - INTEGER(IntKi), PARAMETER :: M3N4FAGyi = 3100 - INTEGER(IntKi), PARAMETER :: M3N5FAGyi = 3101 - INTEGER(IntKi), PARAMETER :: M3N6FAGyi = 3102 - INTEGER(IntKi), PARAMETER :: M3N7FAGyi = 3103 - INTEGER(IntKi), PARAMETER :: M3N8FAGyi = 3104 - INTEGER(IntKi), PARAMETER :: M3N9FAGyi = 3105 - INTEGER(IntKi), PARAMETER :: M4N1FAGyi = 3106 - INTEGER(IntKi), PARAMETER :: M4N2FAGyi = 3107 - INTEGER(IntKi), PARAMETER :: M4N3FAGyi = 3108 - INTEGER(IntKi), PARAMETER :: M4N4FAGyi = 3109 - INTEGER(IntKi), PARAMETER :: M4N5FAGyi = 3110 - INTEGER(IntKi), PARAMETER :: M4N6FAGyi = 3111 - INTEGER(IntKi), PARAMETER :: M4N7FAGyi = 3112 - INTEGER(IntKi), PARAMETER :: M4N8FAGyi = 3113 - INTEGER(IntKi), PARAMETER :: M4N9FAGyi = 3114 - INTEGER(IntKi), PARAMETER :: M5N1FAGyi = 3115 - INTEGER(IntKi), PARAMETER :: M5N2FAGyi = 3116 - INTEGER(IntKi), PARAMETER :: M5N3FAGyi = 3117 - INTEGER(IntKi), PARAMETER :: M5N4FAGyi = 3118 - INTEGER(IntKi), PARAMETER :: M5N5FAGyi = 3119 - INTEGER(IntKi), PARAMETER :: M5N6FAGyi = 3120 - INTEGER(IntKi), PARAMETER :: M5N7FAGyi = 3121 - INTEGER(IntKi), PARAMETER :: M5N8FAGyi = 3122 - INTEGER(IntKi), PARAMETER :: M5N9FAGyi = 3123 - INTEGER(IntKi), PARAMETER :: M6N1FAGyi = 3124 - INTEGER(IntKi), PARAMETER :: M6N2FAGyi = 3125 - INTEGER(IntKi), PARAMETER :: M6N3FAGyi = 3126 - INTEGER(IntKi), PARAMETER :: M6N4FAGyi = 3127 - INTEGER(IntKi), PARAMETER :: M6N5FAGyi = 3128 - INTEGER(IntKi), PARAMETER :: M6N6FAGyi = 3129 - INTEGER(IntKi), PARAMETER :: M6N7FAGyi = 3130 - INTEGER(IntKi), PARAMETER :: M6N8FAGyi = 3131 - INTEGER(IntKi), PARAMETER :: M6N9FAGyi = 3132 - INTEGER(IntKi), PARAMETER :: M7N1FAGyi = 3133 - INTEGER(IntKi), PARAMETER :: M7N2FAGyi = 3134 - INTEGER(IntKi), PARAMETER :: M7N3FAGyi = 3135 - INTEGER(IntKi), PARAMETER :: M7N4FAGyi = 3136 - INTEGER(IntKi), PARAMETER :: M7N5FAGyi = 3137 - INTEGER(IntKi), PARAMETER :: M7N6FAGyi = 3138 - INTEGER(IntKi), PARAMETER :: M7N7FAGyi = 3139 - INTEGER(IntKi), PARAMETER :: M7N8FAGyi = 3140 - INTEGER(IntKi), PARAMETER :: M7N9FAGyi = 3141 - INTEGER(IntKi), PARAMETER :: M8N1FAGyi = 3142 - INTEGER(IntKi), PARAMETER :: M8N2FAGyi = 3143 - INTEGER(IntKi), PARAMETER :: M8N3FAGyi = 3144 - INTEGER(IntKi), PARAMETER :: M8N4FAGyi = 3145 - INTEGER(IntKi), PARAMETER :: M8N5FAGyi = 3146 - INTEGER(IntKi), PARAMETER :: M8N6FAGyi = 3147 - INTEGER(IntKi), PARAMETER :: M8N7FAGyi = 3148 - INTEGER(IntKi), PARAMETER :: M8N8FAGyi = 3149 - INTEGER(IntKi), PARAMETER :: M8N9FAGyi = 3150 - INTEGER(IntKi), PARAMETER :: M9N1FAGyi = 3151 - INTEGER(IntKi), PARAMETER :: M9N2FAGyi = 3152 - INTEGER(IntKi), PARAMETER :: M9N3FAGyi = 3153 - INTEGER(IntKi), PARAMETER :: M9N4FAGyi = 3154 - INTEGER(IntKi), PARAMETER :: M9N5FAGyi = 3155 - INTEGER(IntKi), PARAMETER :: M9N6FAGyi = 3156 - INTEGER(IntKi), PARAMETER :: M9N7FAGyi = 3157 - INTEGER(IntKi), PARAMETER :: M9N8FAGyi = 3158 - INTEGER(IntKi), PARAMETER :: M9N9FAGyi = 3159 - INTEGER(IntKi), PARAMETER :: M1N1FAGzi = 3160 - INTEGER(IntKi), PARAMETER :: M1N2FAGzi = 3161 - INTEGER(IntKi), PARAMETER :: M1N3FAGzi = 3162 - INTEGER(IntKi), PARAMETER :: M1N4FAGzi = 3163 - INTEGER(IntKi), PARAMETER :: M1N5FAGzi = 3164 - INTEGER(IntKi), PARAMETER :: M1N6FAGzi = 3165 - INTEGER(IntKi), PARAMETER :: M1N7FAGzi = 3166 - INTEGER(IntKi), PARAMETER :: M1N8FAGzi = 3167 - INTEGER(IntKi), PARAMETER :: M1N9FAGzi = 3168 - INTEGER(IntKi), PARAMETER :: M2N1FAGzi = 3169 - INTEGER(IntKi), PARAMETER :: M2N2FAGzi = 3170 - INTEGER(IntKi), PARAMETER :: M2N3FAGzi = 3171 - INTEGER(IntKi), PARAMETER :: M2N4FAGzi = 3172 - INTEGER(IntKi), PARAMETER :: M2N5FAGzi = 3173 - INTEGER(IntKi), PARAMETER :: M2N6FAGzi = 3174 - INTEGER(IntKi), PARAMETER :: M2N7FAGzi = 3175 - INTEGER(IntKi), PARAMETER :: M2N8FAGzi = 3176 - INTEGER(IntKi), PARAMETER :: M2N9FAGzi = 3177 - INTEGER(IntKi), PARAMETER :: M3N1FAGzi = 3178 - INTEGER(IntKi), PARAMETER :: M3N2FAGzi = 3179 - INTEGER(IntKi), PARAMETER :: M3N3FAGzi = 3180 - INTEGER(IntKi), PARAMETER :: M3N4FAGzi = 3181 - INTEGER(IntKi), PARAMETER :: M3N5FAGzi = 3182 - INTEGER(IntKi), PARAMETER :: M3N6FAGzi = 3183 - INTEGER(IntKi), PARAMETER :: M3N7FAGzi = 3184 - INTEGER(IntKi), PARAMETER :: M3N8FAGzi = 3185 - INTEGER(IntKi), PARAMETER :: M3N9FAGzi = 3186 - INTEGER(IntKi), PARAMETER :: M4N1FAGzi = 3187 - INTEGER(IntKi), PARAMETER :: M4N2FAGzi = 3188 - INTEGER(IntKi), PARAMETER :: M4N3FAGzi = 3189 - INTEGER(IntKi), PARAMETER :: M4N4FAGzi = 3190 - INTEGER(IntKi), PARAMETER :: M4N5FAGzi = 3191 - INTEGER(IntKi), PARAMETER :: M4N6FAGzi = 3192 - INTEGER(IntKi), PARAMETER :: M4N7FAGzi = 3193 - INTEGER(IntKi), PARAMETER :: M4N8FAGzi = 3194 - INTEGER(IntKi), PARAMETER :: M4N9FAGzi = 3195 - INTEGER(IntKi), PARAMETER :: M5N1FAGzi = 3196 - INTEGER(IntKi), PARAMETER :: M5N2FAGzi = 3197 - INTEGER(IntKi), PARAMETER :: M5N3FAGzi = 3198 - INTEGER(IntKi), PARAMETER :: M5N4FAGzi = 3199 - INTEGER(IntKi), PARAMETER :: M5N5FAGzi = 3200 - INTEGER(IntKi), PARAMETER :: M5N6FAGzi = 3201 - INTEGER(IntKi), PARAMETER :: M5N7FAGzi = 3202 - INTEGER(IntKi), PARAMETER :: M5N8FAGzi = 3203 - INTEGER(IntKi), PARAMETER :: M5N9FAGzi = 3204 - INTEGER(IntKi), PARAMETER :: M6N1FAGzi = 3205 - INTEGER(IntKi), PARAMETER :: M6N2FAGzi = 3206 - INTEGER(IntKi), PARAMETER :: M6N3FAGzi = 3207 - INTEGER(IntKi), PARAMETER :: M6N4FAGzi = 3208 - INTEGER(IntKi), PARAMETER :: M6N5FAGzi = 3209 - INTEGER(IntKi), PARAMETER :: M6N6FAGzi = 3210 - INTEGER(IntKi), PARAMETER :: M6N7FAGzi = 3211 - INTEGER(IntKi), PARAMETER :: M6N8FAGzi = 3212 - INTEGER(IntKi), PARAMETER :: M6N9FAGzi = 3213 - INTEGER(IntKi), PARAMETER :: M7N1FAGzi = 3214 - INTEGER(IntKi), PARAMETER :: M7N2FAGzi = 3215 - INTEGER(IntKi), PARAMETER :: M7N3FAGzi = 3216 - INTEGER(IntKi), PARAMETER :: M7N4FAGzi = 3217 - INTEGER(IntKi), PARAMETER :: M7N5FAGzi = 3218 - INTEGER(IntKi), PARAMETER :: M7N6FAGzi = 3219 - INTEGER(IntKi), PARAMETER :: M7N7FAGzi = 3220 - INTEGER(IntKi), PARAMETER :: M7N8FAGzi = 3221 - INTEGER(IntKi), PARAMETER :: M7N9FAGzi = 3222 - INTEGER(IntKi), PARAMETER :: M8N1FAGzi = 3223 - INTEGER(IntKi), PARAMETER :: M8N2FAGzi = 3224 - INTEGER(IntKi), PARAMETER :: M8N3FAGzi = 3225 - INTEGER(IntKi), PARAMETER :: M8N4FAGzi = 3226 - INTEGER(IntKi), PARAMETER :: M8N5FAGzi = 3227 - INTEGER(IntKi), PARAMETER :: M8N6FAGzi = 3228 - INTEGER(IntKi), PARAMETER :: M8N7FAGzi = 3229 - INTEGER(IntKi), PARAMETER :: M8N8FAGzi = 3230 - INTEGER(IntKi), PARAMETER :: M8N9FAGzi = 3231 - INTEGER(IntKi), PARAMETER :: M9N1FAGzi = 3232 - INTEGER(IntKi), PARAMETER :: M9N2FAGzi = 3233 - INTEGER(IntKi), PARAMETER :: M9N3FAGzi = 3234 - INTEGER(IntKi), PARAMETER :: M9N4FAGzi = 3235 - INTEGER(IntKi), PARAMETER :: M9N5FAGzi = 3236 - INTEGER(IntKi), PARAMETER :: M9N6FAGzi = 3237 - INTEGER(IntKi), PARAMETER :: M9N7FAGzi = 3238 - INTEGER(IntKi), PARAMETER :: M9N8FAGzi = 3239 - INTEGER(IntKi), PARAMETER :: M9N9FAGzi = 3240 - INTEGER(IntKi), PARAMETER :: M1N1FAFxi = 3241 - INTEGER(IntKi), PARAMETER :: M1N2FAFxi = 3242 - INTEGER(IntKi), PARAMETER :: M1N3FAFxi = 3243 - INTEGER(IntKi), PARAMETER :: M1N4FAFxi = 3244 - INTEGER(IntKi), PARAMETER :: M1N5FAFxi = 3245 - INTEGER(IntKi), PARAMETER :: M1N6FAFxi = 3246 - INTEGER(IntKi), PARAMETER :: M1N7FAFxi = 3247 - INTEGER(IntKi), PARAMETER :: M1N8FAFxi = 3248 - INTEGER(IntKi), PARAMETER :: M1N9FAFxi = 3249 - INTEGER(IntKi), PARAMETER :: M2N1FAFxi = 3250 - INTEGER(IntKi), PARAMETER :: M2N2FAFxi = 3251 - INTEGER(IntKi), PARAMETER :: M2N3FAFxi = 3252 - INTEGER(IntKi), PARAMETER :: M2N4FAFxi = 3253 - INTEGER(IntKi), PARAMETER :: M2N5FAFxi = 3254 - INTEGER(IntKi), PARAMETER :: M2N6FAFxi = 3255 - INTEGER(IntKi), PARAMETER :: M2N7FAFxi = 3256 - INTEGER(IntKi), PARAMETER :: M2N8FAFxi = 3257 - INTEGER(IntKi), PARAMETER :: M2N9FAFxi = 3258 - INTEGER(IntKi), PARAMETER :: M3N1FAFxi = 3259 - INTEGER(IntKi), PARAMETER :: M3N2FAFxi = 3260 - INTEGER(IntKi), PARAMETER :: M3N3FAFxi = 3261 - INTEGER(IntKi), PARAMETER :: M3N4FAFxi = 3262 - INTEGER(IntKi), PARAMETER :: M3N5FAFxi = 3263 - INTEGER(IntKi), PARAMETER :: M3N6FAFxi = 3264 - INTEGER(IntKi), PARAMETER :: M3N7FAFxi = 3265 - INTEGER(IntKi), PARAMETER :: M3N8FAFxi = 3266 - INTEGER(IntKi), PARAMETER :: M3N9FAFxi = 3267 - INTEGER(IntKi), PARAMETER :: M4N1FAFxi = 3268 - INTEGER(IntKi), PARAMETER :: M4N2FAFxi = 3269 - INTEGER(IntKi), PARAMETER :: M4N3FAFxi = 3270 - INTEGER(IntKi), PARAMETER :: M4N4FAFxi = 3271 - INTEGER(IntKi), PARAMETER :: M4N5FAFxi = 3272 - INTEGER(IntKi), PARAMETER :: M4N6FAFxi = 3273 - INTEGER(IntKi), PARAMETER :: M4N7FAFxi = 3274 - INTEGER(IntKi), PARAMETER :: M4N8FAFxi = 3275 - INTEGER(IntKi), PARAMETER :: M4N9FAFxi = 3276 - INTEGER(IntKi), PARAMETER :: M5N1FAFxi = 3277 - INTEGER(IntKi), PARAMETER :: M5N2FAFxi = 3278 - INTEGER(IntKi), PARAMETER :: M5N3FAFxi = 3279 - INTEGER(IntKi), PARAMETER :: M5N4FAFxi = 3280 - INTEGER(IntKi), PARAMETER :: M5N5FAFxi = 3281 - INTEGER(IntKi), PARAMETER :: M5N6FAFxi = 3282 - INTEGER(IntKi), PARAMETER :: M5N7FAFxi = 3283 - INTEGER(IntKi), PARAMETER :: M5N8FAFxi = 3284 - INTEGER(IntKi), PARAMETER :: M5N9FAFxi = 3285 - INTEGER(IntKi), PARAMETER :: M6N1FAFxi = 3286 - INTEGER(IntKi), PARAMETER :: M6N2FAFxi = 3287 - INTEGER(IntKi), PARAMETER :: M6N3FAFxi = 3288 - INTEGER(IntKi), PARAMETER :: M6N4FAFxi = 3289 - INTEGER(IntKi), PARAMETER :: M6N5FAFxi = 3290 - INTEGER(IntKi), PARAMETER :: M6N6FAFxi = 3291 - INTEGER(IntKi), PARAMETER :: M6N7FAFxi = 3292 - INTEGER(IntKi), PARAMETER :: M6N8FAFxi = 3293 - INTEGER(IntKi), PARAMETER :: M6N9FAFxi = 3294 - INTEGER(IntKi), PARAMETER :: M7N1FAFxi = 3295 - INTEGER(IntKi), PARAMETER :: M7N2FAFxi = 3296 - INTEGER(IntKi), PARAMETER :: M7N3FAFxi = 3297 - INTEGER(IntKi), PARAMETER :: M7N4FAFxi = 3298 - INTEGER(IntKi), PARAMETER :: M7N5FAFxi = 3299 - INTEGER(IntKi), PARAMETER :: M7N6FAFxi = 3300 - INTEGER(IntKi), PARAMETER :: M7N7FAFxi = 3301 - INTEGER(IntKi), PARAMETER :: M7N8FAFxi = 3302 - INTEGER(IntKi), PARAMETER :: M7N9FAFxi = 3303 - INTEGER(IntKi), PARAMETER :: M8N1FAFxi = 3304 - INTEGER(IntKi), PARAMETER :: M8N2FAFxi = 3305 - INTEGER(IntKi), PARAMETER :: M8N3FAFxi = 3306 - INTEGER(IntKi), PARAMETER :: M8N4FAFxi = 3307 - INTEGER(IntKi), PARAMETER :: M8N5FAFxi = 3308 - INTEGER(IntKi), PARAMETER :: M8N6FAFxi = 3309 - INTEGER(IntKi), PARAMETER :: M8N7FAFxi = 3310 - INTEGER(IntKi), PARAMETER :: M8N8FAFxi = 3311 - INTEGER(IntKi), PARAMETER :: M8N9FAFxi = 3312 - INTEGER(IntKi), PARAMETER :: M9N1FAFxi = 3313 - INTEGER(IntKi), PARAMETER :: M9N2FAFxi = 3314 - INTEGER(IntKi), PARAMETER :: M9N3FAFxi = 3315 - INTEGER(IntKi), PARAMETER :: M9N4FAFxi = 3316 - INTEGER(IntKi), PARAMETER :: M9N5FAFxi = 3317 - INTEGER(IntKi), PARAMETER :: M9N6FAFxi = 3318 - INTEGER(IntKi), PARAMETER :: M9N7FAFxi = 3319 - INTEGER(IntKi), PARAMETER :: M9N8FAFxi = 3320 - INTEGER(IntKi), PARAMETER :: M9N9FAFxi = 3321 - INTEGER(IntKi), PARAMETER :: M1N1FAFyi = 3322 - INTEGER(IntKi), PARAMETER :: M1N2FAFyi = 3323 - INTEGER(IntKi), PARAMETER :: M1N3FAFyi = 3324 - INTEGER(IntKi), PARAMETER :: M1N4FAFyi = 3325 - INTEGER(IntKi), PARAMETER :: M1N5FAFyi = 3326 - INTEGER(IntKi), PARAMETER :: M1N6FAFyi = 3327 - INTEGER(IntKi), PARAMETER :: M1N7FAFyi = 3328 - INTEGER(IntKi), PARAMETER :: M1N8FAFyi = 3329 - INTEGER(IntKi), PARAMETER :: M1N9FAFyi = 3330 - INTEGER(IntKi), PARAMETER :: M2N1FAFyi = 3331 - INTEGER(IntKi), PARAMETER :: M2N2FAFyi = 3332 - INTEGER(IntKi), PARAMETER :: M2N3FAFyi = 3333 - INTEGER(IntKi), PARAMETER :: M2N4FAFyi = 3334 - INTEGER(IntKi), PARAMETER :: M2N5FAFyi = 3335 - INTEGER(IntKi), PARAMETER :: M2N6FAFyi = 3336 - INTEGER(IntKi), PARAMETER :: M2N7FAFyi = 3337 - INTEGER(IntKi), PARAMETER :: M2N8FAFyi = 3338 - INTEGER(IntKi), PARAMETER :: M2N9FAFyi = 3339 - INTEGER(IntKi), PARAMETER :: M3N1FAFyi = 3340 - INTEGER(IntKi), PARAMETER :: M3N2FAFyi = 3341 - INTEGER(IntKi), PARAMETER :: M3N3FAFyi = 3342 - INTEGER(IntKi), PARAMETER :: M3N4FAFyi = 3343 - INTEGER(IntKi), PARAMETER :: M3N5FAFyi = 3344 - INTEGER(IntKi), PARAMETER :: M3N6FAFyi = 3345 - INTEGER(IntKi), PARAMETER :: M3N7FAFyi = 3346 - INTEGER(IntKi), PARAMETER :: M3N8FAFyi = 3347 - INTEGER(IntKi), PARAMETER :: M3N9FAFyi = 3348 - INTEGER(IntKi), PARAMETER :: M4N1FAFyi = 3349 - INTEGER(IntKi), PARAMETER :: M4N2FAFyi = 3350 - INTEGER(IntKi), PARAMETER :: M4N3FAFyi = 3351 - INTEGER(IntKi), PARAMETER :: M4N4FAFyi = 3352 - INTEGER(IntKi), PARAMETER :: M4N5FAFyi = 3353 - INTEGER(IntKi), PARAMETER :: M4N6FAFyi = 3354 - INTEGER(IntKi), PARAMETER :: M4N7FAFyi = 3355 - INTEGER(IntKi), PARAMETER :: M4N8FAFyi = 3356 - INTEGER(IntKi), PARAMETER :: M4N9FAFyi = 3357 - INTEGER(IntKi), PARAMETER :: M5N1FAFyi = 3358 - INTEGER(IntKi), PARAMETER :: M5N2FAFyi = 3359 - INTEGER(IntKi), PARAMETER :: M5N3FAFyi = 3360 - INTEGER(IntKi), PARAMETER :: M5N4FAFyi = 3361 - INTEGER(IntKi), PARAMETER :: M5N5FAFyi = 3362 - INTEGER(IntKi), PARAMETER :: M5N6FAFyi = 3363 - INTEGER(IntKi), PARAMETER :: M5N7FAFyi = 3364 - INTEGER(IntKi), PARAMETER :: M5N8FAFyi = 3365 - INTEGER(IntKi), PARAMETER :: M5N9FAFyi = 3366 - INTEGER(IntKi), PARAMETER :: M6N1FAFyi = 3367 - INTEGER(IntKi), PARAMETER :: M6N2FAFyi = 3368 - INTEGER(IntKi), PARAMETER :: M6N3FAFyi = 3369 - INTEGER(IntKi), PARAMETER :: M6N4FAFyi = 3370 - INTEGER(IntKi), PARAMETER :: M6N5FAFyi = 3371 - INTEGER(IntKi), PARAMETER :: M6N6FAFyi = 3372 - INTEGER(IntKi), PARAMETER :: M6N7FAFyi = 3373 - INTEGER(IntKi), PARAMETER :: M6N8FAFyi = 3374 - INTEGER(IntKi), PARAMETER :: M6N9FAFyi = 3375 - INTEGER(IntKi), PARAMETER :: M7N1FAFyi = 3376 - INTEGER(IntKi), PARAMETER :: M7N2FAFyi = 3377 - INTEGER(IntKi), PARAMETER :: M7N3FAFyi = 3378 - INTEGER(IntKi), PARAMETER :: M7N4FAFyi = 3379 - INTEGER(IntKi), PARAMETER :: M7N5FAFyi = 3380 - INTEGER(IntKi), PARAMETER :: M7N6FAFyi = 3381 - INTEGER(IntKi), PARAMETER :: M7N7FAFyi = 3382 - INTEGER(IntKi), PARAMETER :: M7N8FAFyi = 3383 - INTEGER(IntKi), PARAMETER :: M7N9FAFyi = 3384 - INTEGER(IntKi), PARAMETER :: M8N1FAFyi = 3385 - INTEGER(IntKi), PARAMETER :: M8N2FAFyi = 3386 - INTEGER(IntKi), PARAMETER :: M8N3FAFyi = 3387 - INTEGER(IntKi), PARAMETER :: M8N4FAFyi = 3388 - INTEGER(IntKi), PARAMETER :: M8N5FAFyi = 3389 - INTEGER(IntKi), PARAMETER :: M8N6FAFyi = 3390 - INTEGER(IntKi), PARAMETER :: M8N7FAFyi = 3391 - INTEGER(IntKi), PARAMETER :: M8N8FAFyi = 3392 - INTEGER(IntKi), PARAMETER :: M8N9FAFyi = 3393 - INTEGER(IntKi), PARAMETER :: M9N1FAFyi = 3394 - INTEGER(IntKi), PARAMETER :: M9N2FAFyi = 3395 - INTEGER(IntKi), PARAMETER :: M9N3FAFyi = 3396 - INTEGER(IntKi), PARAMETER :: M9N4FAFyi = 3397 - INTEGER(IntKi), PARAMETER :: M9N5FAFyi = 3398 - INTEGER(IntKi), PARAMETER :: M9N6FAFyi = 3399 - INTEGER(IntKi), PARAMETER :: M9N7FAFyi = 3400 - INTEGER(IntKi), PARAMETER :: M9N8FAFyi = 3401 - INTEGER(IntKi), PARAMETER :: M9N9FAFyi = 3402 - INTEGER(IntKi), PARAMETER :: M1N1FAFzi = 3403 - INTEGER(IntKi), PARAMETER :: M1N2FAFzi = 3404 - INTEGER(IntKi), PARAMETER :: M1N3FAFzi = 3405 - INTEGER(IntKi), PARAMETER :: M1N4FAFzi = 3406 - INTEGER(IntKi), PARAMETER :: M1N5FAFzi = 3407 - INTEGER(IntKi), PARAMETER :: M1N6FAFzi = 3408 - INTEGER(IntKi), PARAMETER :: M1N7FAFzi = 3409 - INTEGER(IntKi), PARAMETER :: M1N8FAFzi = 3410 - INTEGER(IntKi), PARAMETER :: M1N9FAFzi = 3411 - INTEGER(IntKi), PARAMETER :: M2N1FAFzi = 3412 - INTEGER(IntKi), PARAMETER :: M2N2FAFzi = 3413 - INTEGER(IntKi), PARAMETER :: M2N3FAFzi = 3414 - INTEGER(IntKi), PARAMETER :: M2N4FAFzi = 3415 - INTEGER(IntKi), PARAMETER :: M2N5FAFzi = 3416 - INTEGER(IntKi), PARAMETER :: M2N6FAFzi = 3417 - INTEGER(IntKi), PARAMETER :: M2N7FAFzi = 3418 - INTEGER(IntKi), PARAMETER :: M2N8FAFzi = 3419 - INTEGER(IntKi), PARAMETER :: M2N9FAFzi = 3420 - INTEGER(IntKi), PARAMETER :: M3N1FAFzi = 3421 - INTEGER(IntKi), PARAMETER :: M3N2FAFzi = 3422 - INTEGER(IntKi), PARAMETER :: M3N3FAFzi = 3423 - INTEGER(IntKi), PARAMETER :: M3N4FAFzi = 3424 - INTEGER(IntKi), PARAMETER :: M3N5FAFzi = 3425 - INTEGER(IntKi), PARAMETER :: M3N6FAFzi = 3426 - INTEGER(IntKi), PARAMETER :: M3N7FAFzi = 3427 - INTEGER(IntKi), PARAMETER :: M3N8FAFzi = 3428 - INTEGER(IntKi), PARAMETER :: M3N9FAFzi = 3429 - INTEGER(IntKi), PARAMETER :: M4N1FAFzi = 3430 - INTEGER(IntKi), PARAMETER :: M4N2FAFzi = 3431 - INTEGER(IntKi), PARAMETER :: M4N3FAFzi = 3432 - INTEGER(IntKi), PARAMETER :: M4N4FAFzi = 3433 - INTEGER(IntKi), PARAMETER :: M4N5FAFzi = 3434 - INTEGER(IntKi), PARAMETER :: M4N6FAFzi = 3435 - INTEGER(IntKi), PARAMETER :: M4N7FAFzi = 3436 - INTEGER(IntKi), PARAMETER :: M4N8FAFzi = 3437 - INTEGER(IntKi), PARAMETER :: M4N9FAFzi = 3438 - INTEGER(IntKi), PARAMETER :: M5N1FAFzi = 3439 - INTEGER(IntKi), PARAMETER :: M5N2FAFzi = 3440 - INTEGER(IntKi), PARAMETER :: M5N3FAFzi = 3441 - INTEGER(IntKi), PARAMETER :: M5N4FAFzi = 3442 - INTEGER(IntKi), PARAMETER :: M5N5FAFzi = 3443 - INTEGER(IntKi), PARAMETER :: M5N6FAFzi = 3444 - INTEGER(IntKi), PARAMETER :: M5N7FAFzi = 3445 - INTEGER(IntKi), PARAMETER :: M5N8FAFzi = 3446 - INTEGER(IntKi), PARAMETER :: M5N9FAFzi = 3447 - INTEGER(IntKi), PARAMETER :: M6N1FAFzi = 3448 - INTEGER(IntKi), PARAMETER :: M6N2FAFzi = 3449 - INTEGER(IntKi), PARAMETER :: M6N3FAFzi = 3450 - INTEGER(IntKi), PARAMETER :: M6N4FAFzi = 3451 - INTEGER(IntKi), PARAMETER :: M6N5FAFzi = 3452 - INTEGER(IntKi), PARAMETER :: M6N6FAFzi = 3453 - INTEGER(IntKi), PARAMETER :: M6N7FAFzi = 3454 - INTEGER(IntKi), PARAMETER :: M6N8FAFzi = 3455 - INTEGER(IntKi), PARAMETER :: M6N9FAFzi = 3456 - INTEGER(IntKi), PARAMETER :: M7N1FAFzi = 3457 - INTEGER(IntKi), PARAMETER :: M7N2FAFzi = 3458 - INTEGER(IntKi), PARAMETER :: M7N3FAFzi = 3459 - INTEGER(IntKi), PARAMETER :: M7N4FAFzi = 3460 - INTEGER(IntKi), PARAMETER :: M7N5FAFzi = 3461 - INTEGER(IntKi), PARAMETER :: M7N6FAFzi = 3462 - INTEGER(IntKi), PARAMETER :: M7N7FAFzi = 3463 - INTEGER(IntKi), PARAMETER :: M7N8FAFzi = 3464 - INTEGER(IntKi), PARAMETER :: M7N9FAFzi = 3465 - INTEGER(IntKi), PARAMETER :: M8N1FAFzi = 3466 - INTEGER(IntKi), PARAMETER :: M8N2FAFzi = 3467 - INTEGER(IntKi), PARAMETER :: M8N3FAFzi = 3468 - INTEGER(IntKi), PARAMETER :: M8N4FAFzi = 3469 - INTEGER(IntKi), PARAMETER :: M8N5FAFzi = 3470 - INTEGER(IntKi), PARAMETER :: M8N6FAFzi = 3471 - INTEGER(IntKi), PARAMETER :: M8N7FAFzi = 3472 - INTEGER(IntKi), PARAMETER :: M8N8FAFzi = 3473 - INTEGER(IntKi), PARAMETER :: M8N9FAFzi = 3474 - INTEGER(IntKi), PARAMETER :: M9N1FAFzi = 3475 - INTEGER(IntKi), PARAMETER :: M9N2FAFzi = 3476 - INTEGER(IntKi), PARAMETER :: M9N3FAFzi = 3477 - INTEGER(IntKi), PARAMETER :: M9N4FAFzi = 3478 - INTEGER(IntKi), PARAMETER :: M9N5FAFzi = 3479 - INTEGER(IntKi), PARAMETER :: M9N6FAFzi = 3480 - INTEGER(IntKi), PARAMETER :: M9N7FAFzi = 3481 - INTEGER(IntKi), PARAMETER :: M9N8FAFzi = 3482 - INTEGER(IntKi), PARAMETER :: M9N9FAFzi = 3483 - INTEGER(IntKi), PARAMETER :: M1N1FAxi = 3484 - INTEGER(IntKi), PARAMETER :: M1N2FAxi = 3485 - INTEGER(IntKi), PARAMETER :: M1N3FAxi = 3486 - INTEGER(IntKi), PARAMETER :: M1N4FAxi = 3487 - INTEGER(IntKi), PARAMETER :: M1N5FAxi = 3488 - INTEGER(IntKi), PARAMETER :: M1N6FAxi = 3489 - INTEGER(IntKi), PARAMETER :: M1N7FAxi = 3490 - INTEGER(IntKi), PARAMETER :: M1N8FAxi = 3491 - INTEGER(IntKi), PARAMETER :: M1N9FAxi = 3492 - INTEGER(IntKi), PARAMETER :: M2N1FAxi = 3493 - INTEGER(IntKi), PARAMETER :: M2N2FAxi = 3494 - INTEGER(IntKi), PARAMETER :: M2N3FAxi = 3495 - INTEGER(IntKi), PARAMETER :: M2N4FAxi = 3496 - INTEGER(IntKi), PARAMETER :: M2N5FAxi = 3497 - INTEGER(IntKi), PARAMETER :: M2N6FAxi = 3498 - INTEGER(IntKi), PARAMETER :: M2N7FAxi = 3499 - INTEGER(IntKi), PARAMETER :: M2N8FAxi = 3500 - INTEGER(IntKi), PARAMETER :: M2N9FAxi = 3501 - INTEGER(IntKi), PARAMETER :: M3N1FAxi = 3502 - INTEGER(IntKi), PARAMETER :: M3N2FAxi = 3503 - INTEGER(IntKi), PARAMETER :: M3N3FAxi = 3504 - INTEGER(IntKi), PARAMETER :: M3N4FAxi = 3505 - INTEGER(IntKi), PARAMETER :: M3N5FAxi = 3506 - INTEGER(IntKi), PARAMETER :: M3N6FAxi = 3507 - INTEGER(IntKi), PARAMETER :: M3N7FAxi = 3508 - INTEGER(IntKi), PARAMETER :: M3N8FAxi = 3509 - INTEGER(IntKi), PARAMETER :: M3N9FAxi = 3510 - INTEGER(IntKi), PARAMETER :: M4N1FAxi = 3511 - INTEGER(IntKi), PARAMETER :: M4N2FAxi = 3512 - INTEGER(IntKi), PARAMETER :: M4N3FAxi = 3513 - INTEGER(IntKi), PARAMETER :: M4N4FAxi = 3514 - INTEGER(IntKi), PARAMETER :: M4N5FAxi = 3515 - INTEGER(IntKi), PARAMETER :: M4N6FAxi = 3516 - INTEGER(IntKi), PARAMETER :: M4N7FAxi = 3517 - INTEGER(IntKi), PARAMETER :: M4N8FAxi = 3518 - INTEGER(IntKi), PARAMETER :: M4N9FAxi = 3519 - INTEGER(IntKi), PARAMETER :: M5N1FAxi = 3520 - INTEGER(IntKi), PARAMETER :: M5N2FAxi = 3521 - INTEGER(IntKi), PARAMETER :: M5N3FAxi = 3522 - INTEGER(IntKi), PARAMETER :: M5N4FAxi = 3523 - INTEGER(IntKi), PARAMETER :: M5N5FAxi = 3524 - INTEGER(IntKi), PARAMETER :: M5N6FAxi = 3525 - INTEGER(IntKi), PARAMETER :: M5N7FAxi = 3526 - INTEGER(IntKi), PARAMETER :: M5N8FAxi = 3527 - INTEGER(IntKi), PARAMETER :: M5N9FAxi = 3528 - INTEGER(IntKi), PARAMETER :: M6N1FAxi = 3529 - INTEGER(IntKi), PARAMETER :: M6N2FAxi = 3530 - INTEGER(IntKi), PARAMETER :: M6N3FAxi = 3531 - INTEGER(IntKi), PARAMETER :: M6N4FAxi = 3532 - INTEGER(IntKi), PARAMETER :: M6N5FAxi = 3533 - INTEGER(IntKi), PARAMETER :: M6N6FAxi = 3534 - INTEGER(IntKi), PARAMETER :: M6N7FAxi = 3535 - INTEGER(IntKi), PARAMETER :: M6N8FAxi = 3536 - INTEGER(IntKi), PARAMETER :: M6N9FAxi = 3537 - INTEGER(IntKi), PARAMETER :: M7N1FAxi = 3538 - INTEGER(IntKi), PARAMETER :: M7N2FAxi = 3539 - INTEGER(IntKi), PARAMETER :: M7N3FAxi = 3540 - INTEGER(IntKi), PARAMETER :: M7N4FAxi = 3541 - INTEGER(IntKi), PARAMETER :: M7N5FAxi = 3542 - INTEGER(IntKi), PARAMETER :: M7N6FAxi = 3543 - INTEGER(IntKi), PARAMETER :: M7N7FAxi = 3544 - INTEGER(IntKi), PARAMETER :: M7N8FAxi = 3545 - INTEGER(IntKi), PARAMETER :: M7N9FAxi = 3546 - INTEGER(IntKi), PARAMETER :: M8N1FAxi = 3547 - INTEGER(IntKi), PARAMETER :: M8N2FAxi = 3548 - INTEGER(IntKi), PARAMETER :: M8N3FAxi = 3549 - INTEGER(IntKi), PARAMETER :: M8N4FAxi = 3550 - INTEGER(IntKi), PARAMETER :: M8N5FAxi = 3551 - INTEGER(IntKi), PARAMETER :: M8N6FAxi = 3552 - INTEGER(IntKi), PARAMETER :: M8N7FAxi = 3553 - INTEGER(IntKi), PARAMETER :: M8N8FAxi = 3554 - INTEGER(IntKi), PARAMETER :: M8N9FAxi = 3555 - INTEGER(IntKi), PARAMETER :: M9N1FAxi = 3556 - INTEGER(IntKi), PARAMETER :: M9N2FAxi = 3557 - INTEGER(IntKi), PARAMETER :: M9N3FAxi = 3558 - INTEGER(IntKi), PARAMETER :: M9N4FAxi = 3559 - INTEGER(IntKi), PARAMETER :: M9N5FAxi = 3560 - INTEGER(IntKi), PARAMETER :: M9N6FAxi = 3561 - INTEGER(IntKi), PARAMETER :: M9N7FAxi = 3562 - INTEGER(IntKi), PARAMETER :: M9N8FAxi = 3563 - INTEGER(IntKi), PARAMETER :: M9N9FAxi = 3564 - INTEGER(IntKi), PARAMETER :: M1N1FAyi = 3565 - INTEGER(IntKi), PARAMETER :: M1N2FAyi = 3566 - INTEGER(IntKi), PARAMETER :: M1N3FAyi = 3567 - INTEGER(IntKi), PARAMETER :: M1N4FAyi = 3568 - INTEGER(IntKi), PARAMETER :: M1N5FAyi = 3569 - INTEGER(IntKi), PARAMETER :: M1N6FAyi = 3570 - INTEGER(IntKi), PARAMETER :: M1N7FAyi = 3571 - INTEGER(IntKi), PARAMETER :: M1N8FAyi = 3572 - INTEGER(IntKi), PARAMETER :: M1N9FAyi = 3573 - INTEGER(IntKi), PARAMETER :: M2N1FAyi = 3574 - INTEGER(IntKi), PARAMETER :: M2N2FAyi = 3575 - INTEGER(IntKi), PARAMETER :: M2N3FAyi = 3576 - INTEGER(IntKi), PARAMETER :: M2N4FAyi = 3577 - INTEGER(IntKi), PARAMETER :: M2N5FAyi = 3578 - INTEGER(IntKi), PARAMETER :: M2N6FAyi = 3579 - INTEGER(IntKi), PARAMETER :: M2N7FAyi = 3580 - INTEGER(IntKi), PARAMETER :: M2N8FAyi = 3581 - INTEGER(IntKi), PARAMETER :: M2N9FAyi = 3582 - INTEGER(IntKi), PARAMETER :: M3N1FAyi = 3583 - INTEGER(IntKi), PARAMETER :: M3N2FAyi = 3584 - INTEGER(IntKi), PARAMETER :: M3N3FAyi = 3585 - INTEGER(IntKi), PARAMETER :: M3N4FAyi = 3586 - INTEGER(IntKi), PARAMETER :: M3N5FAyi = 3587 - INTEGER(IntKi), PARAMETER :: M3N6FAyi = 3588 - INTEGER(IntKi), PARAMETER :: M3N7FAyi = 3589 - INTEGER(IntKi), PARAMETER :: M3N8FAyi = 3590 - INTEGER(IntKi), PARAMETER :: M3N9FAyi = 3591 - INTEGER(IntKi), PARAMETER :: M4N1FAyi = 3592 - INTEGER(IntKi), PARAMETER :: M4N2FAyi = 3593 - INTEGER(IntKi), PARAMETER :: M4N3FAyi = 3594 - INTEGER(IntKi), PARAMETER :: M4N4FAyi = 3595 - INTEGER(IntKi), PARAMETER :: M4N5FAyi = 3596 - INTEGER(IntKi), PARAMETER :: M4N6FAyi = 3597 - INTEGER(IntKi), PARAMETER :: M4N7FAyi = 3598 - INTEGER(IntKi), PARAMETER :: M4N8FAyi = 3599 - INTEGER(IntKi), PARAMETER :: M4N9FAyi = 3600 - INTEGER(IntKi), PARAMETER :: M5N1FAyi = 3601 - INTEGER(IntKi), PARAMETER :: M5N2FAyi = 3602 - INTEGER(IntKi), PARAMETER :: M5N3FAyi = 3603 - INTEGER(IntKi), PARAMETER :: M5N4FAyi = 3604 - INTEGER(IntKi), PARAMETER :: M5N5FAyi = 3605 - INTEGER(IntKi), PARAMETER :: M5N6FAyi = 3606 - INTEGER(IntKi), PARAMETER :: M5N7FAyi = 3607 - INTEGER(IntKi), PARAMETER :: M5N8FAyi = 3608 - INTEGER(IntKi), PARAMETER :: M5N9FAyi = 3609 - INTEGER(IntKi), PARAMETER :: M6N1FAyi = 3610 - INTEGER(IntKi), PARAMETER :: M6N2FAyi = 3611 - INTEGER(IntKi), PARAMETER :: M6N3FAyi = 3612 - INTEGER(IntKi), PARAMETER :: M6N4FAyi = 3613 - INTEGER(IntKi), PARAMETER :: M6N5FAyi = 3614 - INTEGER(IntKi), PARAMETER :: M6N6FAyi = 3615 - INTEGER(IntKi), PARAMETER :: M6N7FAyi = 3616 - INTEGER(IntKi), PARAMETER :: M6N8FAyi = 3617 - INTEGER(IntKi), PARAMETER :: M6N9FAyi = 3618 - INTEGER(IntKi), PARAMETER :: M7N1FAyi = 3619 - INTEGER(IntKi), PARAMETER :: M7N2FAyi = 3620 - INTEGER(IntKi), PARAMETER :: M7N3FAyi = 3621 - INTEGER(IntKi), PARAMETER :: M7N4FAyi = 3622 - INTEGER(IntKi), PARAMETER :: M7N5FAyi = 3623 - INTEGER(IntKi), PARAMETER :: M7N6FAyi = 3624 - INTEGER(IntKi), PARAMETER :: M7N7FAyi = 3625 - INTEGER(IntKi), PARAMETER :: M7N8FAyi = 3626 - INTEGER(IntKi), PARAMETER :: M7N9FAyi = 3627 - INTEGER(IntKi), PARAMETER :: M8N1FAyi = 3628 - INTEGER(IntKi), PARAMETER :: M8N2FAyi = 3629 - INTEGER(IntKi), PARAMETER :: M8N3FAyi = 3630 - INTEGER(IntKi), PARAMETER :: M8N4FAyi = 3631 - INTEGER(IntKi), PARAMETER :: M8N5FAyi = 3632 - INTEGER(IntKi), PARAMETER :: M8N6FAyi = 3633 - INTEGER(IntKi), PARAMETER :: M8N7FAyi = 3634 - INTEGER(IntKi), PARAMETER :: M8N8FAyi = 3635 - INTEGER(IntKi), PARAMETER :: M8N9FAyi = 3636 - INTEGER(IntKi), PARAMETER :: M9N1FAyi = 3637 - INTEGER(IntKi), PARAMETER :: M9N2FAyi = 3638 - INTEGER(IntKi), PARAMETER :: M9N3FAyi = 3639 - INTEGER(IntKi), PARAMETER :: M9N4FAyi = 3640 - INTEGER(IntKi), PARAMETER :: M9N5FAyi = 3641 - INTEGER(IntKi), PARAMETER :: M9N6FAyi = 3642 - INTEGER(IntKi), PARAMETER :: M9N7FAyi = 3643 - INTEGER(IntKi), PARAMETER :: M9N8FAyi = 3644 - INTEGER(IntKi), PARAMETER :: M9N9FAyi = 3645 - INTEGER(IntKi), PARAMETER :: M1N1FAzi = 3646 - INTEGER(IntKi), PARAMETER :: M1N2FAzi = 3647 - INTEGER(IntKi), PARAMETER :: M1N3FAzi = 3648 - INTEGER(IntKi), PARAMETER :: M1N4FAzi = 3649 - INTEGER(IntKi), PARAMETER :: M1N5FAzi = 3650 - INTEGER(IntKi), PARAMETER :: M1N6FAzi = 3651 - INTEGER(IntKi), PARAMETER :: M1N7FAzi = 3652 - INTEGER(IntKi), PARAMETER :: M1N8FAzi = 3653 - INTEGER(IntKi), PARAMETER :: M1N9FAzi = 3654 - INTEGER(IntKi), PARAMETER :: M2N1FAzi = 3655 - INTEGER(IntKi), PARAMETER :: M2N2FAzi = 3656 - INTEGER(IntKi), PARAMETER :: M2N3FAzi = 3657 - INTEGER(IntKi), PARAMETER :: M2N4FAzi = 3658 - INTEGER(IntKi), PARAMETER :: M2N5FAzi = 3659 - INTEGER(IntKi), PARAMETER :: M2N6FAzi = 3660 - INTEGER(IntKi), PARAMETER :: M2N7FAzi = 3661 - INTEGER(IntKi), PARAMETER :: M2N8FAzi = 3662 - INTEGER(IntKi), PARAMETER :: M2N9FAzi = 3663 - INTEGER(IntKi), PARAMETER :: M3N1FAzi = 3664 - INTEGER(IntKi), PARAMETER :: M3N2FAzi = 3665 - INTEGER(IntKi), PARAMETER :: M3N3FAzi = 3666 - INTEGER(IntKi), PARAMETER :: M3N4FAzi = 3667 - INTEGER(IntKi), PARAMETER :: M3N5FAzi = 3668 - INTEGER(IntKi), PARAMETER :: M3N6FAzi = 3669 - INTEGER(IntKi), PARAMETER :: M3N7FAzi = 3670 - INTEGER(IntKi), PARAMETER :: M3N8FAzi = 3671 - INTEGER(IntKi), PARAMETER :: M3N9FAzi = 3672 - INTEGER(IntKi), PARAMETER :: M4N1FAzi = 3673 - INTEGER(IntKi), PARAMETER :: M4N2FAzi = 3674 - INTEGER(IntKi), PARAMETER :: M4N3FAzi = 3675 - INTEGER(IntKi), PARAMETER :: M4N4FAzi = 3676 - INTEGER(IntKi), PARAMETER :: M4N5FAzi = 3677 - INTEGER(IntKi), PARAMETER :: M4N6FAzi = 3678 - INTEGER(IntKi), PARAMETER :: M4N7FAzi = 3679 - INTEGER(IntKi), PARAMETER :: M4N8FAzi = 3680 - INTEGER(IntKi), PARAMETER :: M4N9FAzi = 3681 - INTEGER(IntKi), PARAMETER :: M5N1FAzi = 3682 - INTEGER(IntKi), PARAMETER :: M5N2FAzi = 3683 - INTEGER(IntKi), PARAMETER :: M5N3FAzi = 3684 - INTEGER(IntKi), PARAMETER :: M5N4FAzi = 3685 - INTEGER(IntKi), PARAMETER :: M5N5FAzi = 3686 - INTEGER(IntKi), PARAMETER :: M5N6FAzi = 3687 - INTEGER(IntKi), PARAMETER :: M5N7FAzi = 3688 - INTEGER(IntKi), PARAMETER :: M5N8FAzi = 3689 - INTEGER(IntKi), PARAMETER :: M5N9FAzi = 3690 - INTEGER(IntKi), PARAMETER :: M6N1FAzi = 3691 - INTEGER(IntKi), PARAMETER :: M6N2FAzi = 3692 - INTEGER(IntKi), PARAMETER :: M6N3FAzi = 3693 - INTEGER(IntKi), PARAMETER :: M6N4FAzi = 3694 - INTEGER(IntKi), PARAMETER :: M6N5FAzi = 3695 - INTEGER(IntKi), PARAMETER :: M6N6FAzi = 3696 - INTEGER(IntKi), PARAMETER :: M6N7FAzi = 3697 - INTEGER(IntKi), PARAMETER :: M6N8FAzi = 3698 - INTEGER(IntKi), PARAMETER :: M6N9FAzi = 3699 - INTEGER(IntKi), PARAMETER :: M7N1FAzi = 3700 - INTEGER(IntKi), PARAMETER :: M7N2FAzi = 3701 - INTEGER(IntKi), PARAMETER :: M7N3FAzi = 3702 - INTEGER(IntKi), PARAMETER :: M7N4FAzi = 3703 - INTEGER(IntKi), PARAMETER :: M7N5FAzi = 3704 - INTEGER(IntKi), PARAMETER :: M7N6FAzi = 3705 - INTEGER(IntKi), PARAMETER :: M7N7FAzi = 3706 - INTEGER(IntKi), PARAMETER :: M7N8FAzi = 3707 - INTEGER(IntKi), PARAMETER :: M7N9FAzi = 3708 - INTEGER(IntKi), PARAMETER :: M8N1FAzi = 3709 - INTEGER(IntKi), PARAMETER :: M8N2FAzi = 3710 - INTEGER(IntKi), PARAMETER :: M8N3FAzi = 3711 - INTEGER(IntKi), PARAMETER :: M8N4FAzi = 3712 - INTEGER(IntKi), PARAMETER :: M8N5FAzi = 3713 - INTEGER(IntKi), PARAMETER :: M8N6FAzi = 3714 - INTEGER(IntKi), PARAMETER :: M8N7FAzi = 3715 - INTEGER(IntKi), PARAMETER :: M8N8FAzi = 3716 - INTEGER(IntKi), PARAMETER :: M8N9FAzi = 3717 - INTEGER(IntKi), PARAMETER :: M9N1FAzi = 3718 - INTEGER(IntKi), PARAMETER :: M9N2FAzi = 3719 - INTEGER(IntKi), PARAMETER :: M9N3FAzi = 3720 - INTEGER(IntKi), PARAMETER :: M9N4FAzi = 3721 - INTEGER(IntKi), PARAMETER :: M9N5FAzi = 3722 - INTEGER(IntKi), PARAMETER :: M9N6FAzi = 3723 - INTEGER(IntKi), PARAMETER :: M9N7FAzi = 3724 - INTEGER(IntKi), PARAMETER :: M9N8FAzi = 3725 - INTEGER(IntKi), PARAMETER :: M9N9FAzi = 3726 - + INTEGER(IntKi), PARAMETER :: M1N1MMGxi = 2755 + INTEGER(IntKi), PARAMETER :: M1N2MMGxi = 2756 + INTEGER(IntKi), PARAMETER :: M1N3MMGxi = 2757 + INTEGER(IntKi), PARAMETER :: M1N4MMGxi = 2758 + INTEGER(IntKi), PARAMETER :: M1N5MMGxi = 2759 + INTEGER(IntKi), PARAMETER :: M1N6MMGxi = 2760 + INTEGER(IntKi), PARAMETER :: M1N7MMGxi = 2761 + INTEGER(IntKi), PARAMETER :: M1N8MMGxi = 2762 + INTEGER(IntKi), PARAMETER :: M1N9MMGxi = 2763 + INTEGER(IntKi), PARAMETER :: M2N1MMGxi = 2764 + INTEGER(IntKi), PARAMETER :: M2N2MMGxi = 2765 + INTEGER(IntKi), PARAMETER :: M2N3MMGxi = 2766 + INTEGER(IntKi), PARAMETER :: M2N4MMGxi = 2767 + INTEGER(IntKi), PARAMETER :: M2N5MMGxi = 2768 + INTEGER(IntKi), PARAMETER :: M2N6MMGxi = 2769 + INTEGER(IntKi), PARAMETER :: M2N7MMGxi = 2770 + INTEGER(IntKi), PARAMETER :: M2N8MMGxi = 2771 + INTEGER(IntKi), PARAMETER :: M2N9MMGxi = 2772 + INTEGER(IntKi), PARAMETER :: M3N1MMGxi = 2773 + INTEGER(IntKi), PARAMETER :: M3N2MMGxi = 2774 + INTEGER(IntKi), PARAMETER :: M3N3MMGxi = 2775 + INTEGER(IntKi), PARAMETER :: M3N4MMGxi = 2776 + INTEGER(IntKi), PARAMETER :: M3N5MMGxi = 2777 + INTEGER(IntKi), PARAMETER :: M3N6MMGxi = 2778 + INTEGER(IntKi), PARAMETER :: M3N7MMGxi = 2779 + INTEGER(IntKi), PARAMETER :: M3N8MMGxi = 2780 + INTEGER(IntKi), PARAMETER :: M3N9MMGxi = 2781 + INTEGER(IntKi), PARAMETER :: M4N1MMGxi = 2782 + INTEGER(IntKi), PARAMETER :: M4N2MMGxi = 2783 + INTEGER(IntKi), PARAMETER :: M4N3MMGxi = 2784 + INTEGER(IntKi), PARAMETER :: M4N4MMGxi = 2785 + INTEGER(IntKi), PARAMETER :: M4N5MMGxi = 2786 + INTEGER(IntKi), PARAMETER :: M4N6MMGxi = 2787 + INTEGER(IntKi), PARAMETER :: M4N7MMGxi = 2788 + INTEGER(IntKi), PARAMETER :: M4N8MMGxi = 2789 + INTEGER(IntKi), PARAMETER :: M4N9MMGxi = 2790 + INTEGER(IntKi), PARAMETER :: M5N1MMGxi = 2791 + INTEGER(IntKi), PARAMETER :: M5N2MMGxi = 2792 + INTEGER(IntKi), PARAMETER :: M5N3MMGxi = 2793 + INTEGER(IntKi), PARAMETER :: M5N4MMGxi = 2794 + INTEGER(IntKi), PARAMETER :: M5N5MMGxi = 2795 + INTEGER(IntKi), PARAMETER :: M5N6MMGxi = 2796 + INTEGER(IntKi), PARAMETER :: M5N7MMGxi = 2797 + INTEGER(IntKi), PARAMETER :: M5N8MMGxi = 2798 + INTEGER(IntKi), PARAMETER :: M5N9MMGxi = 2799 + INTEGER(IntKi), PARAMETER :: M6N1MMGxi = 2800 + INTEGER(IntKi), PARAMETER :: M6N2MMGxi = 2801 + INTEGER(IntKi), PARAMETER :: M6N3MMGxi = 2802 + INTEGER(IntKi), PARAMETER :: M6N4MMGxi = 2803 + INTEGER(IntKi), PARAMETER :: M6N5MMGxi = 2804 + INTEGER(IntKi), PARAMETER :: M6N6MMGxi = 2805 + INTEGER(IntKi), PARAMETER :: M6N7MMGxi = 2806 + INTEGER(IntKi), PARAMETER :: M6N8MMGxi = 2807 + INTEGER(IntKi), PARAMETER :: M6N9MMGxi = 2808 + INTEGER(IntKi), PARAMETER :: M7N1MMGxi = 2809 + INTEGER(IntKi), PARAMETER :: M7N2MMGxi = 2810 + INTEGER(IntKi), PARAMETER :: M7N3MMGxi = 2811 + INTEGER(IntKi), PARAMETER :: M7N4MMGxi = 2812 + INTEGER(IntKi), PARAMETER :: M7N5MMGxi = 2813 + INTEGER(IntKi), PARAMETER :: M7N6MMGxi = 2814 + INTEGER(IntKi), PARAMETER :: M7N7MMGxi = 2815 + INTEGER(IntKi), PARAMETER :: M7N8MMGxi = 2816 + INTEGER(IntKi), PARAMETER :: M7N9MMGxi = 2817 + INTEGER(IntKi), PARAMETER :: M8N1MMGxi = 2818 + INTEGER(IntKi), PARAMETER :: M8N2MMGxi = 2819 + INTEGER(IntKi), PARAMETER :: M8N3MMGxi = 2820 + INTEGER(IntKi), PARAMETER :: M8N4MMGxi = 2821 + INTEGER(IntKi), PARAMETER :: M8N5MMGxi = 2822 + INTEGER(IntKi), PARAMETER :: M8N6MMGxi = 2823 + INTEGER(IntKi), PARAMETER :: M8N7MMGxi = 2824 + INTEGER(IntKi), PARAMETER :: M8N8MMGxi = 2825 + INTEGER(IntKi), PARAMETER :: M8N9MMGxi = 2826 + INTEGER(IntKi), PARAMETER :: M9N1MMGxi = 2827 + INTEGER(IntKi), PARAMETER :: M9N2MMGxi = 2828 + INTEGER(IntKi), PARAMETER :: M9N3MMGxi = 2829 + INTEGER(IntKi), PARAMETER :: M9N4MMGxi = 2830 + INTEGER(IntKi), PARAMETER :: M9N5MMGxi = 2831 + INTEGER(IntKi), PARAMETER :: M9N6MMGxi = 2832 + INTEGER(IntKi), PARAMETER :: M9N7MMGxi = 2833 + INTEGER(IntKi), PARAMETER :: M9N8MMGxi = 2834 + INTEGER(IntKi), PARAMETER :: M9N9MMGxi = 2835 + INTEGER(IntKi), PARAMETER :: M1N1MMGyi = 2836 + INTEGER(IntKi), PARAMETER :: M1N2MMGyi = 2837 + INTEGER(IntKi), PARAMETER :: M1N3MMGyi = 2838 + INTEGER(IntKi), PARAMETER :: M1N4MMGyi = 2839 + INTEGER(IntKi), PARAMETER :: M1N5MMGyi = 2840 + INTEGER(IntKi), PARAMETER :: M1N6MMGyi = 2841 + INTEGER(IntKi), PARAMETER :: M1N7MMGyi = 2842 + INTEGER(IntKi), PARAMETER :: M1N8MMGyi = 2843 + INTEGER(IntKi), PARAMETER :: M1N9MMGyi = 2844 + INTEGER(IntKi), PARAMETER :: M2N1MMGyi = 2845 + INTEGER(IntKi), PARAMETER :: M2N2MMGyi = 2846 + INTEGER(IntKi), PARAMETER :: M2N3MMGyi = 2847 + INTEGER(IntKi), PARAMETER :: M2N4MMGyi = 2848 + INTEGER(IntKi), PARAMETER :: M2N5MMGyi = 2849 + INTEGER(IntKi), PARAMETER :: M2N6MMGyi = 2850 + INTEGER(IntKi), PARAMETER :: M2N7MMGyi = 2851 + INTEGER(IntKi), PARAMETER :: M2N8MMGyi = 2852 + INTEGER(IntKi), PARAMETER :: M2N9MMGyi = 2853 + INTEGER(IntKi), PARAMETER :: M3N1MMGyi = 2854 + INTEGER(IntKi), PARAMETER :: M3N2MMGyi = 2855 + INTEGER(IntKi), PARAMETER :: M3N3MMGyi = 2856 + INTEGER(IntKi), PARAMETER :: M3N4MMGyi = 2857 + INTEGER(IntKi), PARAMETER :: M3N5MMGyi = 2858 + INTEGER(IntKi), PARAMETER :: M3N6MMGyi = 2859 + INTEGER(IntKi), PARAMETER :: M3N7MMGyi = 2860 + INTEGER(IntKi), PARAMETER :: M3N8MMGyi = 2861 + INTEGER(IntKi), PARAMETER :: M3N9MMGyi = 2862 + INTEGER(IntKi), PARAMETER :: M4N1MMGyi = 2863 + INTEGER(IntKi), PARAMETER :: M4N2MMGyi = 2864 + INTEGER(IntKi), PARAMETER :: M4N3MMGyi = 2865 + INTEGER(IntKi), PARAMETER :: M4N4MMGyi = 2866 + INTEGER(IntKi), PARAMETER :: M4N5MMGyi = 2867 + INTEGER(IntKi), PARAMETER :: M4N6MMGyi = 2868 + INTEGER(IntKi), PARAMETER :: M4N7MMGyi = 2869 + INTEGER(IntKi), PARAMETER :: M4N8MMGyi = 2870 + INTEGER(IntKi), PARAMETER :: M4N9MMGyi = 2871 + INTEGER(IntKi), PARAMETER :: M5N1MMGyi = 2872 + INTEGER(IntKi), PARAMETER :: M5N2MMGyi = 2873 + INTEGER(IntKi), PARAMETER :: M5N3MMGyi = 2874 + INTEGER(IntKi), PARAMETER :: M5N4MMGyi = 2875 + INTEGER(IntKi), PARAMETER :: M5N5MMGyi = 2876 + INTEGER(IntKi), PARAMETER :: M5N6MMGyi = 2877 + INTEGER(IntKi), PARAMETER :: M5N7MMGyi = 2878 + INTEGER(IntKi), PARAMETER :: M5N8MMGyi = 2879 + INTEGER(IntKi), PARAMETER :: M5N9MMGyi = 2880 + INTEGER(IntKi), PARAMETER :: M6N1MMGyi = 2881 + INTEGER(IntKi), PARAMETER :: M6N2MMGyi = 2882 + INTEGER(IntKi), PARAMETER :: M6N3MMGyi = 2883 + INTEGER(IntKi), PARAMETER :: M6N4MMGyi = 2884 + INTEGER(IntKi), PARAMETER :: M6N5MMGyi = 2885 + INTEGER(IntKi), PARAMETER :: M6N6MMGyi = 2886 + INTEGER(IntKi), PARAMETER :: M6N7MMGyi = 2887 + INTEGER(IntKi), PARAMETER :: M6N8MMGyi = 2888 + INTEGER(IntKi), PARAMETER :: M6N9MMGyi = 2889 + INTEGER(IntKi), PARAMETER :: M7N1MMGyi = 2890 + INTEGER(IntKi), PARAMETER :: M7N2MMGyi = 2891 + INTEGER(IntKi), PARAMETER :: M7N3MMGyi = 2892 + INTEGER(IntKi), PARAMETER :: M7N4MMGyi = 2893 + INTEGER(IntKi), PARAMETER :: M7N5MMGyi = 2894 + INTEGER(IntKi), PARAMETER :: M7N6MMGyi = 2895 + INTEGER(IntKi), PARAMETER :: M7N7MMGyi = 2896 + INTEGER(IntKi), PARAMETER :: M7N8MMGyi = 2897 + INTEGER(IntKi), PARAMETER :: M7N9MMGyi = 2898 + INTEGER(IntKi), PARAMETER :: M8N1MMGyi = 2899 + INTEGER(IntKi), PARAMETER :: M8N2MMGyi = 2900 + INTEGER(IntKi), PARAMETER :: M8N3MMGyi = 2901 + INTEGER(IntKi), PARAMETER :: M8N4MMGyi = 2902 + INTEGER(IntKi), PARAMETER :: M8N5MMGyi = 2903 + INTEGER(IntKi), PARAMETER :: M8N6MMGyi = 2904 + INTEGER(IntKi), PARAMETER :: M8N7MMGyi = 2905 + INTEGER(IntKi), PARAMETER :: M8N8MMGyi = 2906 + INTEGER(IntKi), PARAMETER :: M8N9MMGyi = 2907 + INTEGER(IntKi), PARAMETER :: M9N1MMGyi = 2908 + INTEGER(IntKi), PARAMETER :: M9N2MMGyi = 2909 + INTEGER(IntKi), PARAMETER :: M9N3MMGyi = 2910 + INTEGER(IntKi), PARAMETER :: M9N4MMGyi = 2911 + INTEGER(IntKi), PARAMETER :: M9N5MMGyi = 2912 + INTEGER(IntKi), PARAMETER :: M9N6MMGyi = 2913 + INTEGER(IntKi), PARAMETER :: M9N7MMGyi = 2914 + INTEGER(IntKi), PARAMETER :: M9N8MMGyi = 2915 + INTEGER(IntKi), PARAMETER :: M9N9MMGyi = 2916 + INTEGER(IntKi), PARAMETER :: M1N1MMGzi = 2917 + INTEGER(IntKi), PARAMETER :: M1N2MMGzi = 2918 + INTEGER(IntKi), PARAMETER :: M1N3MMGzi = 2919 + INTEGER(IntKi), PARAMETER :: M1N4MMGzi = 2920 + INTEGER(IntKi), PARAMETER :: M1N5MMGzi = 2921 + INTEGER(IntKi), PARAMETER :: M1N6MMGzi = 2922 + INTEGER(IntKi), PARAMETER :: M1N7MMGzi = 2923 + INTEGER(IntKi), PARAMETER :: M1N8MMGzi = 2924 + INTEGER(IntKi), PARAMETER :: M1N9MMGzi = 2925 + INTEGER(IntKi), PARAMETER :: M2N1MMGzi = 2926 + INTEGER(IntKi), PARAMETER :: M2N2MMGzi = 2927 + INTEGER(IntKi), PARAMETER :: M2N3MMGzi = 2928 + INTEGER(IntKi), PARAMETER :: M2N4MMGzi = 2929 + INTEGER(IntKi), PARAMETER :: M2N5MMGzi = 2930 + INTEGER(IntKi), PARAMETER :: M2N6MMGzi = 2931 + INTEGER(IntKi), PARAMETER :: M2N7MMGzi = 2932 + INTEGER(IntKi), PARAMETER :: M2N8MMGzi = 2933 + INTEGER(IntKi), PARAMETER :: M2N9MMGzi = 2934 + INTEGER(IntKi), PARAMETER :: M3N1MMGzi = 2935 + INTEGER(IntKi), PARAMETER :: M3N2MMGzi = 2936 + INTEGER(IntKi), PARAMETER :: M3N3MMGzi = 2937 + INTEGER(IntKi), PARAMETER :: M3N4MMGzi = 2938 + INTEGER(IntKi), PARAMETER :: M3N5MMGzi = 2939 + INTEGER(IntKi), PARAMETER :: M3N6MMGzi = 2940 + INTEGER(IntKi), PARAMETER :: M3N7MMGzi = 2941 + INTEGER(IntKi), PARAMETER :: M3N8MMGzi = 2942 + INTEGER(IntKi), PARAMETER :: M3N9MMGzi = 2943 + INTEGER(IntKi), PARAMETER :: M4N1MMGzi = 2944 + INTEGER(IntKi), PARAMETER :: M4N2MMGzi = 2945 + INTEGER(IntKi), PARAMETER :: M4N3MMGzi = 2946 + INTEGER(IntKi), PARAMETER :: M4N4MMGzi = 2947 + INTEGER(IntKi), PARAMETER :: M4N5MMGzi = 2948 + INTEGER(IntKi), PARAMETER :: M4N6MMGzi = 2949 + INTEGER(IntKi), PARAMETER :: M4N7MMGzi = 2950 + INTEGER(IntKi), PARAMETER :: M4N8MMGzi = 2951 + INTEGER(IntKi), PARAMETER :: M4N9MMGzi = 2952 + INTEGER(IntKi), PARAMETER :: M5N1MMGzi = 2953 + INTEGER(IntKi), PARAMETER :: M5N2MMGzi = 2954 + INTEGER(IntKi), PARAMETER :: M5N3MMGzi = 2955 + INTEGER(IntKi), PARAMETER :: M5N4MMGzi = 2956 + INTEGER(IntKi), PARAMETER :: M5N5MMGzi = 2957 + INTEGER(IntKi), PARAMETER :: M5N6MMGzi = 2958 + INTEGER(IntKi), PARAMETER :: M5N7MMGzi = 2959 + INTEGER(IntKi), PARAMETER :: M5N8MMGzi = 2960 + INTEGER(IntKi), PARAMETER :: M5N9MMGzi = 2961 + INTEGER(IntKi), PARAMETER :: M6N1MMGzi = 2962 + INTEGER(IntKi), PARAMETER :: M6N2MMGzi = 2963 + INTEGER(IntKi), PARAMETER :: M6N3MMGzi = 2964 + INTEGER(IntKi), PARAMETER :: M6N4MMGzi = 2965 + INTEGER(IntKi), PARAMETER :: M6N5MMGzi = 2966 + INTEGER(IntKi), PARAMETER :: M6N6MMGzi = 2967 + INTEGER(IntKi), PARAMETER :: M6N7MMGzi = 2968 + INTEGER(IntKi), PARAMETER :: M6N8MMGzi = 2969 + INTEGER(IntKi), PARAMETER :: M6N9MMGzi = 2970 + INTEGER(IntKi), PARAMETER :: M7N1MMGzi = 2971 + INTEGER(IntKi), PARAMETER :: M7N2MMGzi = 2972 + INTEGER(IntKi), PARAMETER :: M7N3MMGzi = 2973 + INTEGER(IntKi), PARAMETER :: M7N4MMGzi = 2974 + INTEGER(IntKi), PARAMETER :: M7N5MMGzi = 2975 + INTEGER(IntKi), PARAMETER :: M7N6MMGzi = 2976 + INTEGER(IntKi), PARAMETER :: M7N7MMGzi = 2977 + INTEGER(IntKi), PARAMETER :: M7N8MMGzi = 2978 + INTEGER(IntKi), PARAMETER :: M7N9MMGzi = 2979 + INTEGER(IntKi), PARAMETER :: M8N1MMGzi = 2980 + INTEGER(IntKi), PARAMETER :: M8N2MMGzi = 2981 + INTEGER(IntKi), PARAMETER :: M8N3MMGzi = 2982 + INTEGER(IntKi), PARAMETER :: M8N4MMGzi = 2983 + INTEGER(IntKi), PARAMETER :: M8N5MMGzi = 2984 + INTEGER(IntKi), PARAMETER :: M8N6MMGzi = 2985 + INTEGER(IntKi), PARAMETER :: M8N7MMGzi = 2986 + INTEGER(IntKi), PARAMETER :: M8N8MMGzi = 2987 + INTEGER(IntKi), PARAMETER :: M8N9MMGzi = 2988 + INTEGER(IntKi), PARAMETER :: M9N1MMGzi = 2989 + INTEGER(IntKi), PARAMETER :: M9N2MMGzi = 2990 + INTEGER(IntKi), PARAMETER :: M9N3MMGzi = 2991 + INTEGER(IntKi), PARAMETER :: M9N4MMGzi = 2992 + INTEGER(IntKi), PARAMETER :: M9N5MMGzi = 2993 + INTEGER(IntKi), PARAMETER :: M9N6MMGzi = 2994 + INTEGER(IntKi), PARAMETER :: M9N7MMGzi = 2995 + INTEGER(IntKi), PARAMETER :: M9N8MMGzi = 2996 + INTEGER(IntKi), PARAMETER :: M9N9MMGzi = 2997 + INTEGER(IntKi), PARAMETER :: M1N1FAMxi = 2998 + INTEGER(IntKi), PARAMETER :: M1N2FAMxi = 2999 + INTEGER(IntKi), PARAMETER :: M1N3FAMxi = 3000 + INTEGER(IntKi), PARAMETER :: M1N4FAMxi = 3001 + INTEGER(IntKi), PARAMETER :: M1N5FAMxi = 3002 + INTEGER(IntKi), PARAMETER :: M1N6FAMxi = 3003 + INTEGER(IntKi), PARAMETER :: M1N7FAMxi = 3004 + INTEGER(IntKi), PARAMETER :: M1N8FAMxi = 3005 + INTEGER(IntKi), PARAMETER :: M1N9FAMxi = 3006 + INTEGER(IntKi), PARAMETER :: M2N1FAMxi = 3007 + INTEGER(IntKi), PARAMETER :: M2N2FAMxi = 3008 + INTEGER(IntKi), PARAMETER :: M2N3FAMxi = 3009 + INTEGER(IntKi), PARAMETER :: M2N4FAMxi = 3010 + INTEGER(IntKi), PARAMETER :: M2N5FAMxi = 3011 + INTEGER(IntKi), PARAMETER :: M2N6FAMxi = 3012 + INTEGER(IntKi), PARAMETER :: M2N7FAMxi = 3013 + INTEGER(IntKi), PARAMETER :: M2N8FAMxi = 3014 + INTEGER(IntKi), PARAMETER :: M2N9FAMxi = 3015 + INTEGER(IntKi), PARAMETER :: M3N1FAMxi = 3016 + INTEGER(IntKi), PARAMETER :: M3N2FAMxi = 3017 + INTEGER(IntKi), PARAMETER :: M3N3FAMxi = 3018 + INTEGER(IntKi), PARAMETER :: M3N4FAMxi = 3019 + INTEGER(IntKi), PARAMETER :: M3N5FAMxi = 3020 + INTEGER(IntKi), PARAMETER :: M3N6FAMxi = 3021 + INTEGER(IntKi), PARAMETER :: M3N7FAMxi = 3022 + INTEGER(IntKi), PARAMETER :: M3N8FAMxi = 3023 + INTEGER(IntKi), PARAMETER :: M3N9FAMxi = 3024 + INTEGER(IntKi), PARAMETER :: M4N1FAMxi = 3025 + INTEGER(IntKi), PARAMETER :: M4N2FAMxi = 3026 + INTEGER(IntKi), PARAMETER :: M4N3FAMxi = 3027 + INTEGER(IntKi), PARAMETER :: M4N4FAMxi = 3028 + INTEGER(IntKi), PARAMETER :: M4N5FAMxi = 3029 + INTEGER(IntKi), PARAMETER :: M4N6FAMxi = 3030 + INTEGER(IntKi), PARAMETER :: M4N7FAMxi = 3031 + INTEGER(IntKi), PARAMETER :: M4N8FAMxi = 3032 + INTEGER(IntKi), PARAMETER :: M4N9FAMxi = 3033 + INTEGER(IntKi), PARAMETER :: M5N1FAMxi = 3034 + INTEGER(IntKi), PARAMETER :: M5N2FAMxi = 3035 + INTEGER(IntKi), PARAMETER :: M5N3FAMxi = 3036 + INTEGER(IntKi), PARAMETER :: M5N4FAMxi = 3037 + INTEGER(IntKi), PARAMETER :: M5N5FAMxi = 3038 + INTEGER(IntKi), PARAMETER :: M5N6FAMxi = 3039 + INTEGER(IntKi), PARAMETER :: M5N7FAMxi = 3040 + INTEGER(IntKi), PARAMETER :: M5N8FAMxi = 3041 + INTEGER(IntKi), PARAMETER :: M5N9FAMxi = 3042 + INTEGER(IntKi), PARAMETER :: M6N1FAMxi = 3043 + INTEGER(IntKi), PARAMETER :: M6N2FAMxi = 3044 + INTEGER(IntKi), PARAMETER :: M6N3FAMxi = 3045 + INTEGER(IntKi), PARAMETER :: M6N4FAMxi = 3046 + INTEGER(IntKi), PARAMETER :: M6N5FAMxi = 3047 + INTEGER(IntKi), PARAMETER :: M6N6FAMxi = 3048 + INTEGER(IntKi), PARAMETER :: M6N7FAMxi = 3049 + INTEGER(IntKi), PARAMETER :: M6N8FAMxi = 3050 + INTEGER(IntKi), PARAMETER :: M6N9FAMxi = 3051 + INTEGER(IntKi), PARAMETER :: M7N1FAMxi = 3052 + INTEGER(IntKi), PARAMETER :: M7N2FAMxi = 3053 + INTEGER(IntKi), PARAMETER :: M7N3FAMxi = 3054 + INTEGER(IntKi), PARAMETER :: M7N4FAMxi = 3055 + INTEGER(IntKi), PARAMETER :: M7N5FAMxi = 3056 + INTEGER(IntKi), PARAMETER :: M7N6FAMxi = 3057 + INTEGER(IntKi), PARAMETER :: M7N7FAMxi = 3058 + INTEGER(IntKi), PARAMETER :: M7N8FAMxi = 3059 + INTEGER(IntKi), PARAMETER :: M7N9FAMxi = 3060 + INTEGER(IntKi), PARAMETER :: M8N1FAMxi = 3061 + INTEGER(IntKi), PARAMETER :: M8N2FAMxi = 3062 + INTEGER(IntKi), PARAMETER :: M8N3FAMxi = 3063 + INTEGER(IntKi), PARAMETER :: M8N4FAMxi = 3064 + INTEGER(IntKi), PARAMETER :: M8N5FAMxi = 3065 + INTEGER(IntKi), PARAMETER :: M8N6FAMxi = 3066 + INTEGER(IntKi), PARAMETER :: M8N7FAMxi = 3067 + INTEGER(IntKi), PARAMETER :: M8N8FAMxi = 3068 + INTEGER(IntKi), PARAMETER :: M8N9FAMxi = 3069 + INTEGER(IntKi), PARAMETER :: M9N1FAMxi = 3070 + INTEGER(IntKi), PARAMETER :: M9N2FAMxi = 3071 + INTEGER(IntKi), PARAMETER :: M9N3FAMxi = 3072 + INTEGER(IntKi), PARAMETER :: M9N4FAMxi = 3073 + INTEGER(IntKi), PARAMETER :: M9N5FAMxi = 3074 + INTEGER(IntKi), PARAMETER :: M9N6FAMxi = 3075 + INTEGER(IntKi), PARAMETER :: M9N7FAMxi = 3076 + INTEGER(IntKi), PARAMETER :: M9N8FAMxi = 3077 + INTEGER(IntKi), PARAMETER :: M9N9FAMxi = 3078 + INTEGER(IntKi), PARAMETER :: M1N1FAMyi = 3079 + INTEGER(IntKi), PARAMETER :: M1N2FAMyi = 3080 + INTEGER(IntKi), PARAMETER :: M1N3FAMyi = 3081 + INTEGER(IntKi), PARAMETER :: M1N4FAMyi = 3082 + INTEGER(IntKi), PARAMETER :: M1N5FAMyi = 3083 + INTEGER(IntKi), PARAMETER :: M1N6FAMyi = 3084 + INTEGER(IntKi), PARAMETER :: M1N7FAMyi = 3085 + INTEGER(IntKi), PARAMETER :: M1N8FAMyi = 3086 + INTEGER(IntKi), PARAMETER :: M1N9FAMyi = 3087 + INTEGER(IntKi), PARAMETER :: M2N1FAMyi = 3088 + INTEGER(IntKi), PARAMETER :: M2N2FAMyi = 3089 + INTEGER(IntKi), PARAMETER :: M2N3FAMyi = 3090 + INTEGER(IntKi), PARAMETER :: M2N4FAMyi = 3091 + INTEGER(IntKi), PARAMETER :: M2N5FAMyi = 3092 + INTEGER(IntKi), PARAMETER :: M2N6FAMyi = 3093 + INTEGER(IntKi), PARAMETER :: M2N7FAMyi = 3094 + INTEGER(IntKi), PARAMETER :: M2N8FAMyi = 3095 + INTEGER(IntKi), PARAMETER :: M2N9FAMyi = 3096 + INTEGER(IntKi), PARAMETER :: M3N1FAMyi = 3097 + INTEGER(IntKi), PARAMETER :: M3N2FAMyi = 3098 + INTEGER(IntKi), PARAMETER :: M3N3FAMyi = 3099 + INTEGER(IntKi), PARAMETER :: M3N4FAMyi = 3100 + INTEGER(IntKi), PARAMETER :: M3N5FAMyi = 3101 + INTEGER(IntKi), PARAMETER :: M3N6FAMyi = 3102 + INTEGER(IntKi), PARAMETER :: M3N7FAMyi = 3103 + INTEGER(IntKi), PARAMETER :: M3N8FAMyi = 3104 + INTEGER(IntKi), PARAMETER :: M3N9FAMyi = 3105 + INTEGER(IntKi), PARAMETER :: M4N1FAMyi = 3106 + INTEGER(IntKi), PARAMETER :: M4N2FAMyi = 3107 + INTEGER(IntKi), PARAMETER :: M4N3FAMyi = 3108 + INTEGER(IntKi), PARAMETER :: M4N4FAMyi = 3109 + INTEGER(IntKi), PARAMETER :: M4N5FAMyi = 3110 + INTEGER(IntKi), PARAMETER :: M4N6FAMyi = 3111 + INTEGER(IntKi), PARAMETER :: M4N7FAMyi = 3112 + INTEGER(IntKi), PARAMETER :: M4N8FAMyi = 3113 + INTEGER(IntKi), PARAMETER :: M4N9FAMyi = 3114 + INTEGER(IntKi), PARAMETER :: M5N1FAMyi = 3115 + INTEGER(IntKi), PARAMETER :: M5N2FAMyi = 3116 + INTEGER(IntKi), PARAMETER :: M5N3FAMyi = 3117 + INTEGER(IntKi), PARAMETER :: M5N4FAMyi = 3118 + INTEGER(IntKi), PARAMETER :: M5N5FAMyi = 3119 + INTEGER(IntKi), PARAMETER :: M5N6FAMyi = 3120 + INTEGER(IntKi), PARAMETER :: M5N7FAMyi = 3121 + INTEGER(IntKi), PARAMETER :: M5N8FAMyi = 3122 + INTEGER(IntKi), PARAMETER :: M5N9FAMyi = 3123 + INTEGER(IntKi), PARAMETER :: M6N1FAMyi = 3124 + INTEGER(IntKi), PARAMETER :: M6N2FAMyi = 3125 + INTEGER(IntKi), PARAMETER :: M6N3FAMyi = 3126 + INTEGER(IntKi), PARAMETER :: M6N4FAMyi = 3127 + INTEGER(IntKi), PARAMETER :: M6N5FAMyi = 3128 + INTEGER(IntKi), PARAMETER :: M6N6FAMyi = 3129 + INTEGER(IntKi), PARAMETER :: M6N7FAMyi = 3130 + INTEGER(IntKi), PARAMETER :: M6N8FAMyi = 3131 + INTEGER(IntKi), PARAMETER :: M6N9FAMyi = 3132 + INTEGER(IntKi), PARAMETER :: M7N1FAMyi = 3133 + INTEGER(IntKi), PARAMETER :: M7N2FAMyi = 3134 + INTEGER(IntKi), PARAMETER :: M7N3FAMyi = 3135 + INTEGER(IntKi), PARAMETER :: M7N4FAMyi = 3136 + INTEGER(IntKi), PARAMETER :: M7N5FAMyi = 3137 + INTEGER(IntKi), PARAMETER :: M7N6FAMyi = 3138 + INTEGER(IntKi), PARAMETER :: M7N7FAMyi = 3139 + INTEGER(IntKi), PARAMETER :: M7N8FAMyi = 3140 + INTEGER(IntKi), PARAMETER :: M7N9FAMyi = 3141 + INTEGER(IntKi), PARAMETER :: M8N1FAMyi = 3142 + INTEGER(IntKi), PARAMETER :: M8N2FAMyi = 3143 + INTEGER(IntKi), PARAMETER :: M8N3FAMyi = 3144 + INTEGER(IntKi), PARAMETER :: M8N4FAMyi = 3145 + INTEGER(IntKi), PARAMETER :: M8N5FAMyi = 3146 + INTEGER(IntKi), PARAMETER :: M8N6FAMyi = 3147 + INTEGER(IntKi), PARAMETER :: M8N7FAMyi = 3148 + INTEGER(IntKi), PARAMETER :: M8N8FAMyi = 3149 + INTEGER(IntKi), PARAMETER :: M8N9FAMyi = 3150 + INTEGER(IntKi), PARAMETER :: M9N1FAMyi = 3151 + INTEGER(IntKi), PARAMETER :: M9N2FAMyi = 3152 + INTEGER(IntKi), PARAMETER :: M9N3FAMyi = 3153 + INTEGER(IntKi), PARAMETER :: M9N4FAMyi = 3154 + INTEGER(IntKi), PARAMETER :: M9N5FAMyi = 3155 + INTEGER(IntKi), PARAMETER :: M9N6FAMyi = 3156 + INTEGER(IntKi), PARAMETER :: M9N7FAMyi = 3157 + INTEGER(IntKi), PARAMETER :: M9N8FAMyi = 3158 + INTEGER(IntKi), PARAMETER :: M9N9FAMyi = 3159 + INTEGER(IntKi), PARAMETER :: M1N1FAMzi = 3160 + INTEGER(IntKi), PARAMETER :: M1N2FAMzi = 3161 + INTEGER(IntKi), PARAMETER :: M1N3FAMzi = 3162 + INTEGER(IntKi), PARAMETER :: M1N4FAMzi = 3163 + INTEGER(IntKi), PARAMETER :: M1N5FAMzi = 3164 + INTEGER(IntKi), PARAMETER :: M1N6FAMzi = 3165 + INTEGER(IntKi), PARAMETER :: M1N7FAMzi = 3166 + INTEGER(IntKi), PARAMETER :: M1N8FAMzi = 3167 + INTEGER(IntKi), PARAMETER :: M1N9FAMzi = 3168 + INTEGER(IntKi), PARAMETER :: M2N1FAMzi = 3169 + INTEGER(IntKi), PARAMETER :: M2N2FAMzi = 3170 + INTEGER(IntKi), PARAMETER :: M2N3FAMzi = 3171 + INTEGER(IntKi), PARAMETER :: M2N4FAMzi = 3172 + INTEGER(IntKi), PARAMETER :: M2N5FAMzi = 3173 + INTEGER(IntKi), PARAMETER :: M2N6FAMzi = 3174 + INTEGER(IntKi), PARAMETER :: M2N7FAMzi = 3175 + INTEGER(IntKi), PARAMETER :: M2N8FAMzi = 3176 + INTEGER(IntKi), PARAMETER :: M2N9FAMzi = 3177 + INTEGER(IntKi), PARAMETER :: M3N1FAMzi = 3178 + INTEGER(IntKi), PARAMETER :: M3N2FAMzi = 3179 + INTEGER(IntKi), PARAMETER :: M3N3FAMzi = 3180 + INTEGER(IntKi), PARAMETER :: M3N4FAMzi = 3181 + INTEGER(IntKi), PARAMETER :: M3N5FAMzi = 3182 + INTEGER(IntKi), PARAMETER :: M3N6FAMzi = 3183 + INTEGER(IntKi), PARAMETER :: M3N7FAMzi = 3184 + INTEGER(IntKi), PARAMETER :: M3N8FAMzi = 3185 + INTEGER(IntKi), PARAMETER :: M3N9FAMzi = 3186 + INTEGER(IntKi), PARAMETER :: M4N1FAMzi = 3187 + INTEGER(IntKi), PARAMETER :: M4N2FAMzi = 3188 + INTEGER(IntKi), PARAMETER :: M4N3FAMzi = 3189 + INTEGER(IntKi), PARAMETER :: M4N4FAMzi = 3190 + INTEGER(IntKi), PARAMETER :: M4N5FAMzi = 3191 + INTEGER(IntKi), PARAMETER :: M4N6FAMzi = 3192 + INTEGER(IntKi), PARAMETER :: M4N7FAMzi = 3193 + INTEGER(IntKi), PARAMETER :: M4N8FAMzi = 3194 + INTEGER(IntKi), PARAMETER :: M4N9FAMzi = 3195 + INTEGER(IntKi), PARAMETER :: M5N1FAMzi = 3196 + INTEGER(IntKi), PARAMETER :: M5N2FAMzi = 3197 + INTEGER(IntKi), PARAMETER :: M5N3FAMzi = 3198 + INTEGER(IntKi), PARAMETER :: M5N4FAMzi = 3199 + INTEGER(IntKi), PARAMETER :: M5N5FAMzi = 3200 + INTEGER(IntKi), PARAMETER :: M5N6FAMzi = 3201 + INTEGER(IntKi), PARAMETER :: M5N7FAMzi = 3202 + INTEGER(IntKi), PARAMETER :: M5N8FAMzi = 3203 + INTEGER(IntKi), PARAMETER :: M5N9FAMzi = 3204 + INTEGER(IntKi), PARAMETER :: M6N1FAMzi = 3205 + INTEGER(IntKi), PARAMETER :: M6N2FAMzi = 3206 + INTEGER(IntKi), PARAMETER :: M6N3FAMzi = 3207 + INTEGER(IntKi), PARAMETER :: M6N4FAMzi = 3208 + INTEGER(IntKi), PARAMETER :: M6N5FAMzi = 3209 + INTEGER(IntKi), PARAMETER :: M6N6FAMzi = 3210 + INTEGER(IntKi), PARAMETER :: M6N7FAMzi = 3211 + INTEGER(IntKi), PARAMETER :: M6N8FAMzi = 3212 + INTEGER(IntKi), PARAMETER :: M6N9FAMzi = 3213 + INTEGER(IntKi), PARAMETER :: M7N1FAMzi = 3214 + INTEGER(IntKi), PARAMETER :: M7N2FAMzi = 3215 + INTEGER(IntKi), PARAMETER :: M7N3FAMzi = 3216 + INTEGER(IntKi), PARAMETER :: M7N4FAMzi = 3217 + INTEGER(IntKi), PARAMETER :: M7N5FAMzi = 3218 + INTEGER(IntKi), PARAMETER :: M7N6FAMzi = 3219 + INTEGER(IntKi), PARAMETER :: M7N7FAMzi = 3220 + INTEGER(IntKi), PARAMETER :: M7N8FAMzi = 3221 + INTEGER(IntKi), PARAMETER :: M7N9FAMzi = 3222 + INTEGER(IntKi), PARAMETER :: M8N1FAMzi = 3223 + INTEGER(IntKi), PARAMETER :: M8N2FAMzi = 3224 + INTEGER(IntKi), PARAMETER :: M8N3FAMzi = 3225 + INTEGER(IntKi), PARAMETER :: M8N4FAMzi = 3226 + INTEGER(IntKi), PARAMETER :: M8N5FAMzi = 3227 + INTEGER(IntKi), PARAMETER :: M8N6FAMzi = 3228 + INTEGER(IntKi), PARAMETER :: M8N7FAMzi = 3229 + INTEGER(IntKi), PARAMETER :: M8N8FAMzi = 3230 + INTEGER(IntKi), PARAMETER :: M8N9FAMzi = 3231 + INTEGER(IntKi), PARAMETER :: M9N1FAMzi = 3232 + INTEGER(IntKi), PARAMETER :: M9N2FAMzi = 3233 + INTEGER(IntKi), PARAMETER :: M9N3FAMzi = 3234 + INTEGER(IntKi), PARAMETER :: M9N4FAMzi = 3235 + INTEGER(IntKi), PARAMETER :: M9N5FAMzi = 3236 + INTEGER(IntKi), PARAMETER :: M9N6FAMzi = 3237 + INTEGER(IntKi), PARAMETER :: M9N7FAMzi = 3238 + INTEGER(IntKi), PARAMETER :: M9N8FAMzi = 3239 + INTEGER(IntKi), PARAMETER :: M9N9FAMzi = 3240 + INTEGER(IntKi), PARAMETER :: M1N1FAGxi = 3241 + INTEGER(IntKi), PARAMETER :: M1N2FAGxi = 3242 + INTEGER(IntKi), PARAMETER :: M1N3FAGxi = 3243 + INTEGER(IntKi), PARAMETER :: M1N4FAGxi = 3244 + INTEGER(IntKi), PARAMETER :: M1N5FAGxi = 3245 + INTEGER(IntKi), PARAMETER :: M1N6FAGxi = 3246 + INTEGER(IntKi), PARAMETER :: M1N7FAGxi = 3247 + INTEGER(IntKi), PARAMETER :: M1N8FAGxi = 3248 + INTEGER(IntKi), PARAMETER :: M1N9FAGxi = 3249 + INTEGER(IntKi), PARAMETER :: M2N1FAGxi = 3250 + INTEGER(IntKi), PARAMETER :: M2N2FAGxi = 3251 + INTEGER(IntKi), PARAMETER :: M2N3FAGxi = 3252 + INTEGER(IntKi), PARAMETER :: M2N4FAGxi = 3253 + INTEGER(IntKi), PARAMETER :: M2N5FAGxi = 3254 + INTEGER(IntKi), PARAMETER :: M2N6FAGxi = 3255 + INTEGER(IntKi), PARAMETER :: M2N7FAGxi = 3256 + INTEGER(IntKi), PARAMETER :: M2N8FAGxi = 3257 + INTEGER(IntKi), PARAMETER :: M2N9FAGxi = 3258 + INTEGER(IntKi), PARAMETER :: M3N1FAGxi = 3259 + INTEGER(IntKi), PARAMETER :: M3N2FAGxi = 3260 + INTEGER(IntKi), PARAMETER :: M3N3FAGxi = 3261 + INTEGER(IntKi), PARAMETER :: M3N4FAGxi = 3262 + INTEGER(IntKi), PARAMETER :: M3N5FAGxi = 3263 + INTEGER(IntKi), PARAMETER :: M3N6FAGxi = 3264 + INTEGER(IntKi), PARAMETER :: M3N7FAGxi = 3265 + INTEGER(IntKi), PARAMETER :: M3N8FAGxi = 3266 + INTEGER(IntKi), PARAMETER :: M3N9FAGxi = 3267 + INTEGER(IntKi), PARAMETER :: M4N1FAGxi = 3268 + INTEGER(IntKi), PARAMETER :: M4N2FAGxi = 3269 + INTEGER(IntKi), PARAMETER :: M4N3FAGxi = 3270 + INTEGER(IntKi), PARAMETER :: M4N4FAGxi = 3271 + INTEGER(IntKi), PARAMETER :: M4N5FAGxi = 3272 + INTEGER(IntKi), PARAMETER :: M4N6FAGxi = 3273 + INTEGER(IntKi), PARAMETER :: M4N7FAGxi = 3274 + INTEGER(IntKi), PARAMETER :: M4N8FAGxi = 3275 + INTEGER(IntKi), PARAMETER :: M4N9FAGxi = 3276 + INTEGER(IntKi), PARAMETER :: M5N1FAGxi = 3277 + INTEGER(IntKi), PARAMETER :: M5N2FAGxi = 3278 + INTEGER(IntKi), PARAMETER :: M5N3FAGxi = 3279 + INTEGER(IntKi), PARAMETER :: M5N4FAGxi = 3280 + INTEGER(IntKi), PARAMETER :: M5N5FAGxi = 3281 + INTEGER(IntKi), PARAMETER :: M5N6FAGxi = 3282 + INTEGER(IntKi), PARAMETER :: M5N7FAGxi = 3283 + INTEGER(IntKi), PARAMETER :: M5N8FAGxi = 3284 + INTEGER(IntKi), PARAMETER :: M5N9FAGxi = 3285 + INTEGER(IntKi), PARAMETER :: M6N1FAGxi = 3286 + INTEGER(IntKi), PARAMETER :: M6N2FAGxi = 3287 + INTEGER(IntKi), PARAMETER :: M6N3FAGxi = 3288 + INTEGER(IntKi), PARAMETER :: M6N4FAGxi = 3289 + INTEGER(IntKi), PARAMETER :: M6N5FAGxi = 3290 + INTEGER(IntKi), PARAMETER :: M6N6FAGxi = 3291 + INTEGER(IntKi), PARAMETER :: M6N7FAGxi = 3292 + INTEGER(IntKi), PARAMETER :: M6N8FAGxi = 3293 + INTEGER(IntKi), PARAMETER :: M6N9FAGxi = 3294 + INTEGER(IntKi), PARAMETER :: M7N1FAGxi = 3295 + INTEGER(IntKi), PARAMETER :: M7N2FAGxi = 3296 + INTEGER(IntKi), PARAMETER :: M7N3FAGxi = 3297 + INTEGER(IntKi), PARAMETER :: M7N4FAGxi = 3298 + INTEGER(IntKi), PARAMETER :: M7N5FAGxi = 3299 + INTEGER(IntKi), PARAMETER :: M7N6FAGxi = 3300 + INTEGER(IntKi), PARAMETER :: M7N7FAGxi = 3301 + INTEGER(IntKi), PARAMETER :: M7N8FAGxi = 3302 + INTEGER(IntKi), PARAMETER :: M7N9FAGxi = 3303 + INTEGER(IntKi), PARAMETER :: M8N1FAGxi = 3304 + INTEGER(IntKi), PARAMETER :: M8N2FAGxi = 3305 + INTEGER(IntKi), PARAMETER :: M8N3FAGxi = 3306 + INTEGER(IntKi), PARAMETER :: M8N4FAGxi = 3307 + INTEGER(IntKi), PARAMETER :: M8N5FAGxi = 3308 + INTEGER(IntKi), PARAMETER :: M8N6FAGxi = 3309 + INTEGER(IntKi), PARAMETER :: M8N7FAGxi = 3310 + INTEGER(IntKi), PARAMETER :: M8N8FAGxi = 3311 + INTEGER(IntKi), PARAMETER :: M8N9FAGxi = 3312 + INTEGER(IntKi), PARAMETER :: M9N1FAGxi = 3313 + INTEGER(IntKi), PARAMETER :: M9N2FAGxi = 3314 + INTEGER(IntKi), PARAMETER :: M9N3FAGxi = 3315 + INTEGER(IntKi), PARAMETER :: M9N4FAGxi = 3316 + INTEGER(IntKi), PARAMETER :: M9N5FAGxi = 3317 + INTEGER(IntKi), PARAMETER :: M9N6FAGxi = 3318 + INTEGER(IntKi), PARAMETER :: M9N7FAGxi = 3319 + INTEGER(IntKi), PARAMETER :: M9N8FAGxi = 3320 + INTEGER(IntKi), PARAMETER :: M9N9FAGxi = 3321 + INTEGER(IntKi), PARAMETER :: M1N1FAGyi = 3322 + INTEGER(IntKi), PARAMETER :: M1N2FAGyi = 3323 + INTEGER(IntKi), PARAMETER :: M1N3FAGyi = 3324 + INTEGER(IntKi), PARAMETER :: M1N4FAGyi = 3325 + INTEGER(IntKi), PARAMETER :: M1N5FAGyi = 3326 + INTEGER(IntKi), PARAMETER :: M1N6FAGyi = 3327 + INTEGER(IntKi), PARAMETER :: M1N7FAGyi = 3328 + INTEGER(IntKi), PARAMETER :: M1N8FAGyi = 3329 + INTEGER(IntKi), PARAMETER :: M1N9FAGyi = 3330 + INTEGER(IntKi), PARAMETER :: M2N1FAGyi = 3331 + INTEGER(IntKi), PARAMETER :: M2N2FAGyi = 3332 + INTEGER(IntKi), PARAMETER :: M2N3FAGyi = 3333 + INTEGER(IntKi), PARAMETER :: M2N4FAGyi = 3334 + INTEGER(IntKi), PARAMETER :: M2N5FAGyi = 3335 + INTEGER(IntKi), PARAMETER :: M2N6FAGyi = 3336 + INTEGER(IntKi), PARAMETER :: M2N7FAGyi = 3337 + INTEGER(IntKi), PARAMETER :: M2N8FAGyi = 3338 + INTEGER(IntKi), PARAMETER :: M2N9FAGyi = 3339 + INTEGER(IntKi), PARAMETER :: M3N1FAGyi = 3340 + INTEGER(IntKi), PARAMETER :: M3N2FAGyi = 3341 + INTEGER(IntKi), PARAMETER :: M3N3FAGyi = 3342 + INTEGER(IntKi), PARAMETER :: M3N4FAGyi = 3343 + INTEGER(IntKi), PARAMETER :: M3N5FAGyi = 3344 + INTEGER(IntKi), PARAMETER :: M3N6FAGyi = 3345 + INTEGER(IntKi), PARAMETER :: M3N7FAGyi = 3346 + INTEGER(IntKi), PARAMETER :: M3N8FAGyi = 3347 + INTEGER(IntKi), PARAMETER :: M3N9FAGyi = 3348 + INTEGER(IntKi), PARAMETER :: M4N1FAGyi = 3349 + INTEGER(IntKi), PARAMETER :: M4N2FAGyi = 3350 + INTEGER(IntKi), PARAMETER :: M4N3FAGyi = 3351 + INTEGER(IntKi), PARAMETER :: M4N4FAGyi = 3352 + INTEGER(IntKi), PARAMETER :: M4N5FAGyi = 3353 + INTEGER(IntKi), PARAMETER :: M4N6FAGyi = 3354 + INTEGER(IntKi), PARAMETER :: M4N7FAGyi = 3355 + INTEGER(IntKi), PARAMETER :: M4N8FAGyi = 3356 + INTEGER(IntKi), PARAMETER :: M4N9FAGyi = 3357 + INTEGER(IntKi), PARAMETER :: M5N1FAGyi = 3358 + INTEGER(IntKi), PARAMETER :: M5N2FAGyi = 3359 + INTEGER(IntKi), PARAMETER :: M5N3FAGyi = 3360 + INTEGER(IntKi), PARAMETER :: M5N4FAGyi = 3361 + INTEGER(IntKi), PARAMETER :: M5N5FAGyi = 3362 + INTEGER(IntKi), PARAMETER :: M5N6FAGyi = 3363 + INTEGER(IntKi), PARAMETER :: M5N7FAGyi = 3364 + INTEGER(IntKi), PARAMETER :: M5N8FAGyi = 3365 + INTEGER(IntKi), PARAMETER :: M5N9FAGyi = 3366 + INTEGER(IntKi), PARAMETER :: M6N1FAGyi = 3367 + INTEGER(IntKi), PARAMETER :: M6N2FAGyi = 3368 + INTEGER(IntKi), PARAMETER :: M6N3FAGyi = 3369 + INTEGER(IntKi), PARAMETER :: M6N4FAGyi = 3370 + INTEGER(IntKi), PARAMETER :: M6N5FAGyi = 3371 + INTEGER(IntKi), PARAMETER :: M6N6FAGyi = 3372 + INTEGER(IntKi), PARAMETER :: M6N7FAGyi = 3373 + INTEGER(IntKi), PARAMETER :: M6N8FAGyi = 3374 + INTEGER(IntKi), PARAMETER :: M6N9FAGyi = 3375 + INTEGER(IntKi), PARAMETER :: M7N1FAGyi = 3376 + INTEGER(IntKi), PARAMETER :: M7N2FAGyi = 3377 + INTEGER(IntKi), PARAMETER :: M7N3FAGyi = 3378 + INTEGER(IntKi), PARAMETER :: M7N4FAGyi = 3379 + INTEGER(IntKi), PARAMETER :: M7N5FAGyi = 3380 + INTEGER(IntKi), PARAMETER :: M7N6FAGyi = 3381 + INTEGER(IntKi), PARAMETER :: M7N7FAGyi = 3382 + INTEGER(IntKi), PARAMETER :: M7N8FAGyi = 3383 + INTEGER(IntKi), PARAMETER :: M7N9FAGyi = 3384 + INTEGER(IntKi), PARAMETER :: M8N1FAGyi = 3385 + INTEGER(IntKi), PARAMETER :: M8N2FAGyi = 3386 + INTEGER(IntKi), PARAMETER :: M8N3FAGyi = 3387 + INTEGER(IntKi), PARAMETER :: M8N4FAGyi = 3388 + INTEGER(IntKi), PARAMETER :: M8N5FAGyi = 3389 + INTEGER(IntKi), PARAMETER :: M8N6FAGyi = 3390 + INTEGER(IntKi), PARAMETER :: M8N7FAGyi = 3391 + INTEGER(IntKi), PARAMETER :: M8N8FAGyi = 3392 + INTEGER(IntKi), PARAMETER :: M8N9FAGyi = 3393 + INTEGER(IntKi), PARAMETER :: M9N1FAGyi = 3394 + INTEGER(IntKi), PARAMETER :: M9N2FAGyi = 3395 + INTEGER(IntKi), PARAMETER :: M9N3FAGyi = 3396 + INTEGER(IntKi), PARAMETER :: M9N4FAGyi = 3397 + INTEGER(IntKi), PARAMETER :: M9N5FAGyi = 3398 + INTEGER(IntKi), PARAMETER :: M9N6FAGyi = 3399 + INTEGER(IntKi), PARAMETER :: M9N7FAGyi = 3400 + INTEGER(IntKi), PARAMETER :: M9N8FAGyi = 3401 + INTEGER(IntKi), PARAMETER :: M9N9FAGyi = 3402 + INTEGER(IntKi), PARAMETER :: M1N1FAGzi = 3403 + INTEGER(IntKi), PARAMETER :: M1N2FAGzi = 3404 + INTEGER(IntKi), PARAMETER :: M1N3FAGzi = 3405 + INTEGER(IntKi), PARAMETER :: M1N4FAGzi = 3406 + INTEGER(IntKi), PARAMETER :: M1N5FAGzi = 3407 + INTEGER(IntKi), PARAMETER :: M1N6FAGzi = 3408 + INTEGER(IntKi), PARAMETER :: M1N7FAGzi = 3409 + INTEGER(IntKi), PARAMETER :: M1N8FAGzi = 3410 + INTEGER(IntKi), PARAMETER :: M1N9FAGzi = 3411 + INTEGER(IntKi), PARAMETER :: M2N1FAGzi = 3412 + INTEGER(IntKi), PARAMETER :: M2N2FAGzi = 3413 + INTEGER(IntKi), PARAMETER :: M2N3FAGzi = 3414 + INTEGER(IntKi), PARAMETER :: M2N4FAGzi = 3415 + INTEGER(IntKi), PARAMETER :: M2N5FAGzi = 3416 + INTEGER(IntKi), PARAMETER :: M2N6FAGzi = 3417 + INTEGER(IntKi), PARAMETER :: M2N7FAGzi = 3418 + INTEGER(IntKi), PARAMETER :: M2N8FAGzi = 3419 + INTEGER(IntKi), PARAMETER :: M2N9FAGzi = 3420 + INTEGER(IntKi), PARAMETER :: M3N1FAGzi = 3421 + INTEGER(IntKi), PARAMETER :: M3N2FAGzi = 3422 + INTEGER(IntKi), PARAMETER :: M3N3FAGzi = 3423 + INTEGER(IntKi), PARAMETER :: M3N4FAGzi = 3424 + INTEGER(IntKi), PARAMETER :: M3N5FAGzi = 3425 + INTEGER(IntKi), PARAMETER :: M3N6FAGzi = 3426 + INTEGER(IntKi), PARAMETER :: M3N7FAGzi = 3427 + INTEGER(IntKi), PARAMETER :: M3N8FAGzi = 3428 + INTEGER(IntKi), PARAMETER :: M3N9FAGzi = 3429 + INTEGER(IntKi), PARAMETER :: M4N1FAGzi = 3430 + INTEGER(IntKi), PARAMETER :: M4N2FAGzi = 3431 + INTEGER(IntKi), PARAMETER :: M4N3FAGzi = 3432 + INTEGER(IntKi), PARAMETER :: M4N4FAGzi = 3433 + INTEGER(IntKi), PARAMETER :: M4N5FAGzi = 3434 + INTEGER(IntKi), PARAMETER :: M4N6FAGzi = 3435 + INTEGER(IntKi), PARAMETER :: M4N7FAGzi = 3436 + INTEGER(IntKi), PARAMETER :: M4N8FAGzi = 3437 + INTEGER(IntKi), PARAMETER :: M4N9FAGzi = 3438 + INTEGER(IntKi), PARAMETER :: M5N1FAGzi = 3439 + INTEGER(IntKi), PARAMETER :: M5N2FAGzi = 3440 + INTEGER(IntKi), PARAMETER :: M5N3FAGzi = 3441 + INTEGER(IntKi), PARAMETER :: M5N4FAGzi = 3442 + INTEGER(IntKi), PARAMETER :: M5N5FAGzi = 3443 + INTEGER(IntKi), PARAMETER :: M5N6FAGzi = 3444 + INTEGER(IntKi), PARAMETER :: M5N7FAGzi = 3445 + INTEGER(IntKi), PARAMETER :: M5N8FAGzi = 3446 + INTEGER(IntKi), PARAMETER :: M5N9FAGzi = 3447 + INTEGER(IntKi), PARAMETER :: M6N1FAGzi = 3448 + INTEGER(IntKi), PARAMETER :: M6N2FAGzi = 3449 + INTEGER(IntKi), PARAMETER :: M6N3FAGzi = 3450 + INTEGER(IntKi), PARAMETER :: M6N4FAGzi = 3451 + INTEGER(IntKi), PARAMETER :: M6N5FAGzi = 3452 + INTEGER(IntKi), PARAMETER :: M6N6FAGzi = 3453 + INTEGER(IntKi), PARAMETER :: M6N7FAGzi = 3454 + INTEGER(IntKi), PARAMETER :: M6N8FAGzi = 3455 + INTEGER(IntKi), PARAMETER :: M6N9FAGzi = 3456 + INTEGER(IntKi), PARAMETER :: M7N1FAGzi = 3457 + INTEGER(IntKi), PARAMETER :: M7N2FAGzi = 3458 + INTEGER(IntKi), PARAMETER :: M7N3FAGzi = 3459 + INTEGER(IntKi), PARAMETER :: M7N4FAGzi = 3460 + INTEGER(IntKi), PARAMETER :: M7N5FAGzi = 3461 + INTEGER(IntKi), PARAMETER :: M7N6FAGzi = 3462 + INTEGER(IntKi), PARAMETER :: M7N7FAGzi = 3463 + INTEGER(IntKi), PARAMETER :: M7N8FAGzi = 3464 + INTEGER(IntKi), PARAMETER :: M7N9FAGzi = 3465 + INTEGER(IntKi), PARAMETER :: M8N1FAGzi = 3466 + INTEGER(IntKi), PARAMETER :: M8N2FAGzi = 3467 + INTEGER(IntKi), PARAMETER :: M8N3FAGzi = 3468 + INTEGER(IntKi), PARAMETER :: M8N4FAGzi = 3469 + INTEGER(IntKi), PARAMETER :: M8N5FAGzi = 3470 + INTEGER(IntKi), PARAMETER :: M8N6FAGzi = 3471 + INTEGER(IntKi), PARAMETER :: M8N7FAGzi = 3472 + INTEGER(IntKi), PARAMETER :: M8N8FAGzi = 3473 + INTEGER(IntKi), PARAMETER :: M8N9FAGzi = 3474 + INTEGER(IntKi), PARAMETER :: M9N1FAGzi = 3475 + INTEGER(IntKi), PARAMETER :: M9N2FAGzi = 3476 + INTEGER(IntKi), PARAMETER :: M9N3FAGzi = 3477 + INTEGER(IntKi), PARAMETER :: M9N4FAGzi = 3478 + INTEGER(IntKi), PARAMETER :: M9N5FAGzi = 3479 + INTEGER(IntKi), PARAMETER :: M9N6FAGzi = 3480 + INTEGER(IntKi), PARAMETER :: M9N7FAGzi = 3481 + INTEGER(IntKi), PARAMETER :: M9N8FAGzi = 3482 + INTEGER(IntKi), PARAMETER :: M9N9FAGzi = 3483 + INTEGER(IntKi), PARAMETER :: M1N1MAGxi = 3484 + INTEGER(IntKi), PARAMETER :: M1N2MAGxi = 3485 + INTEGER(IntKi), PARAMETER :: M1N3MAGxi = 3486 + INTEGER(IntKi), PARAMETER :: M1N4MAGxi = 3487 + INTEGER(IntKi), PARAMETER :: M1N5MAGxi = 3488 + INTEGER(IntKi), PARAMETER :: M1N6MAGxi = 3489 + INTEGER(IntKi), PARAMETER :: M1N7MAGxi = 3490 + INTEGER(IntKi), PARAMETER :: M1N8MAGxi = 3491 + INTEGER(IntKi), PARAMETER :: M1N9MAGxi = 3492 + INTEGER(IntKi), PARAMETER :: M2N1MAGxi = 3493 + INTEGER(IntKi), PARAMETER :: M2N2MAGxi = 3494 + INTEGER(IntKi), PARAMETER :: M2N3MAGxi = 3495 + INTEGER(IntKi), PARAMETER :: M2N4MAGxi = 3496 + INTEGER(IntKi), PARAMETER :: M2N5MAGxi = 3497 + INTEGER(IntKi), PARAMETER :: M2N6MAGxi = 3498 + INTEGER(IntKi), PARAMETER :: M2N7MAGxi = 3499 + INTEGER(IntKi), PARAMETER :: M2N8MAGxi = 3500 + INTEGER(IntKi), PARAMETER :: M2N9MAGxi = 3501 + INTEGER(IntKi), PARAMETER :: M3N1MAGxi = 3502 + INTEGER(IntKi), PARAMETER :: M3N2MAGxi = 3503 + INTEGER(IntKi), PARAMETER :: M3N3MAGxi = 3504 + INTEGER(IntKi), PARAMETER :: M3N4MAGxi = 3505 + INTEGER(IntKi), PARAMETER :: M3N5MAGxi = 3506 + INTEGER(IntKi), PARAMETER :: M3N6MAGxi = 3507 + INTEGER(IntKi), PARAMETER :: M3N7MAGxi = 3508 + INTEGER(IntKi), PARAMETER :: M3N8MAGxi = 3509 + INTEGER(IntKi), PARAMETER :: M3N9MAGxi = 3510 + INTEGER(IntKi), PARAMETER :: M4N1MAGxi = 3511 + INTEGER(IntKi), PARAMETER :: M4N2MAGxi = 3512 + INTEGER(IntKi), PARAMETER :: M4N3MAGxi = 3513 + INTEGER(IntKi), PARAMETER :: M4N4MAGxi = 3514 + INTEGER(IntKi), PARAMETER :: M4N5MAGxi = 3515 + INTEGER(IntKi), PARAMETER :: M4N6MAGxi = 3516 + INTEGER(IntKi), PARAMETER :: M4N7MAGxi = 3517 + INTEGER(IntKi), PARAMETER :: M4N8MAGxi = 3518 + INTEGER(IntKi), PARAMETER :: M4N9MAGxi = 3519 + INTEGER(IntKi), PARAMETER :: M5N1MAGxi = 3520 + INTEGER(IntKi), PARAMETER :: M5N2MAGxi = 3521 + INTEGER(IntKi), PARAMETER :: M5N3MAGxi = 3522 + INTEGER(IntKi), PARAMETER :: M5N4MAGxi = 3523 + INTEGER(IntKi), PARAMETER :: M5N5MAGxi = 3524 + INTEGER(IntKi), PARAMETER :: M5N6MAGxi = 3525 + INTEGER(IntKi), PARAMETER :: M5N7MAGxi = 3526 + INTEGER(IntKi), PARAMETER :: M5N8MAGxi = 3527 + INTEGER(IntKi), PARAMETER :: M5N9MAGxi = 3528 + INTEGER(IntKi), PARAMETER :: M6N1MAGxi = 3529 + INTEGER(IntKi), PARAMETER :: M6N2MAGxi = 3530 + INTEGER(IntKi), PARAMETER :: M6N3MAGxi = 3531 + INTEGER(IntKi), PARAMETER :: M6N4MAGxi = 3532 + INTEGER(IntKi), PARAMETER :: M6N5MAGxi = 3533 + INTEGER(IntKi), PARAMETER :: M6N6MAGxi = 3534 + INTEGER(IntKi), PARAMETER :: M6N7MAGxi = 3535 + INTEGER(IntKi), PARAMETER :: M6N8MAGxi = 3536 + INTEGER(IntKi), PARAMETER :: M6N9MAGxi = 3537 + INTEGER(IntKi), PARAMETER :: M7N1MAGxi = 3538 + INTEGER(IntKi), PARAMETER :: M7N2MAGxi = 3539 + INTEGER(IntKi), PARAMETER :: M7N3MAGxi = 3540 + INTEGER(IntKi), PARAMETER :: M7N4MAGxi = 3541 + INTEGER(IntKi), PARAMETER :: M7N5MAGxi = 3542 + INTEGER(IntKi), PARAMETER :: M7N6MAGxi = 3543 + INTEGER(IntKi), PARAMETER :: M7N7MAGxi = 3544 + INTEGER(IntKi), PARAMETER :: M7N8MAGxi = 3545 + INTEGER(IntKi), PARAMETER :: M7N9MAGxi = 3546 + INTEGER(IntKi), PARAMETER :: M8N1MAGxi = 3547 + INTEGER(IntKi), PARAMETER :: M8N2MAGxi = 3548 + INTEGER(IntKi), PARAMETER :: M8N3MAGxi = 3549 + INTEGER(IntKi), PARAMETER :: M8N4MAGxi = 3550 + INTEGER(IntKi), PARAMETER :: M8N5MAGxi = 3551 + INTEGER(IntKi), PARAMETER :: M8N6MAGxi = 3552 + INTEGER(IntKi), PARAMETER :: M8N7MAGxi = 3553 + INTEGER(IntKi), PARAMETER :: M8N8MAGxi = 3554 + INTEGER(IntKi), PARAMETER :: M8N9MAGxi = 3555 + INTEGER(IntKi), PARAMETER :: M9N1MAGxi = 3556 + INTEGER(IntKi), PARAMETER :: M9N2MAGxi = 3557 + INTEGER(IntKi), PARAMETER :: M9N3MAGxi = 3558 + INTEGER(IntKi), PARAMETER :: M9N4MAGxi = 3559 + INTEGER(IntKi), PARAMETER :: M9N5MAGxi = 3560 + INTEGER(IntKi), PARAMETER :: M9N6MAGxi = 3561 + INTEGER(IntKi), PARAMETER :: M9N7MAGxi = 3562 + INTEGER(IntKi), PARAMETER :: M9N8MAGxi = 3563 + INTEGER(IntKi), PARAMETER :: M9N9MAGxi = 3564 + INTEGER(IntKi), PARAMETER :: M1N1MAGyi = 3565 + INTEGER(IntKi), PARAMETER :: M1N2MAGyi = 3566 + INTEGER(IntKi), PARAMETER :: M1N3MAGyi = 3567 + INTEGER(IntKi), PARAMETER :: M1N4MAGyi = 3568 + INTEGER(IntKi), PARAMETER :: M1N5MAGyi = 3569 + INTEGER(IntKi), PARAMETER :: M1N6MAGyi = 3570 + INTEGER(IntKi), PARAMETER :: M1N7MAGyi = 3571 + INTEGER(IntKi), PARAMETER :: M1N8MAGyi = 3572 + INTEGER(IntKi), PARAMETER :: M1N9MAGyi = 3573 + INTEGER(IntKi), PARAMETER :: M2N1MAGyi = 3574 + INTEGER(IntKi), PARAMETER :: M2N2MAGyi = 3575 + INTEGER(IntKi), PARAMETER :: M2N3MAGyi = 3576 + INTEGER(IntKi), PARAMETER :: M2N4MAGyi = 3577 + INTEGER(IntKi), PARAMETER :: M2N5MAGyi = 3578 + INTEGER(IntKi), PARAMETER :: M2N6MAGyi = 3579 + INTEGER(IntKi), PARAMETER :: M2N7MAGyi = 3580 + INTEGER(IntKi), PARAMETER :: M2N8MAGyi = 3581 + INTEGER(IntKi), PARAMETER :: M2N9MAGyi = 3582 + INTEGER(IntKi), PARAMETER :: M3N1MAGyi = 3583 + INTEGER(IntKi), PARAMETER :: M3N2MAGyi = 3584 + INTEGER(IntKi), PARAMETER :: M3N3MAGyi = 3585 + INTEGER(IntKi), PARAMETER :: M3N4MAGyi = 3586 + INTEGER(IntKi), PARAMETER :: M3N5MAGyi = 3587 + INTEGER(IntKi), PARAMETER :: M3N6MAGyi = 3588 + INTEGER(IntKi), PARAMETER :: M3N7MAGyi = 3589 + INTEGER(IntKi), PARAMETER :: M3N8MAGyi = 3590 + INTEGER(IntKi), PARAMETER :: M3N9MAGyi = 3591 + INTEGER(IntKi), PARAMETER :: M4N1MAGyi = 3592 + INTEGER(IntKi), PARAMETER :: M4N2MAGyi = 3593 + INTEGER(IntKi), PARAMETER :: M4N3MAGyi = 3594 + INTEGER(IntKi), PARAMETER :: M4N4MAGyi = 3595 + INTEGER(IntKi), PARAMETER :: M4N5MAGyi = 3596 + INTEGER(IntKi), PARAMETER :: M4N6MAGyi = 3597 + INTEGER(IntKi), PARAMETER :: M4N7MAGyi = 3598 + INTEGER(IntKi), PARAMETER :: M4N8MAGyi = 3599 + INTEGER(IntKi), PARAMETER :: M4N9MAGyi = 3600 + INTEGER(IntKi), PARAMETER :: M5N1MAGyi = 3601 + INTEGER(IntKi), PARAMETER :: M5N2MAGyi = 3602 + INTEGER(IntKi), PARAMETER :: M5N3MAGyi = 3603 + INTEGER(IntKi), PARAMETER :: M5N4MAGyi = 3604 + INTEGER(IntKi), PARAMETER :: M5N5MAGyi = 3605 + INTEGER(IntKi), PARAMETER :: M5N6MAGyi = 3606 + INTEGER(IntKi), PARAMETER :: M5N7MAGyi = 3607 + INTEGER(IntKi), PARAMETER :: M5N8MAGyi = 3608 + INTEGER(IntKi), PARAMETER :: M5N9MAGyi = 3609 + INTEGER(IntKi), PARAMETER :: M6N1MAGyi = 3610 + INTEGER(IntKi), PARAMETER :: M6N2MAGyi = 3611 + INTEGER(IntKi), PARAMETER :: M6N3MAGyi = 3612 + INTEGER(IntKi), PARAMETER :: M6N4MAGyi = 3613 + INTEGER(IntKi), PARAMETER :: M6N5MAGyi = 3614 + INTEGER(IntKi), PARAMETER :: M6N6MAGyi = 3615 + INTEGER(IntKi), PARAMETER :: M6N7MAGyi = 3616 + INTEGER(IntKi), PARAMETER :: M6N8MAGyi = 3617 + INTEGER(IntKi), PARAMETER :: M6N9MAGyi = 3618 + INTEGER(IntKi), PARAMETER :: M7N1MAGyi = 3619 + INTEGER(IntKi), PARAMETER :: M7N2MAGyi = 3620 + INTEGER(IntKi), PARAMETER :: M7N3MAGyi = 3621 + INTEGER(IntKi), PARAMETER :: M7N4MAGyi = 3622 + INTEGER(IntKi), PARAMETER :: M7N5MAGyi = 3623 + INTEGER(IntKi), PARAMETER :: M7N6MAGyi = 3624 + INTEGER(IntKi), PARAMETER :: M7N7MAGyi = 3625 + INTEGER(IntKi), PARAMETER :: M7N8MAGyi = 3626 + INTEGER(IntKi), PARAMETER :: M7N9MAGyi = 3627 + INTEGER(IntKi), PARAMETER :: M8N1MAGyi = 3628 + INTEGER(IntKi), PARAMETER :: M8N2MAGyi = 3629 + INTEGER(IntKi), PARAMETER :: M8N3MAGyi = 3630 + INTEGER(IntKi), PARAMETER :: M8N4MAGyi = 3631 + INTEGER(IntKi), PARAMETER :: M8N5MAGyi = 3632 + INTEGER(IntKi), PARAMETER :: M8N6MAGyi = 3633 + INTEGER(IntKi), PARAMETER :: M8N7MAGyi = 3634 + INTEGER(IntKi), PARAMETER :: M8N8MAGyi = 3635 + INTEGER(IntKi), PARAMETER :: M8N9MAGyi = 3636 + INTEGER(IntKi), PARAMETER :: M9N1MAGyi = 3637 + INTEGER(IntKi), PARAMETER :: M9N2MAGyi = 3638 + INTEGER(IntKi), PARAMETER :: M9N3MAGyi = 3639 + INTEGER(IntKi), PARAMETER :: M9N4MAGyi = 3640 + INTEGER(IntKi), PARAMETER :: M9N5MAGyi = 3641 + INTEGER(IntKi), PARAMETER :: M9N6MAGyi = 3642 + INTEGER(IntKi), PARAMETER :: M9N7MAGyi = 3643 + INTEGER(IntKi), PARAMETER :: M9N8MAGyi = 3644 + INTEGER(IntKi), PARAMETER :: M9N9MAGyi = 3645 + INTEGER(IntKi), PARAMETER :: M1N1MAGzi = 3646 + INTEGER(IntKi), PARAMETER :: M1N2MAGzi = 3647 + INTEGER(IntKi), PARAMETER :: M1N3MAGzi = 3648 + INTEGER(IntKi), PARAMETER :: M1N4MAGzi = 3649 + INTEGER(IntKi), PARAMETER :: M1N5MAGzi = 3650 + INTEGER(IntKi), PARAMETER :: M1N6MAGzi = 3651 + INTEGER(IntKi), PARAMETER :: M1N7MAGzi = 3652 + INTEGER(IntKi), PARAMETER :: M1N8MAGzi = 3653 + INTEGER(IntKi), PARAMETER :: M1N9MAGzi = 3654 + INTEGER(IntKi), PARAMETER :: M2N1MAGzi = 3655 + INTEGER(IntKi), PARAMETER :: M2N2MAGzi = 3656 + INTEGER(IntKi), PARAMETER :: M2N3MAGzi = 3657 + INTEGER(IntKi), PARAMETER :: M2N4MAGzi = 3658 + INTEGER(IntKi), PARAMETER :: M2N5MAGzi = 3659 + INTEGER(IntKi), PARAMETER :: M2N6MAGzi = 3660 + INTEGER(IntKi), PARAMETER :: M2N7MAGzi = 3661 + INTEGER(IntKi), PARAMETER :: M2N8MAGzi = 3662 + INTEGER(IntKi), PARAMETER :: M2N9MAGzi = 3663 + INTEGER(IntKi), PARAMETER :: M3N1MAGzi = 3664 + INTEGER(IntKi), PARAMETER :: M3N2MAGzi = 3665 + INTEGER(IntKi), PARAMETER :: M3N3MAGzi = 3666 + INTEGER(IntKi), PARAMETER :: M3N4MAGzi = 3667 + INTEGER(IntKi), PARAMETER :: M3N5MAGzi = 3668 + INTEGER(IntKi), PARAMETER :: M3N6MAGzi = 3669 + INTEGER(IntKi), PARAMETER :: M3N7MAGzi = 3670 + INTEGER(IntKi), PARAMETER :: M3N8MAGzi = 3671 + INTEGER(IntKi), PARAMETER :: M3N9MAGzi = 3672 + INTEGER(IntKi), PARAMETER :: M4N1MAGzi = 3673 + INTEGER(IntKi), PARAMETER :: M4N2MAGzi = 3674 + INTEGER(IntKi), PARAMETER :: M4N3MAGzi = 3675 + INTEGER(IntKi), PARAMETER :: M4N4MAGzi = 3676 + INTEGER(IntKi), PARAMETER :: M4N5MAGzi = 3677 + INTEGER(IntKi), PARAMETER :: M4N6MAGzi = 3678 + INTEGER(IntKi), PARAMETER :: M4N7MAGzi = 3679 + INTEGER(IntKi), PARAMETER :: M4N8MAGzi = 3680 + INTEGER(IntKi), PARAMETER :: M4N9MAGzi = 3681 + INTEGER(IntKi), PARAMETER :: M5N1MAGzi = 3682 + INTEGER(IntKi), PARAMETER :: M5N2MAGzi = 3683 + INTEGER(IntKi), PARAMETER :: M5N3MAGzi = 3684 + INTEGER(IntKi), PARAMETER :: M5N4MAGzi = 3685 + INTEGER(IntKi), PARAMETER :: M5N5MAGzi = 3686 + INTEGER(IntKi), PARAMETER :: M5N6MAGzi = 3687 + INTEGER(IntKi), PARAMETER :: M5N7MAGzi = 3688 + INTEGER(IntKi), PARAMETER :: M5N8MAGzi = 3689 + INTEGER(IntKi), PARAMETER :: M5N9MAGzi = 3690 + INTEGER(IntKi), PARAMETER :: M6N1MAGzi = 3691 + INTEGER(IntKi), PARAMETER :: M6N2MAGzi = 3692 + INTEGER(IntKi), PARAMETER :: M6N3MAGzi = 3693 + INTEGER(IntKi), PARAMETER :: M6N4MAGzi = 3694 + INTEGER(IntKi), PARAMETER :: M6N5MAGzi = 3695 + INTEGER(IntKi), PARAMETER :: M6N6MAGzi = 3696 + INTEGER(IntKi), PARAMETER :: M6N7MAGzi = 3697 + INTEGER(IntKi), PARAMETER :: M6N8MAGzi = 3698 + INTEGER(IntKi), PARAMETER :: M6N9MAGzi = 3699 + INTEGER(IntKi), PARAMETER :: M7N1MAGzi = 3700 + INTEGER(IntKi), PARAMETER :: M7N2MAGzi = 3701 + INTEGER(IntKi), PARAMETER :: M7N3MAGzi = 3702 + INTEGER(IntKi), PARAMETER :: M7N4MAGzi = 3703 + INTEGER(IntKi), PARAMETER :: M7N5MAGzi = 3704 + INTEGER(IntKi), PARAMETER :: M7N6MAGzi = 3705 + INTEGER(IntKi), PARAMETER :: M7N7MAGzi = 3706 + INTEGER(IntKi), PARAMETER :: M7N8MAGzi = 3707 + INTEGER(IntKi), PARAMETER :: M7N9MAGzi = 3708 + INTEGER(IntKi), PARAMETER :: M8N1MAGzi = 3709 + INTEGER(IntKi), PARAMETER :: M8N2MAGzi = 3710 + INTEGER(IntKi), PARAMETER :: M8N3MAGzi = 3711 + INTEGER(IntKi), PARAMETER :: M8N4MAGzi = 3712 + INTEGER(IntKi), PARAMETER :: M8N5MAGzi = 3713 + INTEGER(IntKi), PARAMETER :: M8N6MAGzi = 3714 + INTEGER(IntKi), PARAMETER :: M8N7MAGzi = 3715 + INTEGER(IntKi), PARAMETER :: M8N8MAGzi = 3716 + INTEGER(IntKi), PARAMETER :: M8N9MAGzi = 3717 + INTEGER(IntKi), PARAMETER :: M9N1MAGzi = 3718 + INTEGER(IntKi), PARAMETER :: M9N2MAGzi = 3719 + INTEGER(IntKi), PARAMETER :: M9N3MAGzi = 3720 + INTEGER(IntKi), PARAMETER :: M9N4MAGzi = 3721 + INTEGER(IntKi), PARAMETER :: M9N5MAGzi = 3722 + INTEGER(IntKi), PARAMETER :: M9N6MAGzi = 3723 + INTEGER(IntKi), PARAMETER :: M9N7MAGzi = 3724 + INTEGER(IntKi), PARAMETER :: M9N8MAGzi = 3725 + INTEGER(IntKi), PARAMETER :: M9N9MAGzi = 3726 + INTEGER(IntKi), PARAMETER :: M1N1FAFxi = 3727 + INTEGER(IntKi), PARAMETER :: M1N2FAFxi = 3728 + INTEGER(IntKi), PARAMETER :: M1N3FAFxi = 3729 + INTEGER(IntKi), PARAMETER :: M1N4FAFxi = 3730 + INTEGER(IntKi), PARAMETER :: M1N5FAFxi = 3731 + INTEGER(IntKi), PARAMETER :: M1N6FAFxi = 3732 + INTEGER(IntKi), PARAMETER :: M1N7FAFxi = 3733 + INTEGER(IntKi), PARAMETER :: M1N8FAFxi = 3734 + INTEGER(IntKi), PARAMETER :: M1N9FAFxi = 3735 + INTEGER(IntKi), PARAMETER :: M2N1FAFxi = 3736 + INTEGER(IntKi), PARAMETER :: M2N2FAFxi = 3737 + INTEGER(IntKi), PARAMETER :: M2N3FAFxi = 3738 + INTEGER(IntKi), PARAMETER :: M2N4FAFxi = 3739 + INTEGER(IntKi), PARAMETER :: M2N5FAFxi = 3740 + INTEGER(IntKi), PARAMETER :: M2N6FAFxi = 3741 + INTEGER(IntKi), PARAMETER :: M2N7FAFxi = 3742 + INTEGER(IntKi), PARAMETER :: M2N8FAFxi = 3743 + INTEGER(IntKi), PARAMETER :: M2N9FAFxi = 3744 + INTEGER(IntKi), PARAMETER :: M3N1FAFxi = 3745 + INTEGER(IntKi), PARAMETER :: M3N2FAFxi = 3746 + INTEGER(IntKi), PARAMETER :: M3N3FAFxi = 3747 + INTEGER(IntKi), PARAMETER :: M3N4FAFxi = 3748 + INTEGER(IntKi), PARAMETER :: M3N5FAFxi = 3749 + INTEGER(IntKi), PARAMETER :: M3N6FAFxi = 3750 + INTEGER(IntKi), PARAMETER :: M3N7FAFxi = 3751 + INTEGER(IntKi), PARAMETER :: M3N8FAFxi = 3752 + INTEGER(IntKi), PARAMETER :: M3N9FAFxi = 3753 + INTEGER(IntKi), PARAMETER :: M4N1FAFxi = 3754 + INTEGER(IntKi), PARAMETER :: M4N2FAFxi = 3755 + INTEGER(IntKi), PARAMETER :: M4N3FAFxi = 3756 + INTEGER(IntKi), PARAMETER :: M4N4FAFxi = 3757 + INTEGER(IntKi), PARAMETER :: M4N5FAFxi = 3758 + INTEGER(IntKi), PARAMETER :: M4N6FAFxi = 3759 + INTEGER(IntKi), PARAMETER :: M4N7FAFxi = 3760 + INTEGER(IntKi), PARAMETER :: M4N8FAFxi = 3761 + INTEGER(IntKi), PARAMETER :: M4N9FAFxi = 3762 + INTEGER(IntKi), PARAMETER :: M5N1FAFxi = 3763 + INTEGER(IntKi), PARAMETER :: M5N2FAFxi = 3764 + INTEGER(IntKi), PARAMETER :: M5N3FAFxi = 3765 + INTEGER(IntKi), PARAMETER :: M5N4FAFxi = 3766 + INTEGER(IntKi), PARAMETER :: M5N5FAFxi = 3767 + INTEGER(IntKi), PARAMETER :: M5N6FAFxi = 3768 + INTEGER(IntKi), PARAMETER :: M5N7FAFxi = 3769 + INTEGER(IntKi), PARAMETER :: M5N8FAFxi = 3770 + INTEGER(IntKi), PARAMETER :: M5N9FAFxi = 3771 + INTEGER(IntKi), PARAMETER :: M6N1FAFxi = 3772 + INTEGER(IntKi), PARAMETER :: M6N2FAFxi = 3773 + INTEGER(IntKi), PARAMETER :: M6N3FAFxi = 3774 + INTEGER(IntKi), PARAMETER :: M6N4FAFxi = 3775 + INTEGER(IntKi), PARAMETER :: M6N5FAFxi = 3776 + INTEGER(IntKi), PARAMETER :: M6N6FAFxi = 3777 + INTEGER(IntKi), PARAMETER :: M6N7FAFxi = 3778 + INTEGER(IntKi), PARAMETER :: M6N8FAFxi = 3779 + INTEGER(IntKi), PARAMETER :: M6N9FAFxi = 3780 + INTEGER(IntKi), PARAMETER :: M7N1FAFxi = 3781 + INTEGER(IntKi), PARAMETER :: M7N2FAFxi = 3782 + INTEGER(IntKi), PARAMETER :: M7N3FAFxi = 3783 + INTEGER(IntKi), PARAMETER :: M7N4FAFxi = 3784 + INTEGER(IntKi), PARAMETER :: M7N5FAFxi = 3785 + INTEGER(IntKi), PARAMETER :: M7N6FAFxi = 3786 + INTEGER(IntKi), PARAMETER :: M7N7FAFxi = 3787 + INTEGER(IntKi), PARAMETER :: M7N8FAFxi = 3788 + INTEGER(IntKi), PARAMETER :: M7N9FAFxi = 3789 + INTEGER(IntKi), PARAMETER :: M8N1FAFxi = 3790 + INTEGER(IntKi), PARAMETER :: M8N2FAFxi = 3791 + INTEGER(IntKi), PARAMETER :: M8N3FAFxi = 3792 + INTEGER(IntKi), PARAMETER :: M8N4FAFxi = 3793 + INTEGER(IntKi), PARAMETER :: M8N5FAFxi = 3794 + INTEGER(IntKi), PARAMETER :: M8N6FAFxi = 3795 + INTEGER(IntKi), PARAMETER :: M8N7FAFxi = 3796 + INTEGER(IntKi), PARAMETER :: M8N8FAFxi = 3797 + INTEGER(IntKi), PARAMETER :: M8N9FAFxi = 3798 + INTEGER(IntKi), PARAMETER :: M9N1FAFxi = 3799 + INTEGER(IntKi), PARAMETER :: M9N2FAFxi = 3800 + INTEGER(IntKi), PARAMETER :: M9N3FAFxi = 3801 + INTEGER(IntKi), PARAMETER :: M9N4FAFxi = 3802 + INTEGER(IntKi), PARAMETER :: M9N5FAFxi = 3803 + INTEGER(IntKi), PARAMETER :: M9N6FAFxi = 3804 + INTEGER(IntKi), PARAMETER :: M9N7FAFxi = 3805 + INTEGER(IntKi), PARAMETER :: M9N8FAFxi = 3806 + INTEGER(IntKi), PARAMETER :: M9N9FAFxi = 3807 + INTEGER(IntKi), PARAMETER :: M1N1FAFyi = 3808 + INTEGER(IntKi), PARAMETER :: M1N2FAFyi = 3809 + INTEGER(IntKi), PARAMETER :: M1N3FAFyi = 3810 + INTEGER(IntKi), PARAMETER :: M1N4FAFyi = 3811 + INTEGER(IntKi), PARAMETER :: M1N5FAFyi = 3812 + INTEGER(IntKi), PARAMETER :: M1N6FAFyi = 3813 + INTEGER(IntKi), PARAMETER :: M1N7FAFyi = 3814 + INTEGER(IntKi), PARAMETER :: M1N8FAFyi = 3815 + INTEGER(IntKi), PARAMETER :: M1N9FAFyi = 3816 + INTEGER(IntKi), PARAMETER :: M2N1FAFyi = 3817 + INTEGER(IntKi), PARAMETER :: M2N2FAFyi = 3818 + INTEGER(IntKi), PARAMETER :: M2N3FAFyi = 3819 + INTEGER(IntKi), PARAMETER :: M2N4FAFyi = 3820 + INTEGER(IntKi), PARAMETER :: M2N5FAFyi = 3821 + INTEGER(IntKi), PARAMETER :: M2N6FAFyi = 3822 + INTEGER(IntKi), PARAMETER :: M2N7FAFyi = 3823 + INTEGER(IntKi), PARAMETER :: M2N8FAFyi = 3824 + INTEGER(IntKi), PARAMETER :: M2N9FAFyi = 3825 + INTEGER(IntKi), PARAMETER :: M3N1FAFyi = 3826 + INTEGER(IntKi), PARAMETER :: M3N2FAFyi = 3827 + INTEGER(IntKi), PARAMETER :: M3N3FAFyi = 3828 + INTEGER(IntKi), PARAMETER :: M3N4FAFyi = 3829 + INTEGER(IntKi), PARAMETER :: M3N5FAFyi = 3830 + INTEGER(IntKi), PARAMETER :: M3N6FAFyi = 3831 + INTEGER(IntKi), PARAMETER :: M3N7FAFyi = 3832 + INTEGER(IntKi), PARAMETER :: M3N8FAFyi = 3833 + INTEGER(IntKi), PARAMETER :: M3N9FAFyi = 3834 + INTEGER(IntKi), PARAMETER :: M4N1FAFyi = 3835 + INTEGER(IntKi), PARAMETER :: M4N2FAFyi = 3836 + INTEGER(IntKi), PARAMETER :: M4N3FAFyi = 3837 + INTEGER(IntKi), PARAMETER :: M4N4FAFyi = 3838 + INTEGER(IntKi), PARAMETER :: M4N5FAFyi = 3839 + INTEGER(IntKi), PARAMETER :: M4N6FAFyi = 3840 + INTEGER(IntKi), PARAMETER :: M4N7FAFyi = 3841 + INTEGER(IntKi), PARAMETER :: M4N8FAFyi = 3842 + INTEGER(IntKi), PARAMETER :: M4N9FAFyi = 3843 + INTEGER(IntKi), PARAMETER :: M5N1FAFyi = 3844 + INTEGER(IntKi), PARAMETER :: M5N2FAFyi = 3845 + INTEGER(IntKi), PARAMETER :: M5N3FAFyi = 3846 + INTEGER(IntKi), PARAMETER :: M5N4FAFyi = 3847 + INTEGER(IntKi), PARAMETER :: M5N5FAFyi = 3848 + INTEGER(IntKi), PARAMETER :: M5N6FAFyi = 3849 + INTEGER(IntKi), PARAMETER :: M5N7FAFyi = 3850 + INTEGER(IntKi), PARAMETER :: M5N8FAFyi = 3851 + INTEGER(IntKi), PARAMETER :: M5N9FAFyi = 3852 + INTEGER(IntKi), PARAMETER :: M6N1FAFyi = 3853 + INTEGER(IntKi), PARAMETER :: M6N2FAFyi = 3854 + INTEGER(IntKi), PARAMETER :: M6N3FAFyi = 3855 + INTEGER(IntKi), PARAMETER :: M6N4FAFyi = 3856 + INTEGER(IntKi), PARAMETER :: M6N5FAFyi = 3857 + INTEGER(IntKi), PARAMETER :: M6N6FAFyi = 3858 + INTEGER(IntKi), PARAMETER :: M6N7FAFyi = 3859 + INTEGER(IntKi), PARAMETER :: M6N8FAFyi = 3860 + INTEGER(IntKi), PARAMETER :: M6N9FAFyi = 3861 + INTEGER(IntKi), PARAMETER :: M7N1FAFyi = 3862 + INTEGER(IntKi), PARAMETER :: M7N2FAFyi = 3863 + INTEGER(IntKi), PARAMETER :: M7N3FAFyi = 3864 + INTEGER(IntKi), PARAMETER :: M7N4FAFyi = 3865 + INTEGER(IntKi), PARAMETER :: M7N5FAFyi = 3866 + INTEGER(IntKi), PARAMETER :: M7N6FAFyi = 3867 + INTEGER(IntKi), PARAMETER :: M7N7FAFyi = 3868 + INTEGER(IntKi), PARAMETER :: M7N8FAFyi = 3869 + INTEGER(IntKi), PARAMETER :: M7N9FAFyi = 3870 + INTEGER(IntKi), PARAMETER :: M8N1FAFyi = 3871 + INTEGER(IntKi), PARAMETER :: M8N2FAFyi = 3872 + INTEGER(IntKi), PARAMETER :: M8N3FAFyi = 3873 + INTEGER(IntKi), PARAMETER :: M8N4FAFyi = 3874 + INTEGER(IntKi), PARAMETER :: M8N5FAFyi = 3875 + INTEGER(IntKi), PARAMETER :: M8N6FAFyi = 3876 + INTEGER(IntKi), PARAMETER :: M8N7FAFyi = 3877 + INTEGER(IntKi), PARAMETER :: M8N8FAFyi = 3878 + INTEGER(IntKi), PARAMETER :: M8N9FAFyi = 3879 + INTEGER(IntKi), PARAMETER :: M9N1FAFyi = 3880 + INTEGER(IntKi), PARAMETER :: M9N2FAFyi = 3881 + INTEGER(IntKi), PARAMETER :: M9N3FAFyi = 3882 + INTEGER(IntKi), PARAMETER :: M9N4FAFyi = 3883 + INTEGER(IntKi), PARAMETER :: M9N5FAFyi = 3884 + INTEGER(IntKi), PARAMETER :: M9N6FAFyi = 3885 + INTEGER(IntKi), PARAMETER :: M9N7FAFyi = 3886 + INTEGER(IntKi), PARAMETER :: M9N8FAFyi = 3887 + INTEGER(IntKi), PARAMETER :: M9N9FAFyi = 3888 + INTEGER(IntKi), PARAMETER :: M1N1FAFzi = 3889 + INTEGER(IntKi), PARAMETER :: M1N2FAFzi = 3890 + INTEGER(IntKi), PARAMETER :: M1N3FAFzi = 3891 + INTEGER(IntKi), PARAMETER :: M1N4FAFzi = 3892 + INTEGER(IntKi), PARAMETER :: M1N5FAFzi = 3893 + INTEGER(IntKi), PARAMETER :: M1N6FAFzi = 3894 + INTEGER(IntKi), PARAMETER :: M1N7FAFzi = 3895 + INTEGER(IntKi), PARAMETER :: M1N8FAFzi = 3896 + INTEGER(IntKi), PARAMETER :: M1N9FAFzi = 3897 + INTEGER(IntKi), PARAMETER :: M2N1FAFzi = 3898 + INTEGER(IntKi), PARAMETER :: M2N2FAFzi = 3899 + INTEGER(IntKi), PARAMETER :: M2N3FAFzi = 3900 + INTEGER(IntKi), PARAMETER :: M2N4FAFzi = 3901 + INTEGER(IntKi), PARAMETER :: M2N5FAFzi = 3902 + INTEGER(IntKi), PARAMETER :: M2N6FAFzi = 3903 + INTEGER(IntKi), PARAMETER :: M2N7FAFzi = 3904 + INTEGER(IntKi), PARAMETER :: M2N8FAFzi = 3905 + INTEGER(IntKi), PARAMETER :: M2N9FAFzi = 3906 + INTEGER(IntKi), PARAMETER :: M3N1FAFzi = 3907 + INTEGER(IntKi), PARAMETER :: M3N2FAFzi = 3908 + INTEGER(IntKi), PARAMETER :: M3N3FAFzi = 3909 + INTEGER(IntKi), PARAMETER :: M3N4FAFzi = 3910 + INTEGER(IntKi), PARAMETER :: M3N5FAFzi = 3911 + INTEGER(IntKi), PARAMETER :: M3N6FAFzi = 3912 + INTEGER(IntKi), PARAMETER :: M3N7FAFzi = 3913 + INTEGER(IntKi), PARAMETER :: M3N8FAFzi = 3914 + INTEGER(IntKi), PARAMETER :: M3N9FAFzi = 3915 + INTEGER(IntKi), PARAMETER :: M4N1FAFzi = 3916 + INTEGER(IntKi), PARAMETER :: M4N2FAFzi = 3917 + INTEGER(IntKi), PARAMETER :: M4N3FAFzi = 3918 + INTEGER(IntKi), PARAMETER :: M4N4FAFzi = 3919 + INTEGER(IntKi), PARAMETER :: M4N5FAFzi = 3920 + INTEGER(IntKi), PARAMETER :: M4N6FAFzi = 3921 + INTEGER(IntKi), PARAMETER :: M4N7FAFzi = 3922 + INTEGER(IntKi), PARAMETER :: M4N8FAFzi = 3923 + INTEGER(IntKi), PARAMETER :: M4N9FAFzi = 3924 + INTEGER(IntKi), PARAMETER :: M5N1FAFzi = 3925 + INTEGER(IntKi), PARAMETER :: M5N2FAFzi = 3926 + INTEGER(IntKi), PARAMETER :: M5N3FAFzi = 3927 + INTEGER(IntKi), PARAMETER :: M5N4FAFzi = 3928 + INTEGER(IntKi), PARAMETER :: M5N5FAFzi = 3929 + INTEGER(IntKi), PARAMETER :: M5N6FAFzi = 3930 + INTEGER(IntKi), PARAMETER :: M5N7FAFzi = 3931 + INTEGER(IntKi), PARAMETER :: M5N8FAFzi = 3932 + INTEGER(IntKi), PARAMETER :: M5N9FAFzi = 3933 + INTEGER(IntKi), PARAMETER :: M6N1FAFzi = 3934 + INTEGER(IntKi), PARAMETER :: M6N2FAFzi = 3935 + INTEGER(IntKi), PARAMETER :: M6N3FAFzi = 3936 + INTEGER(IntKi), PARAMETER :: M6N4FAFzi = 3937 + INTEGER(IntKi), PARAMETER :: M6N5FAFzi = 3938 + INTEGER(IntKi), PARAMETER :: M6N6FAFzi = 3939 + INTEGER(IntKi), PARAMETER :: M6N7FAFzi = 3940 + INTEGER(IntKi), PARAMETER :: M6N8FAFzi = 3941 + INTEGER(IntKi), PARAMETER :: M6N9FAFzi = 3942 + INTEGER(IntKi), PARAMETER :: M7N1FAFzi = 3943 + INTEGER(IntKi), PARAMETER :: M7N2FAFzi = 3944 + INTEGER(IntKi), PARAMETER :: M7N3FAFzi = 3945 + INTEGER(IntKi), PARAMETER :: M7N4FAFzi = 3946 + INTEGER(IntKi), PARAMETER :: M7N5FAFzi = 3947 + INTEGER(IntKi), PARAMETER :: M7N6FAFzi = 3948 + INTEGER(IntKi), PARAMETER :: M7N7FAFzi = 3949 + INTEGER(IntKi), PARAMETER :: M7N8FAFzi = 3950 + INTEGER(IntKi), PARAMETER :: M7N9FAFzi = 3951 + INTEGER(IntKi), PARAMETER :: M8N1FAFzi = 3952 + INTEGER(IntKi), PARAMETER :: M8N2FAFzi = 3953 + INTEGER(IntKi), PARAMETER :: M8N3FAFzi = 3954 + INTEGER(IntKi), PARAMETER :: M8N4FAFzi = 3955 + INTEGER(IntKi), PARAMETER :: M8N5FAFzi = 3956 + INTEGER(IntKi), PARAMETER :: M8N6FAFzi = 3957 + INTEGER(IntKi), PARAMETER :: M8N7FAFzi = 3958 + INTEGER(IntKi), PARAMETER :: M8N8FAFzi = 3959 + INTEGER(IntKi), PARAMETER :: M8N9FAFzi = 3960 + INTEGER(IntKi), PARAMETER :: M9N1FAFzi = 3961 + INTEGER(IntKi), PARAMETER :: M9N2FAFzi = 3962 + INTEGER(IntKi), PARAMETER :: M9N3FAFzi = 3963 + INTEGER(IntKi), PARAMETER :: M9N4FAFzi = 3964 + INTEGER(IntKi), PARAMETER :: M9N5FAFzi = 3965 + INTEGER(IntKi), PARAMETER :: M9N6FAFzi = 3966 + INTEGER(IntKi), PARAMETER :: M9N7FAFzi = 3967 + INTEGER(IntKi), PARAMETER :: M9N8FAFzi = 3968 + INTEGER(IntKi), PARAMETER :: M9N9FAFzi = 3969 + INTEGER(IntKi), PARAMETER :: M1N1MAFxi = 3970 + INTEGER(IntKi), PARAMETER :: M1N2MAFxi = 3971 + INTEGER(IntKi), PARAMETER :: M1N3MAFxi = 3972 + INTEGER(IntKi), PARAMETER :: M1N4MAFxi = 3973 + INTEGER(IntKi), PARAMETER :: M1N5MAFxi = 3974 + INTEGER(IntKi), PARAMETER :: M1N6MAFxi = 3975 + INTEGER(IntKi), PARAMETER :: M1N7MAFxi = 3976 + INTEGER(IntKi), PARAMETER :: M1N8MAFxi = 3977 + INTEGER(IntKi), PARAMETER :: M1N9MAFxi = 3978 + INTEGER(IntKi), PARAMETER :: M2N1MAFxi = 3979 + INTEGER(IntKi), PARAMETER :: M2N2MAFxi = 3980 + INTEGER(IntKi), PARAMETER :: M2N3MAFxi = 3981 + INTEGER(IntKi), PARAMETER :: M2N4MAFxi = 3982 + INTEGER(IntKi), PARAMETER :: M2N5MAFxi = 3983 + INTEGER(IntKi), PARAMETER :: M2N6MAFxi = 3984 + INTEGER(IntKi), PARAMETER :: M2N7MAFxi = 3985 + INTEGER(IntKi), PARAMETER :: M2N8MAFxi = 3986 + INTEGER(IntKi), PARAMETER :: M2N9MAFxi = 3987 + INTEGER(IntKi), PARAMETER :: M3N1MAFxi = 3988 + INTEGER(IntKi), PARAMETER :: M3N2MAFxi = 3989 + INTEGER(IntKi), PARAMETER :: M3N3MAFxi = 3990 + INTEGER(IntKi), PARAMETER :: M3N4MAFxi = 3991 + INTEGER(IntKi), PARAMETER :: M3N5MAFxi = 3992 + INTEGER(IntKi), PARAMETER :: M3N6MAFxi = 3993 + INTEGER(IntKi), PARAMETER :: M3N7MAFxi = 3994 + INTEGER(IntKi), PARAMETER :: M3N8MAFxi = 3995 + INTEGER(IntKi), PARAMETER :: M3N9MAFxi = 3996 + INTEGER(IntKi), PARAMETER :: M4N1MAFxi = 3997 + INTEGER(IntKi), PARAMETER :: M4N2MAFxi = 3998 + INTEGER(IntKi), PARAMETER :: M4N3MAFxi = 3999 + INTEGER(IntKi), PARAMETER :: M4N4MAFxi = 4000 + INTEGER(IntKi), PARAMETER :: M4N5MAFxi = 4001 + INTEGER(IntKi), PARAMETER :: M4N6MAFxi = 4002 + INTEGER(IntKi), PARAMETER :: M4N7MAFxi = 4003 + INTEGER(IntKi), PARAMETER :: M4N8MAFxi = 4004 + INTEGER(IntKi), PARAMETER :: M4N9MAFxi = 4005 + INTEGER(IntKi), PARAMETER :: M5N1MAFxi = 4006 + INTEGER(IntKi), PARAMETER :: M5N2MAFxi = 4007 + INTEGER(IntKi), PARAMETER :: M5N3MAFxi = 4008 + INTEGER(IntKi), PARAMETER :: M5N4MAFxi = 4009 + INTEGER(IntKi), PARAMETER :: M5N5MAFxi = 4010 + INTEGER(IntKi), PARAMETER :: M5N6MAFxi = 4011 + INTEGER(IntKi), PARAMETER :: M5N7MAFxi = 4012 + INTEGER(IntKi), PARAMETER :: M5N8MAFxi = 4013 + INTEGER(IntKi), PARAMETER :: M5N9MAFxi = 4014 + INTEGER(IntKi), PARAMETER :: M6N1MAFxi = 4015 + INTEGER(IntKi), PARAMETER :: M6N2MAFxi = 4016 + INTEGER(IntKi), PARAMETER :: M6N3MAFxi = 4017 + INTEGER(IntKi), PARAMETER :: M6N4MAFxi = 4018 + INTEGER(IntKi), PARAMETER :: M6N5MAFxi = 4019 + INTEGER(IntKi), PARAMETER :: M6N6MAFxi = 4020 + INTEGER(IntKi), PARAMETER :: M6N7MAFxi = 4021 + INTEGER(IntKi), PARAMETER :: M6N8MAFxi = 4022 + INTEGER(IntKi), PARAMETER :: M6N9MAFxi = 4023 + INTEGER(IntKi), PARAMETER :: M7N1MAFxi = 4024 + INTEGER(IntKi), PARAMETER :: M7N2MAFxi = 4025 + INTEGER(IntKi), PARAMETER :: M7N3MAFxi = 4026 + INTEGER(IntKi), PARAMETER :: M7N4MAFxi = 4027 + INTEGER(IntKi), PARAMETER :: M7N5MAFxi = 4028 + INTEGER(IntKi), PARAMETER :: M7N6MAFxi = 4029 + INTEGER(IntKi), PARAMETER :: M7N7MAFxi = 4030 + INTEGER(IntKi), PARAMETER :: M7N8MAFxi = 4031 + INTEGER(IntKi), PARAMETER :: M7N9MAFxi = 4032 + INTEGER(IntKi), PARAMETER :: M8N1MAFxi = 4033 + INTEGER(IntKi), PARAMETER :: M8N2MAFxi = 4034 + INTEGER(IntKi), PARAMETER :: M8N3MAFxi = 4035 + INTEGER(IntKi), PARAMETER :: M8N4MAFxi = 4036 + INTEGER(IntKi), PARAMETER :: M8N5MAFxi = 4037 + INTEGER(IntKi), PARAMETER :: M8N6MAFxi = 4038 + INTEGER(IntKi), PARAMETER :: M8N7MAFxi = 4039 + INTEGER(IntKi), PARAMETER :: M8N8MAFxi = 4040 + INTEGER(IntKi), PARAMETER :: M8N9MAFxi = 4041 + INTEGER(IntKi), PARAMETER :: M9N1MAFxi = 4042 + INTEGER(IntKi), PARAMETER :: M9N2MAFxi = 4043 + INTEGER(IntKi), PARAMETER :: M9N3MAFxi = 4044 + INTEGER(IntKi), PARAMETER :: M9N4MAFxi = 4045 + INTEGER(IntKi), PARAMETER :: M9N5MAFxi = 4046 + INTEGER(IntKi), PARAMETER :: M9N6MAFxi = 4047 + INTEGER(IntKi), PARAMETER :: M9N7MAFxi = 4048 + INTEGER(IntKi), PARAMETER :: M9N8MAFxi = 4049 + INTEGER(IntKi), PARAMETER :: M9N9MAFxi = 4050 + INTEGER(IntKi), PARAMETER :: M1N1MAFyi = 4051 + INTEGER(IntKi), PARAMETER :: M1N2MAFyi = 4052 + INTEGER(IntKi), PARAMETER :: M1N3MAFyi = 4053 + INTEGER(IntKi), PARAMETER :: M1N4MAFyi = 4054 + INTEGER(IntKi), PARAMETER :: M1N5MAFyi = 4055 + INTEGER(IntKi), PARAMETER :: M1N6MAFyi = 4056 + INTEGER(IntKi), PARAMETER :: M1N7MAFyi = 4057 + INTEGER(IntKi), PARAMETER :: M1N8MAFyi = 4058 + INTEGER(IntKi), PARAMETER :: M1N9MAFyi = 4059 + INTEGER(IntKi), PARAMETER :: M2N1MAFyi = 4060 + INTEGER(IntKi), PARAMETER :: M2N2MAFyi = 4061 + INTEGER(IntKi), PARAMETER :: M2N3MAFyi = 4062 + INTEGER(IntKi), PARAMETER :: M2N4MAFyi = 4063 + INTEGER(IntKi), PARAMETER :: M2N5MAFyi = 4064 + INTEGER(IntKi), PARAMETER :: M2N6MAFyi = 4065 + INTEGER(IntKi), PARAMETER :: M2N7MAFyi = 4066 + INTEGER(IntKi), PARAMETER :: M2N8MAFyi = 4067 + INTEGER(IntKi), PARAMETER :: M2N9MAFyi = 4068 + INTEGER(IntKi), PARAMETER :: M3N1MAFyi = 4069 + INTEGER(IntKi), PARAMETER :: M3N2MAFyi = 4070 + INTEGER(IntKi), PARAMETER :: M3N3MAFyi = 4071 + INTEGER(IntKi), PARAMETER :: M3N4MAFyi = 4072 + INTEGER(IntKi), PARAMETER :: M3N5MAFyi = 4073 + INTEGER(IntKi), PARAMETER :: M3N6MAFyi = 4074 + INTEGER(IntKi), PARAMETER :: M3N7MAFyi = 4075 + INTEGER(IntKi), PARAMETER :: M3N8MAFyi = 4076 + INTEGER(IntKi), PARAMETER :: M3N9MAFyi = 4077 + INTEGER(IntKi), PARAMETER :: M4N1MAFyi = 4078 + INTEGER(IntKi), PARAMETER :: M4N2MAFyi = 4079 + INTEGER(IntKi), PARAMETER :: M4N3MAFyi = 4080 + INTEGER(IntKi), PARAMETER :: M4N4MAFyi = 4081 + INTEGER(IntKi), PARAMETER :: M4N5MAFyi = 4082 + INTEGER(IntKi), PARAMETER :: M4N6MAFyi = 4083 + INTEGER(IntKi), PARAMETER :: M4N7MAFyi = 4084 + INTEGER(IntKi), PARAMETER :: M4N8MAFyi = 4085 + INTEGER(IntKi), PARAMETER :: M4N9MAFyi = 4086 + INTEGER(IntKi), PARAMETER :: M5N1MAFyi = 4087 + INTEGER(IntKi), PARAMETER :: M5N2MAFyi = 4088 + INTEGER(IntKi), PARAMETER :: M5N3MAFyi = 4089 + INTEGER(IntKi), PARAMETER :: M5N4MAFyi = 4090 + INTEGER(IntKi), PARAMETER :: M5N5MAFyi = 4091 + INTEGER(IntKi), PARAMETER :: M5N6MAFyi = 4092 + INTEGER(IntKi), PARAMETER :: M5N7MAFyi = 4093 + INTEGER(IntKi), PARAMETER :: M5N8MAFyi = 4094 + INTEGER(IntKi), PARAMETER :: M5N9MAFyi = 4095 + INTEGER(IntKi), PARAMETER :: M6N1MAFyi = 4096 + INTEGER(IntKi), PARAMETER :: M6N2MAFyi = 4097 + INTEGER(IntKi), PARAMETER :: M6N3MAFyi = 4098 + INTEGER(IntKi), PARAMETER :: M6N4MAFyi = 4099 + INTEGER(IntKi), PARAMETER :: M6N5MAFyi = 4100 + INTEGER(IntKi), PARAMETER :: M6N6MAFyi = 4101 + INTEGER(IntKi), PARAMETER :: M6N7MAFyi = 4102 + INTEGER(IntKi), PARAMETER :: M6N8MAFyi = 4103 + INTEGER(IntKi), PARAMETER :: M6N9MAFyi = 4104 + INTEGER(IntKi), PARAMETER :: M7N1MAFyi = 4105 + INTEGER(IntKi), PARAMETER :: M7N2MAFyi = 4106 + INTEGER(IntKi), PARAMETER :: M7N3MAFyi = 4107 + INTEGER(IntKi), PARAMETER :: M7N4MAFyi = 4108 + INTEGER(IntKi), PARAMETER :: M7N5MAFyi = 4109 + INTEGER(IntKi), PARAMETER :: M7N6MAFyi = 4110 + INTEGER(IntKi), PARAMETER :: M7N7MAFyi = 4111 + INTEGER(IntKi), PARAMETER :: M7N8MAFyi = 4112 + INTEGER(IntKi), PARAMETER :: M7N9MAFyi = 4113 + INTEGER(IntKi), PARAMETER :: M8N1MAFyi = 4114 + INTEGER(IntKi), PARAMETER :: M8N2MAFyi = 4115 + INTEGER(IntKi), PARAMETER :: M8N3MAFyi = 4116 + INTEGER(IntKi), PARAMETER :: M8N4MAFyi = 4117 + INTEGER(IntKi), PARAMETER :: M8N5MAFyi = 4118 + INTEGER(IntKi), PARAMETER :: M8N6MAFyi = 4119 + INTEGER(IntKi), PARAMETER :: M8N7MAFyi = 4120 + INTEGER(IntKi), PARAMETER :: M8N8MAFyi = 4121 + INTEGER(IntKi), PARAMETER :: M8N9MAFyi = 4122 + INTEGER(IntKi), PARAMETER :: M9N1MAFyi = 4123 + INTEGER(IntKi), PARAMETER :: M9N2MAFyi = 4124 + INTEGER(IntKi), PARAMETER :: M9N3MAFyi = 4125 + INTEGER(IntKi), PARAMETER :: M9N4MAFyi = 4126 + INTEGER(IntKi), PARAMETER :: M9N5MAFyi = 4127 + INTEGER(IntKi), PARAMETER :: M9N6MAFyi = 4128 + INTEGER(IntKi), PARAMETER :: M9N7MAFyi = 4129 + INTEGER(IntKi), PARAMETER :: M9N8MAFyi = 4130 + INTEGER(IntKi), PARAMETER :: M9N9MAFyi = 4131 + INTEGER(IntKi), PARAMETER :: M1N1MAFzi = 4132 + INTEGER(IntKi), PARAMETER :: M1N2MAFzi = 4133 + INTEGER(IntKi), PARAMETER :: M1N3MAFzi = 4134 + INTEGER(IntKi), PARAMETER :: M1N4MAFzi = 4135 + INTEGER(IntKi), PARAMETER :: M1N5MAFzi = 4136 + INTEGER(IntKi), PARAMETER :: M1N6MAFzi = 4137 + INTEGER(IntKi), PARAMETER :: M1N7MAFzi = 4138 + INTEGER(IntKi), PARAMETER :: M1N8MAFzi = 4139 + INTEGER(IntKi), PARAMETER :: M1N9MAFzi = 4140 + INTEGER(IntKi), PARAMETER :: M2N1MAFzi = 4141 + INTEGER(IntKi), PARAMETER :: M2N2MAFzi = 4142 + INTEGER(IntKi), PARAMETER :: M2N3MAFzi = 4143 + INTEGER(IntKi), PARAMETER :: M2N4MAFzi = 4144 + INTEGER(IntKi), PARAMETER :: M2N5MAFzi = 4145 + INTEGER(IntKi), PARAMETER :: M2N6MAFzi = 4146 + INTEGER(IntKi), PARAMETER :: M2N7MAFzi = 4147 + INTEGER(IntKi), PARAMETER :: M2N8MAFzi = 4148 + INTEGER(IntKi), PARAMETER :: M2N9MAFzi = 4149 + INTEGER(IntKi), PARAMETER :: M3N1MAFzi = 4150 + INTEGER(IntKi), PARAMETER :: M3N2MAFzi = 4151 + INTEGER(IntKi), PARAMETER :: M3N3MAFzi = 4152 + INTEGER(IntKi), PARAMETER :: M3N4MAFzi = 4153 + INTEGER(IntKi), PARAMETER :: M3N5MAFzi = 4154 + INTEGER(IntKi), PARAMETER :: M3N6MAFzi = 4155 + INTEGER(IntKi), PARAMETER :: M3N7MAFzi = 4156 + INTEGER(IntKi), PARAMETER :: M3N8MAFzi = 4157 + INTEGER(IntKi), PARAMETER :: M3N9MAFzi = 4158 + INTEGER(IntKi), PARAMETER :: M4N1MAFzi = 4159 + INTEGER(IntKi), PARAMETER :: M4N2MAFzi = 4160 + INTEGER(IntKi), PARAMETER :: M4N3MAFzi = 4161 + INTEGER(IntKi), PARAMETER :: M4N4MAFzi = 4162 + INTEGER(IntKi), PARAMETER :: M4N5MAFzi = 4163 + INTEGER(IntKi), PARAMETER :: M4N6MAFzi = 4164 + INTEGER(IntKi), PARAMETER :: M4N7MAFzi = 4165 + INTEGER(IntKi), PARAMETER :: M4N8MAFzi = 4166 + INTEGER(IntKi), PARAMETER :: M4N9MAFzi = 4167 + INTEGER(IntKi), PARAMETER :: M5N1MAFzi = 4168 + INTEGER(IntKi), PARAMETER :: M5N2MAFzi = 4169 + INTEGER(IntKi), PARAMETER :: M5N3MAFzi = 4170 + INTEGER(IntKi), PARAMETER :: M5N4MAFzi = 4171 + INTEGER(IntKi), PARAMETER :: M5N5MAFzi = 4172 + INTEGER(IntKi), PARAMETER :: M5N6MAFzi = 4173 + INTEGER(IntKi), PARAMETER :: M5N7MAFzi = 4174 + INTEGER(IntKi), PARAMETER :: M5N8MAFzi = 4175 + INTEGER(IntKi), PARAMETER :: M5N9MAFzi = 4176 + INTEGER(IntKi), PARAMETER :: M6N1MAFzi = 4177 + INTEGER(IntKi), PARAMETER :: M6N2MAFzi = 4178 + INTEGER(IntKi), PARAMETER :: M6N3MAFzi = 4179 + INTEGER(IntKi), PARAMETER :: M6N4MAFzi = 4180 + INTEGER(IntKi), PARAMETER :: M6N5MAFzi = 4181 + INTEGER(IntKi), PARAMETER :: M6N6MAFzi = 4182 + INTEGER(IntKi), PARAMETER :: M6N7MAFzi = 4183 + INTEGER(IntKi), PARAMETER :: M6N8MAFzi = 4184 + INTEGER(IntKi), PARAMETER :: M6N9MAFzi = 4185 + INTEGER(IntKi), PARAMETER :: M7N1MAFzi = 4186 + INTEGER(IntKi), PARAMETER :: M7N2MAFzi = 4187 + INTEGER(IntKi), PARAMETER :: M7N3MAFzi = 4188 + INTEGER(IntKi), PARAMETER :: M7N4MAFzi = 4189 + INTEGER(IntKi), PARAMETER :: M7N5MAFzi = 4190 + INTEGER(IntKi), PARAMETER :: M7N6MAFzi = 4191 + INTEGER(IntKi), PARAMETER :: M7N7MAFzi = 4192 + INTEGER(IntKi), PARAMETER :: M7N8MAFzi = 4193 + INTEGER(IntKi), PARAMETER :: M7N9MAFzi = 4194 + INTEGER(IntKi), PARAMETER :: M8N1MAFzi = 4195 + INTEGER(IntKi), PARAMETER :: M8N2MAFzi = 4196 + INTEGER(IntKi), PARAMETER :: M8N3MAFzi = 4197 + INTEGER(IntKi), PARAMETER :: M8N4MAFzi = 4198 + INTEGER(IntKi), PARAMETER :: M8N5MAFzi = 4199 + INTEGER(IntKi), PARAMETER :: M8N6MAFzi = 4200 + INTEGER(IntKi), PARAMETER :: M8N7MAFzi = 4201 + INTEGER(IntKi), PARAMETER :: M8N8MAFzi = 4202 + INTEGER(IntKi), PARAMETER :: M8N9MAFzi = 4203 + INTEGER(IntKi), PARAMETER :: M9N1MAFzi = 4204 + INTEGER(IntKi), PARAMETER :: M9N2MAFzi = 4205 + INTEGER(IntKi), PARAMETER :: M9N3MAFzi = 4206 + INTEGER(IntKi), PARAMETER :: M9N4MAFzi = 4207 + INTEGER(IntKi), PARAMETER :: M9N5MAFzi = 4208 + INTEGER(IntKi), PARAMETER :: M9N6MAFzi = 4209 + INTEGER(IntKi), PARAMETER :: M9N7MAFzi = 4210 + INTEGER(IntKi), PARAMETER :: M9N8MAFzi = 4211 + INTEGER(IntKi), PARAMETER :: M9N9MAFzi = 4212 - ! Category: - INTEGER(IntKi), PARAMETER :: J1Vxi = 3727 - INTEGER(IntKi), PARAMETER :: J2Vxi = 3728 - INTEGER(IntKi), PARAMETER :: J3Vxi = 3729 - INTEGER(IntKi), PARAMETER :: J4Vxi = 3730 - INTEGER(IntKi), PARAMETER :: J5Vxi = 3731 - INTEGER(IntKi), PARAMETER :: J6Vxi = 3732 - INTEGER(IntKi), PARAMETER :: J7Vxi = 3733 - INTEGER(IntKi), PARAMETER :: J8Vxi = 3734 - INTEGER(IntKi), PARAMETER :: J9Vxi = 3735 - INTEGER(IntKi), PARAMETER :: J1Vyi = 3736 - INTEGER(IntKi), PARAMETER :: J2Vyi = 3737 - INTEGER(IntKi), PARAMETER :: J3Vyi = 3738 - INTEGER(IntKi), PARAMETER :: J4Vyi = 3739 - INTEGER(IntKi), PARAMETER :: J5Vyi = 3740 - INTEGER(IntKi), PARAMETER :: J6Vyi = 3741 - INTEGER(IntKi), PARAMETER :: J7Vyi = 3742 - INTEGER(IntKi), PARAMETER :: J8Vyi = 3743 - INTEGER(IntKi), PARAMETER :: J9Vyi = 3744 - INTEGER(IntKi), PARAMETER :: J1Vzi = 3745 - INTEGER(IntKi), PARAMETER :: J2Vzi = 3746 - INTEGER(IntKi), PARAMETER :: J3Vzi = 3747 - INTEGER(IntKi), PARAMETER :: J4Vzi = 3748 - INTEGER(IntKi), PARAMETER :: J5Vzi = 3749 - INTEGER(IntKi), PARAMETER :: J6Vzi = 3750 - INTEGER(IntKi), PARAMETER :: J7Vzi = 3751 - INTEGER(IntKi), PARAMETER :: J8Vzi = 3752 - INTEGER(IntKi), PARAMETER :: J9Vzi = 3753 - INTEGER(IntKi), PARAMETER :: J1Axi = 3754 - INTEGER(IntKi), PARAMETER :: J2Axi = 3755 - INTEGER(IntKi), PARAMETER :: J3Axi = 3756 - INTEGER(IntKi), PARAMETER :: J4Axi = 3757 - INTEGER(IntKi), PARAMETER :: J5Axi = 3758 - INTEGER(IntKi), PARAMETER :: J6Axi = 3759 - INTEGER(IntKi), PARAMETER :: J7Axi = 3760 - INTEGER(IntKi), PARAMETER :: J8Axi = 3761 - INTEGER(IntKi), PARAMETER :: J9Axi = 3762 - INTEGER(IntKi), PARAMETER :: J1Ayi = 3763 - INTEGER(IntKi), PARAMETER :: J2Ayi = 3764 - INTEGER(IntKi), PARAMETER :: J3Ayi = 3765 - INTEGER(IntKi), PARAMETER :: J4Ayi = 3766 - INTEGER(IntKi), PARAMETER :: J5Ayi = 3767 - INTEGER(IntKi), PARAMETER :: J6Ayi = 3768 - INTEGER(IntKi), PARAMETER :: J7Ayi = 3769 - INTEGER(IntKi), PARAMETER :: J8Ayi = 3770 - INTEGER(IntKi), PARAMETER :: J9Ayi = 3771 - INTEGER(IntKi), PARAMETER :: J1Azi = 3772 - INTEGER(IntKi), PARAMETER :: J2Azi = 3773 - INTEGER(IntKi), PARAMETER :: J3Azi = 3774 - INTEGER(IntKi), PARAMETER :: J4Azi = 3775 - INTEGER(IntKi), PARAMETER :: J5Azi = 3776 - INTEGER(IntKi), PARAMETER :: J6Azi = 3777 - INTEGER(IntKi), PARAMETER :: J7Azi = 3778 - INTEGER(IntKi), PARAMETER :: J8Azi = 3779 - INTEGER(IntKi), PARAMETER :: J9Azi = 3780 - INTEGER(IntKi), PARAMETER :: J1DynP = 3781 - INTEGER(IntKi), PARAMETER :: J2DynP = 3782 - INTEGER(IntKi), PARAMETER :: J3DynP = 3783 - INTEGER(IntKi), PARAMETER :: J4DynP = 3784 - INTEGER(IntKi), PARAMETER :: J5DynP = 3785 - INTEGER(IntKi), PARAMETER :: J6DynP = 3786 - INTEGER(IntKi), PARAMETER :: J7DynP = 3787 - INTEGER(IntKi), PARAMETER :: J8DynP = 3788 - INTEGER(IntKi), PARAMETER :: J9DynP = 3789 - INTEGER(IntKi), PARAMETER :: J1STVxi = 3790 - INTEGER(IntKi), PARAMETER :: J2STVxi = 3791 - INTEGER(IntKi), PARAMETER :: J3STVxi = 3792 - INTEGER(IntKi), PARAMETER :: J4STVxi = 3793 - INTEGER(IntKi), PARAMETER :: J5STVxi = 3794 - INTEGER(IntKi), PARAMETER :: J6STVxi = 3795 - INTEGER(IntKi), PARAMETER :: J7STVxi = 3796 - INTEGER(IntKi), PARAMETER :: J8STVxi = 3797 - INTEGER(IntKi), PARAMETER :: J9STVxi = 3798 - INTEGER(IntKi), PARAMETER :: J1STVyi = 3799 - INTEGER(IntKi), PARAMETER :: J2STVyi = 3800 - INTEGER(IntKi), PARAMETER :: J3STVyi = 3801 - INTEGER(IntKi), PARAMETER :: J4STVyi = 3802 - INTEGER(IntKi), PARAMETER :: J5STVyi = 3803 - INTEGER(IntKi), PARAMETER :: J6STVyi = 3804 - INTEGER(IntKi), PARAMETER :: J7STVyi = 3805 - INTEGER(IntKi), PARAMETER :: J8STVyi = 3806 - INTEGER(IntKi), PARAMETER :: J9STVyi = 3807 - INTEGER(IntKi), PARAMETER :: J1STVzi = 3808 - INTEGER(IntKi), PARAMETER :: J2STVzi = 3809 - INTEGER(IntKi), PARAMETER :: J3STVzi = 3810 - INTEGER(IntKi), PARAMETER :: J4STVzi = 3811 - INTEGER(IntKi), PARAMETER :: J5STVzi = 3812 - INTEGER(IntKi), PARAMETER :: J6STVzi = 3813 - INTEGER(IntKi), PARAMETER :: J7STVzi = 3814 - INTEGER(IntKi), PARAMETER :: J8STVzi = 3815 - INTEGER(IntKi), PARAMETER :: J9STVzi = 3816 - INTEGER(IntKi), PARAMETER :: J1STAxi = 3817 - INTEGER(IntKi), PARAMETER :: J2STAxi = 3818 - INTEGER(IntKi), PARAMETER :: J3STAxi = 3819 - INTEGER(IntKi), PARAMETER :: J4STAxi = 3820 - INTEGER(IntKi), PARAMETER :: J5STAxi = 3821 - INTEGER(IntKi), PARAMETER :: J6STAxi = 3822 - INTEGER(IntKi), PARAMETER :: J7STAxi = 3823 - INTEGER(IntKi), PARAMETER :: J8STAxi = 3824 - INTEGER(IntKi), PARAMETER :: J9STAxi = 3825 - INTEGER(IntKi), PARAMETER :: J1STAyi = 3826 - INTEGER(IntKi), PARAMETER :: J2STAyi = 3827 - INTEGER(IntKi), PARAMETER :: J3STAyi = 3828 - INTEGER(IntKi), PARAMETER :: J4STAyi = 3829 - INTEGER(IntKi), PARAMETER :: J5STAyi = 3830 - INTEGER(IntKi), PARAMETER :: J6STAyi = 3831 - INTEGER(IntKi), PARAMETER :: J7STAyi = 3832 - INTEGER(IntKi), PARAMETER :: J8STAyi = 3833 - INTEGER(IntKi), PARAMETER :: J9STAyi = 3834 - INTEGER(IntKi), PARAMETER :: J1STAzi = 3835 - INTEGER(IntKi), PARAMETER :: J2STAzi = 3836 - INTEGER(IntKi), PARAMETER :: J3STAzi = 3837 - INTEGER(IntKi), PARAMETER :: J4STAzi = 3838 - INTEGER(IntKi), PARAMETER :: J5STAzi = 3839 - INTEGER(IntKi), PARAMETER :: J6STAzi = 3840 - INTEGER(IntKi), PARAMETER :: J7STAzi = 3841 - INTEGER(IntKi), PARAMETER :: J8STAzi = 3842 - INTEGER(IntKi), PARAMETER :: J9STAzi = 3843 + ! Joint-level Wave Kinematics : + INTEGER(IntKi), PARAMETER :: J1Vxi = 4213 + INTEGER(IntKi), PARAMETER :: J2Vxi = 4214 + INTEGER(IntKi), PARAMETER :: J3Vxi = 4215 + INTEGER(IntKi), PARAMETER :: J4Vxi = 4216 + INTEGER(IntKi), PARAMETER :: J5Vxi = 4217 + INTEGER(IntKi), PARAMETER :: J6Vxi = 4218 + INTEGER(IntKi), PARAMETER :: J7Vxi = 4219 + INTEGER(IntKi), PARAMETER :: J8Vxi = 4220 + INTEGER(IntKi), PARAMETER :: J9Vxi = 4221 + INTEGER(IntKi), PARAMETER :: J1Vyi = 4222 + INTEGER(IntKi), PARAMETER :: J2Vyi = 4223 + INTEGER(IntKi), PARAMETER :: J3Vyi = 4224 + INTEGER(IntKi), PARAMETER :: J4Vyi = 4225 + INTEGER(IntKi), PARAMETER :: J5Vyi = 4226 + INTEGER(IntKi), PARAMETER :: J6Vyi = 4227 + INTEGER(IntKi), PARAMETER :: J7Vyi = 4228 + INTEGER(IntKi), PARAMETER :: J8Vyi = 4229 + INTEGER(IntKi), PARAMETER :: J9Vyi = 4230 + INTEGER(IntKi), PARAMETER :: J1Vzi = 4231 + INTEGER(IntKi), PARAMETER :: J2Vzi = 4232 + INTEGER(IntKi), PARAMETER :: J3Vzi = 4233 + INTEGER(IntKi), PARAMETER :: J4Vzi = 4234 + INTEGER(IntKi), PARAMETER :: J5Vzi = 4235 + INTEGER(IntKi), PARAMETER :: J6Vzi = 4236 + INTEGER(IntKi), PARAMETER :: J7Vzi = 4237 + INTEGER(IntKi), PARAMETER :: J8Vzi = 4238 + INTEGER(IntKi), PARAMETER :: J9Vzi = 4239 + INTEGER(IntKi), PARAMETER :: J1Axi = 4240 + INTEGER(IntKi), PARAMETER :: J2Axi = 4241 + INTEGER(IntKi), PARAMETER :: J3Axi = 4242 + INTEGER(IntKi), PARAMETER :: J4Axi = 4243 + INTEGER(IntKi), PARAMETER :: J5Axi = 4244 + INTEGER(IntKi), PARAMETER :: J6Axi = 4245 + INTEGER(IntKi), PARAMETER :: J7Axi = 4246 + INTEGER(IntKi), PARAMETER :: J8Axi = 4247 + INTEGER(IntKi), PARAMETER :: J9Axi = 4248 + INTEGER(IntKi), PARAMETER :: J1Ayi = 4249 + INTEGER(IntKi), PARAMETER :: J2Ayi = 4250 + INTEGER(IntKi), PARAMETER :: J3Ayi = 4251 + INTEGER(IntKi), PARAMETER :: J4Ayi = 4252 + INTEGER(IntKi), PARAMETER :: J5Ayi = 4253 + INTEGER(IntKi), PARAMETER :: J6Ayi = 4254 + INTEGER(IntKi), PARAMETER :: J7Ayi = 4255 + INTEGER(IntKi), PARAMETER :: J8Ayi = 4256 + INTEGER(IntKi), PARAMETER :: J9Ayi = 4257 + INTEGER(IntKi), PARAMETER :: J1Azi = 4258 + INTEGER(IntKi), PARAMETER :: J2Azi = 4259 + INTEGER(IntKi), PARAMETER :: J3Azi = 4260 + INTEGER(IntKi), PARAMETER :: J4Azi = 4261 + INTEGER(IntKi), PARAMETER :: J5Azi = 4262 + INTEGER(IntKi), PARAMETER :: J6Azi = 4263 + INTEGER(IntKi), PARAMETER :: J7Azi = 4264 + INTEGER(IntKi), PARAMETER :: J8Azi = 4265 + INTEGER(IntKi), PARAMETER :: J9Azi = 4266 + INTEGER(IntKi), PARAMETER :: J1DynP = 4267 + INTEGER(IntKi), PARAMETER :: J2DynP = 4268 + INTEGER(IntKi), PARAMETER :: J3DynP = 4269 + INTEGER(IntKi), PARAMETER :: J4DynP = 4270 + INTEGER(IntKi), PARAMETER :: J5DynP = 4271 + INTEGER(IntKi), PARAMETER :: J6DynP = 4272 + INTEGER(IntKi), PARAMETER :: J7DynP = 4273 + INTEGER(IntKi), PARAMETER :: J8DynP = 4274 + INTEGER(IntKi), PARAMETER :: J9DynP = 4275 + INTEGER(IntKi), PARAMETER :: J1STVxi = 4276 + INTEGER(IntKi), PARAMETER :: J2STVxi = 4277 + INTEGER(IntKi), PARAMETER :: J3STVxi = 4278 + INTEGER(IntKi), PARAMETER :: J4STVxi = 4279 + INTEGER(IntKi), PARAMETER :: J5STVxi = 4280 + INTEGER(IntKi), PARAMETER :: J6STVxi = 4281 + INTEGER(IntKi), PARAMETER :: J7STVxi = 4282 + INTEGER(IntKi), PARAMETER :: J8STVxi = 4283 + INTEGER(IntKi), PARAMETER :: J9STVxi = 4284 + INTEGER(IntKi), PARAMETER :: J1STVyi = 4285 + INTEGER(IntKi), PARAMETER :: J2STVyi = 4286 + INTEGER(IntKi), PARAMETER :: J3STVyi = 4287 + INTEGER(IntKi), PARAMETER :: J4STVyi = 4288 + INTEGER(IntKi), PARAMETER :: J5STVyi = 4289 + INTEGER(IntKi), PARAMETER :: J6STVyi = 4290 + INTEGER(IntKi), PARAMETER :: J7STVyi = 4291 + INTEGER(IntKi), PARAMETER :: J8STVyi = 4292 + INTEGER(IntKi), PARAMETER :: J9STVyi = 4293 + INTEGER(IntKi), PARAMETER :: J1STVzi = 4294 + INTEGER(IntKi), PARAMETER :: J2STVzi = 4295 + INTEGER(IntKi), PARAMETER :: J3STVzi = 4296 + INTEGER(IntKi), PARAMETER :: J4STVzi = 4297 + INTEGER(IntKi), PARAMETER :: J5STVzi = 4298 + INTEGER(IntKi), PARAMETER :: J6STVzi = 4299 + INTEGER(IntKi), PARAMETER :: J7STVzi = 4300 + INTEGER(IntKi), PARAMETER :: J8STVzi = 4301 + INTEGER(IntKi), PARAMETER :: J9STVzi = 4302 + INTEGER(IntKi), PARAMETER :: J1STAxi = 4303 + INTEGER(IntKi), PARAMETER :: J2STAxi = 4304 + INTEGER(IntKi), PARAMETER :: J3STAxi = 4305 + INTEGER(IntKi), PARAMETER :: J4STAxi = 4306 + INTEGER(IntKi), PARAMETER :: J5STAxi = 4307 + INTEGER(IntKi), PARAMETER :: J6STAxi = 4308 + INTEGER(IntKi), PARAMETER :: J7STAxi = 4309 + INTEGER(IntKi), PARAMETER :: J8STAxi = 4310 + INTEGER(IntKi), PARAMETER :: J9STAxi = 4311 + INTEGER(IntKi), PARAMETER :: J1STAyi = 4312 + INTEGER(IntKi), PARAMETER :: J2STAyi = 4313 + INTEGER(IntKi), PARAMETER :: J3STAyi = 4314 + INTEGER(IntKi), PARAMETER :: J4STAyi = 4315 + INTEGER(IntKi), PARAMETER :: J5STAyi = 4316 + INTEGER(IntKi), PARAMETER :: J6STAyi = 4317 + INTEGER(IntKi), PARAMETER :: J7STAyi = 4318 + INTEGER(IntKi), PARAMETER :: J8STAyi = 4319 + INTEGER(IntKi), PARAMETER :: J9STAyi = 4320 + INTEGER(IntKi), PARAMETER :: J1STAzi = 4321 + INTEGER(IntKi), PARAMETER :: J2STAzi = 4322 + INTEGER(IntKi), PARAMETER :: J3STAzi = 4323 + INTEGER(IntKi), PARAMETER :: J4STAzi = 4324 + INTEGER(IntKi), PARAMETER :: J5STAzi = 4325 + INTEGER(IntKi), PARAMETER :: J6STAzi = 4326 + INTEGER(IntKi), PARAMETER :: J7STAzi = 4327 + INTEGER(IntKi), PARAMETER :: J8STAzi = 4328 + INTEGER(IntKi), PARAMETER :: J9STAzi = 4329 - ! Category: - INTEGER(IntKi), PARAMETER :: J1FDxi = 3844 - INTEGER(IntKi), PARAMETER :: J2FDxi = 3845 - INTEGER(IntKi), PARAMETER :: J3FDxi = 3846 - INTEGER(IntKi), PARAMETER :: J4FDxi = 3847 - INTEGER(IntKi), PARAMETER :: J5FDxi = 3848 - INTEGER(IntKi), PARAMETER :: J6FDxi = 3849 - INTEGER(IntKi), PARAMETER :: J7FDxi = 3850 - INTEGER(IntKi), PARAMETER :: J8FDxi = 3851 - INTEGER(IntKi), PARAMETER :: J9FDxi = 3852 - INTEGER(IntKi), PARAMETER :: J1FDyi = 3853 - INTEGER(IntKi), PARAMETER :: J2FDyi = 3854 - INTEGER(IntKi), PARAMETER :: J3FDyi = 3855 - INTEGER(IntKi), PARAMETER :: J4FDyi = 3856 - INTEGER(IntKi), PARAMETER :: J5FDyi = 3857 - INTEGER(IntKi), PARAMETER :: J6FDyi = 3858 - INTEGER(IntKi), PARAMETER :: J7FDyi = 3859 - INTEGER(IntKi), PARAMETER :: J8FDyi = 3860 - INTEGER(IntKi), PARAMETER :: J9FDyi = 3861 - INTEGER(IntKi), PARAMETER :: J1FDzi = 3862 - INTEGER(IntKi), PARAMETER :: J2FDzi = 3863 - INTEGER(IntKi), PARAMETER :: J3FDzi = 3864 - INTEGER(IntKi), PARAMETER :: J4FDzi = 3865 - INTEGER(IntKi), PARAMETER :: J5FDzi = 3866 - INTEGER(IntKi), PARAMETER :: J6FDzi = 3867 - INTEGER(IntKi), PARAMETER :: J7FDzi = 3868 - INTEGER(IntKi), PARAMETER :: J8FDzi = 3869 - INTEGER(IntKi), PARAMETER :: J9FDzi = 3870 - INTEGER(IntKi), PARAMETER :: J1FBxi = 3871 - INTEGER(IntKi), PARAMETER :: J2FBxi = 3872 - INTEGER(IntKi), PARAMETER :: J3FBxi = 3873 - INTEGER(IntKi), PARAMETER :: J4FBxi = 3874 - INTEGER(IntKi), PARAMETER :: J5FBxi = 3875 - INTEGER(IntKi), PARAMETER :: J6FBxi = 3876 - INTEGER(IntKi), PARAMETER :: J7FBxi = 3877 - INTEGER(IntKi), PARAMETER :: J8FBxi = 3878 - INTEGER(IntKi), PARAMETER :: J9FBxi = 3879 - INTEGER(IntKi), PARAMETER :: J1FByi = 3880 - INTEGER(IntKi), PARAMETER :: J2FByi = 3881 - INTEGER(IntKi), PARAMETER :: J3FByi = 3882 - INTEGER(IntKi), PARAMETER :: J4FByi = 3883 - INTEGER(IntKi), PARAMETER :: J5FByi = 3884 - INTEGER(IntKi), PARAMETER :: J6FByi = 3885 - INTEGER(IntKi), PARAMETER :: J7FByi = 3886 - INTEGER(IntKi), PARAMETER :: J8FByi = 3887 - INTEGER(IntKi), PARAMETER :: J9FByi = 3888 - INTEGER(IntKi), PARAMETER :: J1FBzi = 3889 - INTEGER(IntKi), PARAMETER :: J2FBzi = 3890 - INTEGER(IntKi), PARAMETER :: J3FBzi = 3891 - INTEGER(IntKi), PARAMETER :: J4FBzi = 3892 - INTEGER(IntKi), PARAMETER :: J5FBzi = 3893 - INTEGER(IntKi), PARAMETER :: J6FBzi = 3894 - INTEGER(IntKi), PARAMETER :: J7FBzi = 3895 - INTEGER(IntKi), PARAMETER :: J8FBzi = 3896 - INTEGER(IntKi), PARAMETER :: J9FBzi = 3897 - INTEGER(IntKi), PARAMETER :: J1MBxi = 3898 - INTEGER(IntKi), PARAMETER :: J2MBxi = 3899 - INTEGER(IntKi), PARAMETER :: J3MBxi = 3900 - INTEGER(IntKi), PARAMETER :: J4MBxi = 3901 - INTEGER(IntKi), PARAMETER :: J5MBxi = 3902 - INTEGER(IntKi), PARAMETER :: J6MBxi = 3903 - INTEGER(IntKi), PARAMETER :: J7MBxi = 3904 - INTEGER(IntKi), PARAMETER :: J8MBxi = 3905 - INTEGER(IntKi), PARAMETER :: J9MBxi = 3906 - INTEGER(IntKi), PARAMETER :: J1MByi = 3907 - INTEGER(IntKi), PARAMETER :: J2MByi = 3908 - INTEGER(IntKi), PARAMETER :: J3MByi = 3909 - INTEGER(IntKi), PARAMETER :: J4MByi = 3910 - INTEGER(IntKi), PARAMETER :: J5MByi = 3911 - INTEGER(IntKi), PARAMETER :: J6MByi = 3912 - INTEGER(IntKi), PARAMETER :: J7MByi = 3913 - INTEGER(IntKi), PARAMETER :: J8MByi = 3914 - INTEGER(IntKi), PARAMETER :: J9MByi = 3915 - INTEGER(IntKi), PARAMETER :: J1MBzi = 3916 - INTEGER(IntKi), PARAMETER :: J2MBzi = 3917 - INTEGER(IntKi), PARAMETER :: J3MBzi = 3918 - INTEGER(IntKi), PARAMETER :: J4MBzi = 3919 - INTEGER(IntKi), PARAMETER :: J5MBzi = 3920 - INTEGER(IntKi), PARAMETER :: J6MBzi = 3921 - INTEGER(IntKi), PARAMETER :: J7MBzi = 3922 - INTEGER(IntKi), PARAMETER :: J8MBzi = 3923 - INTEGER(IntKi), PARAMETER :: J9MBzi = 3924 - INTEGER(IntKi), PARAMETER :: J1FBFxi = 3925 - INTEGER(IntKi), PARAMETER :: J2FBFxi = 3926 - INTEGER(IntKi), PARAMETER :: J3FBFxi = 3927 - INTEGER(IntKi), PARAMETER :: J4FBFxi = 3928 - INTEGER(IntKi), PARAMETER :: J5FBFxi = 3929 - INTEGER(IntKi), PARAMETER :: J6FBFxi = 3930 - INTEGER(IntKi), PARAMETER :: J7FBFxi = 3931 - INTEGER(IntKi), PARAMETER :: J8FBFxi = 3932 - INTEGER(IntKi), PARAMETER :: J9FBFxi = 3933 - INTEGER(IntKi), PARAMETER :: J1FBFyi = 3934 - INTEGER(IntKi), PARAMETER :: J2FBFyi = 3935 - INTEGER(IntKi), PARAMETER :: J3FBFyi = 3936 - INTEGER(IntKi), PARAMETER :: J4FBFyi = 3937 - INTEGER(IntKi), PARAMETER :: J5FBFyi = 3938 - INTEGER(IntKi), PARAMETER :: J6FBFyi = 3939 - INTEGER(IntKi), PARAMETER :: J7FBFyi = 3940 - INTEGER(IntKi), PARAMETER :: J8FBFyi = 3941 - INTEGER(IntKi), PARAMETER :: J9FBFyi = 3942 - INTEGER(IntKi), PARAMETER :: J1FBFzi = 3943 - INTEGER(IntKi), PARAMETER :: J2FBFzi = 3944 - INTEGER(IntKi), PARAMETER :: J3FBFzi = 3945 - INTEGER(IntKi), PARAMETER :: J4FBFzi = 3946 - INTEGER(IntKi), PARAMETER :: J5FBFzi = 3947 - INTEGER(IntKi), PARAMETER :: J6FBFzi = 3948 - INTEGER(IntKi), PARAMETER :: J7FBFzi = 3949 - INTEGER(IntKi), PARAMETER :: J8FBFzi = 3950 - INTEGER(IntKi), PARAMETER :: J9FBFzi = 3951 - INTEGER(IntKi), PARAMETER :: J1MBFxi = 3952 - INTEGER(IntKi), PARAMETER :: J2MBFxi = 3953 - INTEGER(IntKi), PARAMETER :: J3MBFxi = 3954 - INTEGER(IntKi), PARAMETER :: J4MBFxi = 3955 - INTEGER(IntKi), PARAMETER :: J5MBFxi = 3956 - INTEGER(IntKi), PARAMETER :: J6MBFxi = 3957 - INTEGER(IntKi), PARAMETER :: J7MBFxi = 3958 - INTEGER(IntKi), PARAMETER :: J8MBFxi = 3959 - INTEGER(IntKi), PARAMETER :: J9MBFxi = 3960 - INTEGER(IntKi), PARAMETER :: J1MBFyi = 3961 - INTEGER(IntKi), PARAMETER :: J2MBFyi = 3962 - INTEGER(IntKi), PARAMETER :: J3MBFyi = 3963 - INTEGER(IntKi), PARAMETER :: J4MBFyi = 3964 - INTEGER(IntKi), PARAMETER :: J5MBFyi = 3965 - INTEGER(IntKi), PARAMETER :: J6MBFyi = 3966 - INTEGER(IntKi), PARAMETER :: J7MBFyi = 3967 - INTEGER(IntKi), PARAMETER :: J8MBFyi = 3968 - INTEGER(IntKi), PARAMETER :: J9MBFyi = 3969 - INTEGER(IntKi), PARAMETER :: J1MBFzi = 3970 - INTEGER(IntKi), PARAMETER :: J2MBFzi = 3971 - INTEGER(IntKi), PARAMETER :: J3MBFzi = 3972 - INTEGER(IntKi), PARAMETER :: J4MBFzi = 3973 - INTEGER(IntKi), PARAMETER :: J5MBFzi = 3974 - INTEGER(IntKi), PARAMETER :: J6MBFzi = 3975 - INTEGER(IntKi), PARAMETER :: J7MBFzi = 3976 - INTEGER(IntKi), PARAMETER :: J8MBFzi = 3977 - INTEGER(IntKi), PARAMETER :: J9MBFzi = 3978 - INTEGER(IntKi), PARAMETER :: J1FIxi = 3979 - INTEGER(IntKi), PARAMETER :: J2FIxi = 3980 - INTEGER(IntKi), PARAMETER :: J3FIxi = 3981 - INTEGER(IntKi), PARAMETER :: J4FIxi = 3982 - INTEGER(IntKi), PARAMETER :: J5FIxi = 3983 - INTEGER(IntKi), PARAMETER :: J6FIxi = 3984 - INTEGER(IntKi), PARAMETER :: J7FIxi = 3985 - INTEGER(IntKi), PARAMETER :: J8FIxi = 3986 - INTEGER(IntKi), PARAMETER :: J9FIxi = 3987 - INTEGER(IntKi), PARAMETER :: J1FIyi = 3988 - INTEGER(IntKi), PARAMETER :: J2FIyi = 3989 - INTEGER(IntKi), PARAMETER :: J3FIyi = 3990 - INTEGER(IntKi), PARAMETER :: J4FIyi = 3991 - INTEGER(IntKi), PARAMETER :: J5FIyi = 3992 - INTEGER(IntKi), PARAMETER :: J6FIyi = 3993 - INTEGER(IntKi), PARAMETER :: J7FIyi = 3994 - INTEGER(IntKi), PARAMETER :: J8FIyi = 3995 - INTEGER(IntKi), PARAMETER :: J9FIyi = 3996 - INTEGER(IntKi), PARAMETER :: J1FIzi = 3997 - INTEGER(IntKi), PARAMETER :: J2FIzi = 3998 - INTEGER(IntKi), PARAMETER :: J3FIzi = 3999 - INTEGER(IntKi), PARAMETER :: J4FIzi = 4000 - INTEGER(IntKi), PARAMETER :: J5FIzi = 4001 - INTEGER(IntKi), PARAMETER :: J6FIzi = 4002 - INTEGER(IntKi), PARAMETER :: J7FIzi = 4003 - INTEGER(IntKi), PARAMETER :: J8FIzi = 4004 - INTEGER(IntKi), PARAMETER :: J9FIzi = 4005 - INTEGER(IntKi), PARAMETER :: J1FAMxi = 4006 - INTEGER(IntKi), PARAMETER :: J2FAMxi = 4007 - INTEGER(IntKi), PARAMETER :: J3FAMxi = 4008 - INTEGER(IntKi), PARAMETER :: J4FAMxi = 4009 - INTEGER(IntKi), PARAMETER :: J5FAMxi = 4010 - INTEGER(IntKi), PARAMETER :: J6FAMxi = 4011 - INTEGER(IntKi), PARAMETER :: J7FAMxi = 4012 - INTEGER(IntKi), PARAMETER :: J8FAMxi = 4013 - INTEGER(IntKi), PARAMETER :: J9FAMxi = 4014 - INTEGER(IntKi), PARAMETER :: J1FAMyi = 4015 - INTEGER(IntKi), PARAMETER :: J2FAMyi = 4016 - INTEGER(IntKi), PARAMETER :: J3FAMyi = 4017 - INTEGER(IntKi), PARAMETER :: J4FAMyi = 4018 - INTEGER(IntKi), PARAMETER :: J5FAMyi = 4019 - INTEGER(IntKi), PARAMETER :: J6FAMyi = 4020 - INTEGER(IntKi), PARAMETER :: J7FAMyi = 4021 - INTEGER(IntKi), PARAMETER :: J8FAMyi = 4022 - INTEGER(IntKi), PARAMETER :: J9FAMyi = 4023 - INTEGER(IntKi), PARAMETER :: J1FAMzi = 4024 - INTEGER(IntKi), PARAMETER :: J2FAMzi = 4025 - INTEGER(IntKi), PARAMETER :: J3FAMzi = 4026 - INTEGER(IntKi), PARAMETER :: J4FAMzi = 4027 - INTEGER(IntKi), PARAMETER :: J5FAMzi = 4028 - INTEGER(IntKi), PARAMETER :: J6FAMzi = 4029 - INTEGER(IntKi), PARAMETER :: J7FAMzi = 4030 - INTEGER(IntKi), PARAMETER :: J8FAMzi = 4031 - INTEGER(IntKi), PARAMETER :: J9FAMzi = 4032 + ! Joint Loads: + INTEGER(IntKi), PARAMETER :: J1FDxi = 4330 + INTEGER(IntKi), PARAMETER :: J2FDxi = 4331 + INTEGER(IntKi), PARAMETER :: J3FDxi = 4332 + INTEGER(IntKi), PARAMETER :: J4FDxi = 4333 + INTEGER(IntKi), PARAMETER :: J5FDxi = 4334 + INTEGER(IntKi), PARAMETER :: J6FDxi = 4335 + INTEGER(IntKi), PARAMETER :: J7FDxi = 4336 + INTEGER(IntKi), PARAMETER :: J8FDxi = 4337 + INTEGER(IntKi), PARAMETER :: J9FDxi = 4338 + INTEGER(IntKi), PARAMETER :: J1FDyi = 4339 + INTEGER(IntKi), PARAMETER :: J2FDyi = 4340 + INTEGER(IntKi), PARAMETER :: J3FDyi = 4341 + INTEGER(IntKi), PARAMETER :: J4FDyi = 4342 + INTEGER(IntKi), PARAMETER :: J5FDyi = 4343 + INTEGER(IntKi), PARAMETER :: J6FDyi = 4344 + INTEGER(IntKi), PARAMETER :: J7FDyi = 4345 + INTEGER(IntKi), PARAMETER :: J8FDyi = 4346 + INTEGER(IntKi), PARAMETER :: J9FDyi = 4347 + INTEGER(IntKi), PARAMETER :: J1FDzi = 4348 + INTEGER(IntKi), PARAMETER :: J2FDzi = 4349 + INTEGER(IntKi), PARAMETER :: J3FDzi = 4350 + INTEGER(IntKi), PARAMETER :: J4FDzi = 4351 + INTEGER(IntKi), PARAMETER :: J5FDzi = 4352 + INTEGER(IntKi), PARAMETER :: J6FDzi = 4353 + INTEGER(IntKi), PARAMETER :: J7FDzi = 4354 + INTEGER(IntKi), PARAMETER :: J8FDzi = 4355 + INTEGER(IntKi), PARAMETER :: J9FDzi = 4356 + INTEGER(IntKi), PARAMETER :: J1FBxi = 4357 + INTEGER(IntKi), PARAMETER :: J2FBxi = 4358 + INTEGER(IntKi), PARAMETER :: J3FBxi = 4359 + INTEGER(IntKi), PARAMETER :: J4FBxi = 4360 + INTEGER(IntKi), PARAMETER :: J5FBxi = 4361 + INTEGER(IntKi), PARAMETER :: J6FBxi = 4362 + INTEGER(IntKi), PARAMETER :: J7FBxi = 4363 + INTEGER(IntKi), PARAMETER :: J8FBxi = 4364 + INTEGER(IntKi), PARAMETER :: J9FBxi = 4365 + INTEGER(IntKi), PARAMETER :: J1FByi = 4366 + INTEGER(IntKi), PARAMETER :: J2FByi = 4367 + INTEGER(IntKi), PARAMETER :: J3FByi = 4368 + INTEGER(IntKi), PARAMETER :: J4FByi = 4369 + INTEGER(IntKi), PARAMETER :: J5FByi = 4370 + INTEGER(IntKi), PARAMETER :: J6FByi = 4371 + INTEGER(IntKi), PARAMETER :: J7FByi = 4372 + INTEGER(IntKi), PARAMETER :: J8FByi = 4373 + INTEGER(IntKi), PARAMETER :: J9FByi = 4374 + INTEGER(IntKi), PARAMETER :: J1FBzi = 4375 + INTEGER(IntKi), PARAMETER :: J2FBzi = 4376 + INTEGER(IntKi), PARAMETER :: J3FBzi = 4377 + INTEGER(IntKi), PARAMETER :: J4FBzi = 4378 + INTEGER(IntKi), PARAMETER :: J5FBzi = 4379 + INTEGER(IntKi), PARAMETER :: J6FBzi = 4380 + INTEGER(IntKi), PARAMETER :: J7FBzi = 4381 + INTEGER(IntKi), PARAMETER :: J8FBzi = 4382 + INTEGER(IntKi), PARAMETER :: J9FBzi = 4383 + INTEGER(IntKi), PARAMETER :: J1MBxi = 4384 + INTEGER(IntKi), PARAMETER :: J2MBxi = 4385 + INTEGER(IntKi), PARAMETER :: J3MBxi = 4386 + INTEGER(IntKi), PARAMETER :: J4MBxi = 4387 + INTEGER(IntKi), PARAMETER :: J5MBxi = 4388 + INTEGER(IntKi), PARAMETER :: J6MBxi = 4389 + INTEGER(IntKi), PARAMETER :: J7MBxi = 4390 + INTEGER(IntKi), PARAMETER :: J8MBxi = 4391 + INTEGER(IntKi), PARAMETER :: J9MBxi = 4392 + INTEGER(IntKi), PARAMETER :: J1MByi = 4393 + INTEGER(IntKi), PARAMETER :: J2MByi = 4394 + INTEGER(IntKi), PARAMETER :: J3MByi = 4395 + INTEGER(IntKi), PARAMETER :: J4MByi = 4396 + INTEGER(IntKi), PARAMETER :: J5MByi = 4397 + INTEGER(IntKi), PARAMETER :: J6MByi = 4398 + INTEGER(IntKi), PARAMETER :: J7MByi = 4399 + INTEGER(IntKi), PARAMETER :: J8MByi = 4400 + INTEGER(IntKi), PARAMETER :: J9MByi = 4401 + INTEGER(IntKi), PARAMETER :: J1MBzi = 4402 + INTEGER(IntKi), PARAMETER :: J2MBzi = 4403 + INTEGER(IntKi), PARAMETER :: J3MBzi = 4404 + INTEGER(IntKi), PARAMETER :: J4MBzi = 4405 + INTEGER(IntKi), PARAMETER :: J5MBzi = 4406 + INTEGER(IntKi), PARAMETER :: J6MBzi = 4407 + INTEGER(IntKi), PARAMETER :: J7MBzi = 4408 + INTEGER(IntKi), PARAMETER :: J8MBzi = 4409 + INTEGER(IntKi), PARAMETER :: J9MBzi = 4410 + INTEGER(IntKi), PARAMETER :: J1FBFxi = 4411 + INTEGER(IntKi), PARAMETER :: J2FBFxi = 4412 + INTEGER(IntKi), PARAMETER :: J3FBFxi = 4413 + INTEGER(IntKi), PARAMETER :: J4FBFxi = 4414 + INTEGER(IntKi), PARAMETER :: J5FBFxi = 4415 + INTEGER(IntKi), PARAMETER :: J6FBFxi = 4416 + INTEGER(IntKi), PARAMETER :: J7FBFxi = 4417 + INTEGER(IntKi), PARAMETER :: J8FBFxi = 4418 + INTEGER(IntKi), PARAMETER :: J9FBFxi = 4419 + INTEGER(IntKi), PARAMETER :: J1FBFyi = 4420 + INTEGER(IntKi), PARAMETER :: J2FBFyi = 4421 + INTEGER(IntKi), PARAMETER :: J3FBFyi = 4422 + INTEGER(IntKi), PARAMETER :: J4FBFyi = 4423 + INTEGER(IntKi), PARAMETER :: J5FBFyi = 4424 + INTEGER(IntKi), PARAMETER :: J6FBFyi = 4425 + INTEGER(IntKi), PARAMETER :: J7FBFyi = 4426 + INTEGER(IntKi), PARAMETER :: J8FBFyi = 4427 + INTEGER(IntKi), PARAMETER :: J9FBFyi = 4428 + INTEGER(IntKi), PARAMETER :: J1FBFzi = 4429 + INTEGER(IntKi), PARAMETER :: J2FBFzi = 4430 + INTEGER(IntKi), PARAMETER :: J3FBFzi = 4431 + INTEGER(IntKi), PARAMETER :: J4FBFzi = 4432 + INTEGER(IntKi), PARAMETER :: J5FBFzi = 4433 + INTEGER(IntKi), PARAMETER :: J6FBFzi = 4434 + INTEGER(IntKi), PARAMETER :: J7FBFzi = 4435 + INTEGER(IntKi), PARAMETER :: J8FBFzi = 4436 + INTEGER(IntKi), PARAMETER :: J9FBFzi = 4437 + INTEGER(IntKi), PARAMETER :: J1MBFxi = 4438 + INTEGER(IntKi), PARAMETER :: J2MBFxi = 4439 + INTEGER(IntKi), PARAMETER :: J3MBFxi = 4440 + INTEGER(IntKi), PARAMETER :: J4MBFxi = 4441 + INTEGER(IntKi), PARAMETER :: J5MBFxi = 4442 + INTEGER(IntKi), PARAMETER :: J6MBFxi = 4443 + INTEGER(IntKi), PARAMETER :: J7MBFxi = 4444 + INTEGER(IntKi), PARAMETER :: J8MBFxi = 4445 + INTEGER(IntKi), PARAMETER :: J9MBFxi = 4446 + INTEGER(IntKi), PARAMETER :: J1MBFyi = 4447 + INTEGER(IntKi), PARAMETER :: J2MBFyi = 4448 + INTEGER(IntKi), PARAMETER :: J3MBFyi = 4449 + INTEGER(IntKi), PARAMETER :: J4MBFyi = 4450 + INTEGER(IntKi), PARAMETER :: J5MBFyi = 4451 + INTEGER(IntKi), PARAMETER :: J6MBFyi = 4452 + INTEGER(IntKi), PARAMETER :: J7MBFyi = 4453 + INTEGER(IntKi), PARAMETER :: J8MBFyi = 4454 + INTEGER(IntKi), PARAMETER :: J9MBFyi = 4455 + INTEGER(IntKi), PARAMETER :: J1MBFzi = 4456 + INTEGER(IntKi), PARAMETER :: J2MBFzi = 4457 + INTEGER(IntKi), PARAMETER :: J3MBFzi = 4458 + INTEGER(IntKi), PARAMETER :: J4MBFzi = 4459 + INTEGER(IntKi), PARAMETER :: J5MBFzi = 4460 + INTEGER(IntKi), PARAMETER :: J6MBFzi = 4461 + INTEGER(IntKi), PARAMETER :: J7MBFzi = 4462 + INTEGER(IntKi), PARAMETER :: J8MBFzi = 4463 + INTEGER(IntKi), PARAMETER :: J9MBFzi = 4464 + INTEGER(IntKi), PARAMETER :: J1FIxi = 4465 + INTEGER(IntKi), PARAMETER :: J2FIxi = 4466 + INTEGER(IntKi), PARAMETER :: J3FIxi = 4467 + INTEGER(IntKi), PARAMETER :: J4FIxi = 4468 + INTEGER(IntKi), PARAMETER :: J5FIxi = 4469 + INTEGER(IntKi), PARAMETER :: J6FIxi = 4470 + INTEGER(IntKi), PARAMETER :: J7FIxi = 4471 + INTEGER(IntKi), PARAMETER :: J8FIxi = 4472 + INTEGER(IntKi), PARAMETER :: J9FIxi = 4473 + INTEGER(IntKi), PARAMETER :: J1FIyi = 4474 + INTEGER(IntKi), PARAMETER :: J2FIyi = 4475 + INTEGER(IntKi), PARAMETER :: J3FIyi = 4476 + INTEGER(IntKi), PARAMETER :: J4FIyi = 4477 + INTEGER(IntKi), PARAMETER :: J5FIyi = 4478 + INTEGER(IntKi), PARAMETER :: J6FIyi = 4479 + INTEGER(IntKi), PARAMETER :: J7FIyi = 4480 + INTEGER(IntKi), PARAMETER :: J8FIyi = 4481 + INTEGER(IntKi), PARAMETER :: J9FIyi = 4482 + INTEGER(IntKi), PARAMETER :: J1FIzi = 4483 + INTEGER(IntKi), PARAMETER :: J2FIzi = 4484 + INTEGER(IntKi), PARAMETER :: J3FIzi = 4485 + INTEGER(IntKi), PARAMETER :: J4FIzi = 4486 + INTEGER(IntKi), PARAMETER :: J5FIzi = 4487 + INTEGER(IntKi), PARAMETER :: J6FIzi = 4488 + INTEGER(IntKi), PARAMETER :: J7FIzi = 4489 + INTEGER(IntKi), PARAMETER :: J8FIzi = 4490 + INTEGER(IntKi), PARAMETER :: J9FIzi = 4491 + INTEGER(IntKi), PARAMETER :: J1FAMxi = 4492 + INTEGER(IntKi), PARAMETER :: J2FAMxi = 4493 + INTEGER(IntKi), PARAMETER :: J3FAMxi = 4494 + INTEGER(IntKi), PARAMETER :: J4FAMxi = 4495 + INTEGER(IntKi), PARAMETER :: J5FAMxi = 4496 + INTEGER(IntKi), PARAMETER :: J6FAMxi = 4497 + INTEGER(IntKi), PARAMETER :: J7FAMxi = 4498 + INTEGER(IntKi), PARAMETER :: J8FAMxi = 4499 + INTEGER(IntKi), PARAMETER :: J9FAMxi = 4500 + INTEGER(IntKi), PARAMETER :: J1FAMyi = 4501 + INTEGER(IntKi), PARAMETER :: J2FAMyi = 4502 + INTEGER(IntKi), PARAMETER :: J3FAMyi = 4503 + INTEGER(IntKi), PARAMETER :: J4FAMyi = 4504 + INTEGER(IntKi), PARAMETER :: J5FAMyi = 4505 + INTEGER(IntKi), PARAMETER :: J6FAMyi = 4506 + INTEGER(IntKi), PARAMETER :: J7FAMyi = 4507 + INTEGER(IntKi), PARAMETER :: J8FAMyi = 4508 + INTEGER(IntKi), PARAMETER :: J9FAMyi = 4509 + INTEGER(IntKi), PARAMETER :: J1FAMzi = 4510 + INTEGER(IntKi), PARAMETER :: J2FAMzi = 4511 + INTEGER(IntKi), PARAMETER :: J3FAMzi = 4512 + INTEGER(IntKi), PARAMETER :: J4FAMzi = 4513 + INTEGER(IntKi), PARAMETER :: J5FAMzi = 4514 + INTEGER(IntKi), PARAMETER :: J6FAMzi = 4515 + INTEGER(IntKi), PARAMETER :: J7FAMzi = 4516 + INTEGER(IntKi), PARAMETER :: J8FAMzi = 4517 + INTEGER(IntKi), PARAMETER :: J9FAMzi = 4518 + INTEGER(IntKi), PARAMETER :: J1FAGxi = 4519 + INTEGER(IntKi), PARAMETER :: J2FAGxi = 4520 + INTEGER(IntKi), PARAMETER :: J3FAGxi = 4521 + INTEGER(IntKi), PARAMETER :: J4FAGxi = 4522 + INTEGER(IntKi), PARAMETER :: J5FAGxi = 4523 + INTEGER(IntKi), PARAMETER :: J6FAGxi = 4524 + INTEGER(IntKi), PARAMETER :: J7FAGxi = 4525 + INTEGER(IntKi), PARAMETER :: J8FAGxi = 4526 + INTEGER(IntKi), PARAMETER :: J9FAGxi = 4527 + INTEGER(IntKi), PARAMETER :: J1FAGyi = 4528 + INTEGER(IntKi), PARAMETER :: J2FAGyi = 4529 + INTEGER(IntKi), PARAMETER :: J3FAGyi = 4530 + INTEGER(IntKi), PARAMETER :: J4FAGyi = 4531 + INTEGER(IntKi), PARAMETER :: J5FAGyi = 4532 + INTEGER(IntKi), PARAMETER :: J6FAGyi = 4533 + INTEGER(IntKi), PARAMETER :: J7FAGyi = 4534 + INTEGER(IntKi), PARAMETER :: J8FAGyi = 4535 + INTEGER(IntKi), PARAMETER :: J9FAGyi = 4536 + INTEGER(IntKi), PARAMETER :: J1FAGzi = 4537 + INTEGER(IntKi), PARAMETER :: J2FAGzi = 4538 + INTEGER(IntKi), PARAMETER :: J3FAGzi = 4539 + INTEGER(IntKi), PARAMETER :: J4FAGzi = 4540 + INTEGER(IntKi), PARAMETER :: J5FAGzi = 4541 + INTEGER(IntKi), PARAMETER :: J6FAGzi = 4542 + INTEGER(IntKi), PARAMETER :: J7FAGzi = 4543 + INTEGER(IntKi), PARAMETER :: J8FAGzi = 4544 + INTEGER(IntKi), PARAMETER :: J9FAGzi = 4545 + INTEGER(IntKi), PARAMETER :: J1MAGxi = 4546 + INTEGER(IntKi), PARAMETER :: J2MAGxi = 4547 + INTEGER(IntKi), PARAMETER :: J3MAGxi = 4548 + INTEGER(IntKi), PARAMETER :: J4MAGxi = 4549 + INTEGER(IntKi), PARAMETER :: J5MAGxi = 4550 + INTEGER(IntKi), PARAMETER :: J6MAGxi = 4551 + INTEGER(IntKi), PARAMETER :: J7MAGxi = 4552 + INTEGER(IntKi), PARAMETER :: J8MAGxi = 4553 + INTEGER(IntKi), PARAMETER :: J9MAGxi = 4554 + INTEGER(IntKi), PARAMETER :: J1MAGyi = 4555 + INTEGER(IntKi), PARAMETER :: J2MAGyi = 4556 + INTEGER(IntKi), PARAMETER :: J3MAGyi = 4557 + INTEGER(IntKi), PARAMETER :: J4MAGyi = 4558 + INTEGER(IntKi), PARAMETER :: J5MAGyi = 4559 + INTEGER(IntKi), PARAMETER :: J6MAGyi = 4560 + INTEGER(IntKi), PARAMETER :: J7MAGyi = 4561 + INTEGER(IntKi), PARAMETER :: J8MAGyi = 4562 + INTEGER(IntKi), PARAMETER :: J9MAGyi = 4563 + INTEGER(IntKi), PARAMETER :: J1MAGzi = 4564 + INTEGER(IntKi), PARAMETER :: J2MAGzi = 4565 + INTEGER(IntKi), PARAMETER :: J3MAGzi = 4566 + INTEGER(IntKi), PARAMETER :: J4MAGzi = 4567 + INTEGER(IntKi), PARAMETER :: J5MAGzi = 4568 + INTEGER(IntKi), PARAMETER :: J6MAGzi = 4569 + INTEGER(IntKi), PARAMETER :: J7MAGzi = 4570 + INTEGER(IntKi), PARAMETER :: J8MAGzi = 4571 + INTEGER(IntKi), PARAMETER :: J9MAGzi = 4572 + INTEGER(IntKi), PARAMETER :: J1FMGxi = 4573 + INTEGER(IntKi), PARAMETER :: J2FMGxi = 4574 + INTEGER(IntKi), PARAMETER :: J3FMGxi = 4575 + INTEGER(IntKi), PARAMETER :: J4FMGxi = 4576 + INTEGER(IntKi), PARAMETER :: J5FMGxi = 4577 + INTEGER(IntKi), PARAMETER :: J6FMGxi = 4578 + INTEGER(IntKi), PARAMETER :: J7FMGxi = 4579 + INTEGER(IntKi), PARAMETER :: J8FMGxi = 4580 + INTEGER(IntKi), PARAMETER :: J9FMGxi = 4581 + INTEGER(IntKi), PARAMETER :: J1FMGyi = 4582 + INTEGER(IntKi), PARAMETER :: J2FMGyi = 4583 + INTEGER(IntKi), PARAMETER :: J3FMGyi = 4584 + INTEGER(IntKi), PARAMETER :: J4FMGyi = 4585 + INTEGER(IntKi), PARAMETER :: J5FMGyi = 4586 + INTEGER(IntKi), PARAMETER :: J6FMGyi = 4587 + INTEGER(IntKi), PARAMETER :: J7FMGyi = 4588 + INTEGER(IntKi), PARAMETER :: J8FMGyi = 4589 + INTEGER(IntKi), PARAMETER :: J9FMGyi = 4590 + INTEGER(IntKi), PARAMETER :: J1FMGzi = 4591 + INTEGER(IntKi), PARAMETER :: J2FMGzi = 4592 + INTEGER(IntKi), PARAMETER :: J3FMGzi = 4593 + INTEGER(IntKi), PARAMETER :: J4FMGzi = 4594 + INTEGER(IntKi), PARAMETER :: J5FMGzi = 4595 + INTEGER(IntKi), PARAMETER :: J6FMGzi = 4596 + INTEGER(IntKi), PARAMETER :: J7FMGzi = 4597 + INTEGER(IntKi), PARAMETER :: J8FMGzi = 4598 + INTEGER(IntKi), PARAMETER :: J9FMGzi = 4599 !End of code generated by Matlab script @@ -5020,6 +5585,88 @@ MODULE Morison_Output M9N8FMGxi,M9N8FMGyi,M9N8FMGzi, & M9N9FMGxi,M9N9FMGyi,M9N9FMGzi/), (/3,9,9/)) + INTEGER, PARAMETER :: MNMMGi(3,9,9) = reshape((/M1N1MMGxi,M1N1MMGyi,M1N1MMGzi, & + M1N2MMGxi,M1N2MMGyi,M1N2MMGzi, & + M1N3MMGxi,M1N3MMGyi,M1N3MMGzi, & + M1N4MMGxi,M1N4MMGyi,M1N4MMGzi, & + M1N5MMGxi,M1N5MMGyi,M1N5MMGzi, & + M1N6MMGxi,M1N6MMGyi,M1N6MMGzi, & + M1N7MMGxi,M1N7MMGyi,M1N7MMGzi, & + M1N8MMGxi,M1N8MMGyi,M1N8MMGzi, & + M1N9MMGxi,M1N9MMGyi,M1N9MMGzi, & + M2N1MMGxi,M2N1MMGyi,M2N1MMGzi, & + M2N2MMGxi,M2N2MMGyi,M2N2MMGzi, & + M2N3MMGxi,M2N3MMGyi,M2N3MMGzi, & + M2N4MMGxi,M2N4MMGyi,M2N4MMGzi, & + M2N5MMGxi,M2N5MMGyi,M2N5MMGzi, & + M2N6MMGxi,M2N6MMGyi,M2N6MMGzi, & + M2N7MMGxi,M2N7MMGyi,M2N7MMGzi, & + M2N8MMGxi,M2N8MMGyi,M2N8MMGzi, & + M2N9MMGxi,M2N9MMGyi,M2N9MMGzi, & + M3N1MMGxi,M3N1MMGyi,M3N1MMGzi, & + M3N2MMGxi,M3N2MMGyi,M3N2MMGzi, & + M3N3MMGxi,M3N3MMGyi,M3N3MMGzi, & + M3N4MMGxi,M3N4MMGyi,M3N4MMGzi, & + M3N5MMGxi,M3N5MMGyi,M3N5MMGzi, & + M3N6MMGxi,M3N6MMGyi,M3N6MMGzi, & + M3N7MMGxi,M3N7MMGyi,M3N7MMGzi, & + M3N8MMGxi,M3N8MMGyi,M3N8MMGzi, & + M3N9MMGxi,M3N9MMGyi,M3N9MMGzi, & + M4N1MMGxi,M4N1MMGyi,M4N1MMGzi, & + M4N2MMGxi,M4N2MMGyi,M4N2MMGzi, & + M4N3MMGxi,M4N3MMGyi,M4N3MMGzi, & + M4N4MMGxi,M4N4MMGyi,M4N4MMGzi, & + M4N5MMGxi,M4N5MMGyi,M4N5MMGzi, & + M4N6MMGxi,M4N6MMGyi,M4N6MMGzi, & + M4N7MMGxi,M4N7MMGyi,M4N7MMGzi, & + M4N8MMGxi,M4N8MMGyi,M4N8MMGzi, & + M4N9MMGxi,M4N9MMGyi,M4N9MMGzi, & + M5N1MMGxi,M5N1MMGyi,M5N1MMGzi, & + M5N2MMGxi,M5N2MMGyi,M5N2MMGzi, & + M5N3MMGxi,M5N3MMGyi,M5N3MMGzi, & + M5N4MMGxi,M5N4MMGyi,M5N4MMGzi, & + M5N5MMGxi,M5N5MMGyi,M5N5MMGzi, & + M5N6MMGxi,M5N6MMGyi,M5N6MMGzi, & + M5N7MMGxi,M5N7MMGyi,M5N7MMGzi, & + M5N8MMGxi,M5N8MMGyi,M5N8MMGzi, & + M5N9MMGxi,M5N9MMGyi,M5N9MMGzi, & + M6N1MMGxi,M6N1MMGyi,M6N1MMGzi, & + M6N2MMGxi,M6N2MMGyi,M6N2MMGzi, & + M6N3MMGxi,M6N3MMGyi,M6N3MMGzi, & + M6N4MMGxi,M6N4MMGyi,M6N4MMGzi, & + M6N5MMGxi,M6N5MMGyi,M6N5MMGzi, & + M6N6MMGxi,M6N6MMGyi,M6N6MMGzi, & + M6N7MMGxi,M6N7MMGyi,M6N7MMGzi, & + M6N8MMGxi,M6N8MMGyi,M6N8MMGzi, & + M6N9MMGxi,M6N9MMGyi,M6N9MMGzi, & + M7N1MMGxi,M7N1MMGyi,M7N1MMGzi, & + M7N2MMGxi,M7N2MMGyi,M7N2MMGzi, & + M7N3MMGxi,M7N3MMGyi,M7N3MMGzi, & + M7N4MMGxi,M7N4MMGyi,M7N4MMGzi, & + M7N5MMGxi,M7N5MMGyi,M7N5MMGzi, & + M7N6MMGxi,M7N6MMGyi,M7N6MMGzi, & + M7N7MMGxi,M7N7MMGyi,M7N7MMGzi, & + M7N8MMGxi,M7N8MMGyi,M7N8MMGzi, & + M7N9MMGxi,M7N9MMGyi,M7N9MMGzi, & + M8N1MMGxi,M8N1MMGyi,M8N1MMGzi, & + M8N2MMGxi,M8N2MMGyi,M8N2MMGzi, & + M8N3MMGxi,M8N3MMGyi,M8N3MMGzi, & + M8N4MMGxi,M8N4MMGyi,M8N4MMGzi, & + M8N5MMGxi,M8N5MMGyi,M8N5MMGzi, & + M8N6MMGxi,M8N6MMGyi,M8N6MMGzi, & + M8N7MMGxi,M8N7MMGyi,M8N7MMGzi, & + M8N8MMGxi,M8N8MMGyi,M8N8MMGzi, & + M8N9MMGxi,M8N9MMGyi,M8N9MMGzi, & + M9N1MMGxi,M9N1MMGyi,M9N1MMGzi, & + M9N2MMGxi,M9N2MMGyi,M9N2MMGzi, & + M9N3MMGxi,M9N3MMGyi,M9N3MMGzi, & + M9N4MMGxi,M9N4MMGyi,M9N4MMGzi, & + M9N5MMGxi,M9N5MMGyi,M9N5MMGzi, & + M9N6MMGxi,M9N6MMGyi,M9N6MMGzi, & + M9N7MMGxi,M9N7MMGyi,M9N7MMGzi, & + M9N8MMGxi,M9N8MMGyi,M9N8MMGzi, & + M9N9MMGxi,M9N9MMGyi,M9N9MMGzi/), (/3,9,9/)) + INTEGER, PARAMETER :: MNMBi(3,9,9) = reshape((/M1N1MBxi,M1N1MByi,M1N1MBzi, & M1N2MBxi,M1N2MByi,M1N2MBzi, & M1N3MBxi,M1N3MByi,M1N3MBzi, & @@ -5348,6 +5995,88 @@ MODULE Morison_Output M9N8FAGxi,M9N8FAGyi,M9N8FAGzi, & M9N9FAGxi,M9N9FAGyi,M9N9FAGzi/), (/3,9,9/)) + INTEGER, PARAMETER :: MNMAGi(3,9,9) = reshape((/M1N1MAGxi,M1N1MAGyi,M1N1MAGzi, & + M1N2MAGxi,M1N2MAGyi,M1N2MAGzi, & + M1N3MAGxi,M1N3MAGyi,M1N3MAGzi, & + M1N4MAGxi,M1N4MAGyi,M1N4MAGzi, & + M1N5MAGxi,M1N5MAGyi,M1N5MAGzi, & + M1N6MAGxi,M1N6MAGyi,M1N6MAGzi, & + M1N7MAGxi,M1N7MAGyi,M1N7MAGzi, & + M1N8MAGxi,M1N8MAGyi,M1N8MAGzi, & + M1N9MAGxi,M1N9MAGyi,M1N9MAGzi, & + M2N1MAGxi,M2N1MAGyi,M2N1MAGzi, & + M2N2MAGxi,M2N2MAGyi,M2N2MAGzi, & + M2N3MAGxi,M2N3MAGyi,M2N3MAGzi, & + M2N4MAGxi,M2N4MAGyi,M2N4MAGzi, & + M2N5MAGxi,M2N5MAGyi,M2N5MAGzi, & + M2N6MAGxi,M2N6MAGyi,M2N6MAGzi, & + M2N7MAGxi,M2N7MAGyi,M2N7MAGzi, & + M2N8MAGxi,M2N8MAGyi,M2N8MAGzi, & + M2N9MAGxi,M2N9MAGyi,M2N9MAGzi, & + M3N1MAGxi,M3N1MAGyi,M3N1MAGzi, & + M3N2MAGxi,M3N2MAGyi,M3N2MAGzi, & + M3N3MAGxi,M3N3MAGyi,M3N3MAGzi, & + M3N4MAGxi,M3N4MAGyi,M3N4MAGzi, & + M3N5MAGxi,M3N5MAGyi,M3N5MAGzi, & + M3N6MAGxi,M3N6MAGyi,M3N6MAGzi, & + M3N7MAGxi,M3N7MAGyi,M3N7MAGzi, & + M3N8MAGxi,M3N8MAGyi,M3N8MAGzi, & + M3N9MAGxi,M3N9MAGyi,M3N9MAGzi, & + M4N1MAGxi,M4N1MAGyi,M4N1MAGzi, & + M4N2MAGxi,M4N2MAGyi,M4N2MAGzi, & + M4N3MAGxi,M4N3MAGyi,M4N3MAGzi, & + M4N4MAGxi,M4N4MAGyi,M4N4MAGzi, & + M4N5MAGxi,M4N5MAGyi,M4N5MAGzi, & + M4N6MAGxi,M4N6MAGyi,M4N6MAGzi, & + M4N7MAGxi,M4N7MAGyi,M4N7MAGzi, & + M4N8MAGxi,M4N8MAGyi,M4N8MAGzi, & + M4N9MAGxi,M4N9MAGyi,M4N9MAGzi, & + M5N1MAGxi,M5N1MAGyi,M5N1MAGzi, & + M5N2MAGxi,M5N2MAGyi,M5N2MAGzi, & + M5N3MAGxi,M5N3MAGyi,M5N3MAGzi, & + M5N4MAGxi,M5N4MAGyi,M5N4MAGzi, & + M5N5MAGxi,M5N5MAGyi,M5N5MAGzi, & + M5N6MAGxi,M5N6MAGyi,M5N6MAGzi, & + M5N7MAGxi,M5N7MAGyi,M5N7MAGzi, & + M5N8MAGxi,M5N8MAGyi,M5N8MAGzi, & + M5N9MAGxi,M5N9MAGyi,M5N9MAGzi, & + M6N1MAGxi,M6N1MAGyi,M6N1MAGzi, & + M6N2MAGxi,M6N2MAGyi,M6N2MAGzi, & + M6N3MAGxi,M6N3MAGyi,M6N3MAGzi, & + M6N4MAGxi,M6N4MAGyi,M6N4MAGzi, & + M6N5MAGxi,M6N5MAGyi,M6N5MAGzi, & + M6N6MAGxi,M6N6MAGyi,M6N6MAGzi, & + M6N7MAGxi,M6N7MAGyi,M6N7MAGzi, & + M6N8MAGxi,M6N8MAGyi,M6N8MAGzi, & + M6N9MAGxi,M6N9MAGyi,M6N9MAGzi, & + M7N1MAGxi,M7N1MAGyi,M7N1MAGzi, & + M7N2MAGxi,M7N2MAGyi,M7N2MAGzi, & + M7N3MAGxi,M7N3MAGyi,M7N3MAGzi, & + M7N4MAGxi,M7N4MAGyi,M7N4MAGzi, & + M7N5MAGxi,M7N5MAGyi,M7N5MAGzi, & + M7N6MAGxi,M7N6MAGyi,M7N6MAGzi, & + M7N7MAGxi,M7N7MAGyi,M7N7MAGzi, & + M7N8MAGxi,M7N8MAGyi,M7N8MAGzi, & + M7N9MAGxi,M7N9MAGyi,M7N9MAGzi, & + M8N1MAGxi,M8N1MAGyi,M8N1MAGzi, & + M8N2MAGxi,M8N2MAGyi,M8N2MAGzi, & + M8N3MAGxi,M8N3MAGyi,M8N3MAGzi, & + M8N4MAGxi,M8N4MAGyi,M8N4MAGzi, & + M8N5MAGxi,M8N5MAGyi,M8N5MAGzi, & + M8N6MAGxi,M8N6MAGyi,M8N6MAGzi, & + M8N7MAGxi,M8N7MAGyi,M8N7MAGzi, & + M8N8MAGxi,M8N8MAGyi,M8N8MAGzi, & + M8N9MAGxi,M8N9MAGyi,M8N9MAGzi, & + M9N1MAGxi,M9N1MAGyi,M9N1MAGzi, & + M9N2MAGxi,M9N2MAGyi,M9N2MAGzi, & + M9N3MAGxi,M9N3MAGyi,M9N3MAGzi, & + M9N4MAGxi,M9N4MAGyi,M9N4MAGzi, & + M9N5MAGxi,M9N5MAGyi,M9N5MAGzi, & + M9N6MAGxi,M9N6MAGyi,M9N6MAGzi, & + M9N7MAGxi,M9N7MAGyi,M9N7MAGzi, & + M9N8MAGxi,M9N8MAGyi,M9N8MAGzi, & + M9N9MAGxi,M9N9MAGyi,M9N9MAGzi/), (/3,9,9/)) + INTEGER, PARAMETER :: MNFAFi(3,9,9) = reshape((/M1N1FAFxi,M1N1FAFyi,M1N1FAFzi, & M1N2FAFxi,M1N2FAFyi,M1N2FAFzi, & M1N3FAFxi,M1N3FAFyi,M1N3FAFzi, & @@ -5430,87 +6159,87 @@ MODULE Morison_Output M9N8FAFxi,M9N8FAFyi,M9N8FAFzi, & M9N9FAFxi,M9N9FAFyi,M9N9FAFzi/), (/3,9,9/)) - INTEGER, PARAMETER :: MNFAi(3,9,9) = reshape((/M1N1FAxi,M1N1FAyi,M1N1FAzi, & - M1N2FAxi,M1N2FAyi,M1N2FAzi, & - M1N3FAxi,M1N3FAyi,M1N3FAzi, & - M1N4FAxi,M1N4FAyi,M1N4FAzi, & - M1N5FAxi,M1N5FAyi,M1N5FAzi, & - M1N6FAxi,M1N6FAyi,M1N6FAzi, & - M1N7FAxi,M1N7FAyi,M1N7FAzi, & - M1N8FAxi,M1N8FAyi,M1N8FAzi, & - M1N9FAxi,M1N9FAyi,M1N9FAzi, & - M2N1FAxi,M2N1FAyi,M2N1FAzi, & - M2N2FAxi,M2N2FAyi,M2N2FAzi, & - M2N3FAxi,M2N3FAyi,M2N3FAzi, & - M2N4FAxi,M2N4FAyi,M2N4FAzi, & - M2N5FAxi,M2N5FAyi,M2N5FAzi, & - M2N6FAxi,M2N6FAyi,M2N6FAzi, & - M2N7FAxi,M2N7FAyi,M2N7FAzi, & - M2N8FAxi,M2N8FAyi,M2N8FAzi, & - M2N9FAxi,M2N9FAyi,M2N9FAzi, & - M3N1FAxi,M3N1FAyi,M3N1FAzi, & - M3N2FAxi,M3N2FAyi,M3N2FAzi, & - M3N3FAxi,M3N3FAyi,M3N3FAzi, & - M3N4FAxi,M3N4FAyi,M3N4FAzi, & - M3N5FAxi,M3N5FAyi,M3N5FAzi, & - M3N6FAxi,M3N6FAyi,M3N6FAzi, & - M3N7FAxi,M3N7FAyi,M3N7FAzi, & - M3N8FAxi,M3N8FAyi,M3N8FAzi, & - M3N9FAxi,M3N9FAyi,M3N9FAzi, & - M4N1FAxi,M4N1FAyi,M4N1FAzi, & - M4N2FAxi,M4N2FAyi,M4N2FAzi, & - M4N3FAxi,M4N3FAyi,M4N3FAzi, & - M4N4FAxi,M4N4FAyi,M4N4FAzi, & - M4N5FAxi,M4N5FAyi,M4N5FAzi, & - M4N6FAxi,M4N6FAyi,M4N6FAzi, & - M4N7FAxi,M4N7FAyi,M4N7FAzi, & - M4N8FAxi,M4N8FAyi,M4N8FAzi, & - M4N9FAxi,M4N9FAyi,M4N9FAzi, & - M5N1FAxi,M5N1FAyi,M5N1FAzi, & - M5N2FAxi,M5N2FAyi,M5N2FAzi, & - M5N3FAxi,M5N3FAyi,M5N3FAzi, & - M5N4FAxi,M5N4FAyi,M5N4FAzi, & - M5N5FAxi,M5N5FAyi,M5N5FAzi, & - M5N6FAxi,M5N6FAyi,M5N6FAzi, & - M5N7FAxi,M5N7FAyi,M5N7FAzi, & - M5N8FAxi,M5N8FAyi,M5N8FAzi, & - M5N9FAxi,M5N9FAyi,M5N9FAzi, & - M6N1FAxi,M6N1FAyi,M6N1FAzi, & - M6N2FAxi,M6N2FAyi,M6N2FAzi, & - M6N3FAxi,M6N3FAyi,M6N3FAzi, & - M6N4FAxi,M6N4FAyi,M6N4FAzi, & - M6N5FAxi,M6N5FAyi,M6N5FAzi, & - M6N6FAxi,M6N6FAyi,M6N6FAzi, & - M6N7FAxi,M6N7FAyi,M6N7FAzi, & - M6N8FAxi,M6N8FAyi,M6N8FAzi, & - M6N9FAxi,M6N9FAyi,M6N9FAzi, & - M7N1FAxi,M7N1FAyi,M7N1FAzi, & - M7N2FAxi,M7N2FAyi,M7N2FAzi, & - M7N3FAxi,M7N3FAyi,M7N3FAzi, & - M7N4FAxi,M7N4FAyi,M7N4FAzi, & - M7N5FAxi,M7N5FAyi,M7N5FAzi, & - M7N6FAxi,M7N6FAyi,M7N6FAzi, & - M7N7FAxi,M7N7FAyi,M7N7FAzi, & - M7N8FAxi,M7N8FAyi,M7N8FAzi, & - M7N9FAxi,M7N9FAyi,M7N9FAzi, & - M8N1FAxi,M8N1FAyi,M8N1FAzi, & - M8N2FAxi,M8N2FAyi,M8N2FAzi, & - M8N3FAxi,M8N3FAyi,M8N3FAzi, & - M8N4FAxi,M8N4FAyi,M8N4FAzi, & - M8N5FAxi,M8N5FAyi,M8N5FAzi, & - M8N6FAxi,M8N6FAyi,M8N6FAzi, & - M8N7FAxi,M8N7FAyi,M8N7FAzi, & - M8N8FAxi,M8N8FAyi,M8N8FAzi, & - M8N9FAxi,M8N9FAyi,M8N9FAzi, & - M9N1FAxi,M9N1FAyi,M9N1FAzi, & - M9N2FAxi,M9N2FAyi,M9N2FAzi, & - M9N3FAxi,M9N3FAyi,M9N3FAzi, & - M9N4FAxi,M9N4FAyi,M9N4FAzi, & - M9N5FAxi,M9N5FAyi,M9N5FAzi, & - M9N6FAxi,M9N6FAyi,M9N6FAzi, & - M9N7FAxi,M9N7FAyi,M9N7FAzi, & - M9N8FAxi,M9N8FAyi,M9N8FAzi, & - M9N9FAxi,M9N9FAyi,M9N9FAzi/), (/3,9,9/)) + INTEGER, PARAMETER :: MNMAFi(3,9,9) = reshape((/M1N1MAFxi,M1N1MAFyi,M1N1MAFzi, & + M1N2MAFxi,M1N2MAFyi,M1N2MAFzi, & + M1N3MAFxi,M1N3MAFyi,M1N3MAFzi, & + M1N4MAFxi,M1N4MAFyi,M1N4MAFzi, & + M1N5MAFxi,M1N5MAFyi,M1N5MAFzi, & + M1N6MAFxi,M1N6MAFyi,M1N6MAFzi, & + M1N7MAFxi,M1N7MAFyi,M1N7MAFzi, & + M1N8MAFxi,M1N8MAFyi,M1N8MAFzi, & + M1N9MAFxi,M1N9MAFyi,M1N9MAFzi, & + M2N1MAFxi,M2N1MAFyi,M2N1MAFzi, & + M2N2MAFxi,M2N2MAFyi,M2N2MAFzi, & + M2N3MAFxi,M2N3MAFyi,M2N3MAFzi, & + M2N4MAFxi,M2N4MAFyi,M2N4MAFzi, & + M2N5MAFxi,M2N5MAFyi,M2N5MAFzi, & + M2N6MAFxi,M2N6MAFyi,M2N6MAFzi, & + M2N7MAFxi,M2N7MAFyi,M2N7MAFzi, & + M2N8MAFxi,M2N8MAFyi,M2N8MAFzi, & + M2N9MAFxi,M2N9MAFyi,M2N9MAFzi, & + M3N1MAFxi,M3N1MAFyi,M3N1MAFzi, & + M3N2MAFxi,M3N2MAFyi,M3N2MAFzi, & + M3N3MAFxi,M3N3MAFyi,M3N3MAFzi, & + M3N4MAFxi,M3N4MAFyi,M3N4MAFzi, & + M3N5MAFxi,M3N5MAFyi,M3N5MAFzi, & + M3N6MAFxi,M3N6MAFyi,M3N6MAFzi, & + M3N7MAFxi,M3N7MAFyi,M3N7MAFzi, & + M3N8MAFxi,M3N8MAFyi,M3N8MAFzi, & + M3N9MAFxi,M3N9MAFyi,M3N9MAFzi, & + M4N1MAFxi,M4N1MAFyi,M4N1MAFzi, & + M4N2MAFxi,M4N2MAFyi,M4N2MAFzi, & + M4N3MAFxi,M4N3MAFyi,M4N3MAFzi, & + M4N4MAFxi,M4N4MAFyi,M4N4MAFzi, & + M4N5MAFxi,M4N5MAFyi,M4N5MAFzi, & + M4N6MAFxi,M4N6MAFyi,M4N6MAFzi, & + M4N7MAFxi,M4N7MAFyi,M4N7MAFzi, & + M4N8MAFxi,M4N8MAFyi,M4N8MAFzi, & + M4N9MAFxi,M4N9MAFyi,M4N9MAFzi, & + M5N1MAFxi,M5N1MAFyi,M5N1MAFzi, & + M5N2MAFxi,M5N2MAFyi,M5N2MAFzi, & + M5N3MAFxi,M5N3MAFyi,M5N3MAFzi, & + M5N4MAFxi,M5N4MAFyi,M5N4MAFzi, & + M5N5MAFxi,M5N5MAFyi,M5N5MAFzi, & + M5N6MAFxi,M5N6MAFyi,M5N6MAFzi, & + M5N7MAFxi,M5N7MAFyi,M5N7MAFzi, & + M5N8MAFxi,M5N8MAFyi,M5N8MAFzi, & + M5N9MAFxi,M5N9MAFyi,M5N9MAFzi, & + M6N1MAFxi,M6N1MAFyi,M6N1MAFzi, & + M6N2MAFxi,M6N2MAFyi,M6N2MAFzi, & + M6N3MAFxi,M6N3MAFyi,M6N3MAFzi, & + M6N4MAFxi,M6N4MAFyi,M6N4MAFzi, & + M6N5MAFxi,M6N5MAFyi,M6N5MAFzi, & + M6N6MAFxi,M6N6MAFyi,M6N6MAFzi, & + M6N7MAFxi,M6N7MAFyi,M6N7MAFzi, & + M6N8MAFxi,M6N8MAFyi,M6N8MAFzi, & + M6N9MAFxi,M6N9MAFyi,M6N9MAFzi, & + M7N1MAFxi,M7N1MAFyi,M7N1MAFzi, & + M7N2MAFxi,M7N2MAFyi,M7N2MAFzi, & + M7N3MAFxi,M7N3MAFyi,M7N3MAFzi, & + M7N4MAFxi,M7N4MAFyi,M7N4MAFzi, & + M7N5MAFxi,M7N5MAFyi,M7N5MAFzi, & + M7N6MAFxi,M7N6MAFyi,M7N6MAFzi, & + M7N7MAFxi,M7N7MAFyi,M7N7MAFzi, & + M7N8MAFxi,M7N8MAFyi,M7N8MAFzi, & + M7N9MAFxi,M7N9MAFyi,M7N9MAFzi, & + M8N1MAFxi,M8N1MAFyi,M8N1MAFzi, & + M8N2MAFxi,M8N2MAFyi,M8N2MAFzi, & + M8N3MAFxi,M8N3MAFyi,M8N3MAFzi, & + M8N4MAFxi,M8N4MAFyi,M8N4MAFzi, & + M8N5MAFxi,M8N5MAFyi,M8N5MAFzi, & + M8N6MAFxi,M8N6MAFyi,M8N6MAFzi, & + M8N7MAFxi,M8N7MAFyi,M8N7MAFzi, & + M8N8MAFxi,M8N8MAFyi,M8N8MAFzi, & + M8N9MAFxi,M8N9MAFyi,M8N9MAFzi, & + M9N1MAFxi,M9N1MAFyi,M9N1MAFzi, & + M9N2MAFxi,M9N2MAFyi,M9N2MAFzi, & + M9N3MAFxi,M9N3MAFyi,M9N3MAFzi, & + M9N4MAFxi,M9N4MAFyi,M9N4MAFzi, & + M9N5MAFxi,M9N5MAFyi,M9N5MAFzi, & + M9N6MAFxi,M9N6MAFyi,M9N6MAFzi, & + M9N7MAFxi,M9N7MAFyi,M9N7MAFzi, & + M9N8MAFxi,M9N8MAFyi,M9N8MAFzi, & + M9N9MAFxi,M9N9MAFyi,M9N9MAFzi/), (/3,9,9/)) INTEGER, PARAMETER :: JVi(3,9) = reshape((/J1Vxi, J1Vyi, J1Vzi , & J2Vxi, J2Vyi, J2Vzi , & @@ -5617,7 +6346,26 @@ MODULE Morison_Output J9MBFxi, J9MBFyi, J9MBFzi/), (/3,9/)) - + INTEGER, PARAMETER :: JFAGi(3,9) = reshape((/J1FAGxi, J1FAGyi, J1FAGzi , & + J2FAGxi, J2FAGyi, J2FAGzi , & + J3FAGxi, J3FAGyi, J3FAGzi , & + J4FAGxi, J4FAGyi, J4FAGzi , & + J5FAGxi, J5FAGyi, J5FAGzi , & + J6FAGxi, J6FAGyi, J6FAGzi , & + J7FAGxi, J7FAGyi, J7FAGzi , & + J8FAGxi, J8FAGyi, J8FAGzi , & + J9FAGxi, J9FAGyi, J9FAGzi/), (/3,9/)) + + INTEGER, PARAMETER :: JMAGi(3,9) = reshape((/J1MAGxi, J1MAGyi, J1MAGzi , & + J2MAGxi, J2MAGyi, J2MAGzi , & + J3MAGxi, J3MAGyi, J3MAGzi , & + J4MAGxi, J4MAGyi, J4MAGzi , & + J5MAGxi, J5MAGyi, J5MAGzi , & + J6MAGxi, J6MAGyi, J6MAGzi , & + J7MAGxi, J7MAGyi, J7MAGzi , & + J8MAGxi, J8MAGyi, J8MAGzi , & + J9MAGxi, J9MAGyi, J9MAGzi/), (/3,9/)) + INTEGER, PARAMETER :: JFAMi(3,9) = reshape((/J1FAMxi, J1FAMyi, J1FAMzi , & J2FAMxi, J2FAMyi, J2FAMzi , & J3FAMxi, J3FAMyi, J3FAMzi , & @@ -5627,1230 +6375,27 @@ MODULE Morison_Output J7FAMxi, J7FAMyi, J7FAMzi , & J8FAMxi, J8FAMyi, J8FAMzi , & J9FAMxi, J9FAMyi, J9FAMzi/), (/3,9/)) + + INTEGER, PARAMETER :: JFMGi(3,9) = reshape((/J1FMGxi, J1FMGyi, J1FMGzi , & + J2FMGxi, J2FMGyi, J2FMGzi , & + J3FMGxi, J3FMGyi, J3FMGzi , & + J4FMGxi, J4FMGyi, J4FMGzi , & + J5FMGxi, J5FMGyi, J5FMGzi , & + J6FMGxi, J6FMGyi, J6FMGzi , & + J7FMGxi, J7FMGyi, J7FMGzi , & + J8FMGxi, J8FMGyi, J8FMGzi , & + J9FMGxi, J9FMGyi, J9FMGzi/), (/3,9/)) !********************************************************************************************************************************** ! 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 04-Jan-2014 12:13:30. - - CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(4032) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically - "J1AXI ","J1AYI ","J1AZI ","J1DYNP ","J1FAMXI ","J1FAMYI ","J1FAMZI ","J1FBFXI ","J1FBFYI ","J1FBFZI ", & - "J1FBXI ","J1FBYI ","J1FBZI ","J1FDXI ","J1FDYI ","J1FDZI ","J1FIXI ","J1FIYI ","J1FIZI ","J1MBFXI ", & - "J1MBFYI ","J1MBFZI ","J1MBXI ","J1MBYI ","J1MBZI ","J1STAXI ","J1STAYI ","J1STAZI ","J1STVXI ","J1STVYI ", & - "J1STVZI ","J1VXI ","J1VYI ","J1VZI ","J2AXI ","J2AYI ","J2AZI ","J2DYNP ","J2FAMXI ","J2FAMYI ", & - "J2FAMZI ","J2FBFXI ","J2FBFYI ","J2FBFZI ","J2FBXI ","J2FBYI ","J2FBZI ","J2FDXI ","J2FDYI ","J2FDZI ", & - "J2FIXI ","J2FIYI ","J2FIZI ","J2MBFXI ","J2MBFYI ","J2MBFZI ","J2MBXI ","J2MBYI ","J2MBZI ","J2STAXI ", & - "J2STAYI ","J2STAZI ","J2STVXI ","J2STVYI ","J2STVZI ","J2VXI ","J2VYI ","J2VZI ","J3AXI ","J3AYI ", & - "J3AZI ","J3DYNP ","J3FAMXI ","J3FAMYI ","J3FAMZI ","J3FBFXI ","J3FBFYI ","J3FBFZI ","J3FBXI ","J3FBYI ", & - "J3FBZI ","J3FDXI ","J3FDYI ","J3FDZI ","J3FIXI ","J3FIYI ","J3FIZI ","J3MBFXI ","J3MBFYI ","J3MBFZI ", & - "J3MBXI ","J3MBYI ","J3MBZI ","J3STAXI ","J3STAYI ","J3STAZI ","J3STVXI ","J3STVYI ","J3STVZI ","J3VXI ", & - "J3VYI ","J3VZI ","J4AXI ","J4AYI ","J4AZI ","J4DYNP ","J4FAMXI ","J4FAMYI ","J4FAMZI ","J4FBFXI ", & - "J4FBFYI ","J4FBFZI ","J4FBXI ","J4FBYI ","J4FBZI ","J4FDXI ","J4FDYI ","J4FDZI ","J4FIXI ","J4FIYI ", & - "J4FIZI ","J4MBFXI ","J4MBFYI ","J4MBFZI ","J4MBXI ","J4MBYI ","J4MBZI ","J4STAXI ","J4STAYI ","J4STAZI ", & - "J4STVXI ","J4STVYI ","J4STVZI ","J4VXI ","J4VYI ","J4VZI ","J5AXI ","J5AYI ","J5AZI ","J5DYNP ", & - "J5FAMXI ","J5FAMYI ","J5FAMZI ","J5FBFXI ","J5FBFYI ","J5FBFZI ","J5FBXI ","J5FBYI ","J5FBZI ","J5FDXI ", & - "J5FDYI ","J5FDZI ","J5FIXI ","J5FIYI ","J5FIZI ","J5MBFXI ","J5MBFYI ","J5MBFZI ","J5MBXI ","J5MBYI ", & - "J5MBZI ","J5STAXI ","J5STAYI ","J5STAZI ","J5STVXI ","J5STVYI ","J5STVZI ","J5VXI ","J5VYI ","J5VZI ", & - "J6AXI ","J6AYI ","J6AZI ","J6DYNP ","J6FAMXI ","J6FAMYI ","J6FAMZI ","J6FBFXI ","J6FBFYI ","J6FBFZI ", & - "J6FBXI ","J6FBYI ","J6FBZI ","J6FDXI ","J6FDYI ","J6FDZI ","J6FIXI ","J6FIYI ","J6FIZI ","J6MBFXI ", & - "J6MBFYI ","J6MBFZI ","J6MBXI ","J6MBYI ","J6MBZI ","J6STAXI ","J6STAYI ","J6STAZI ","J6STVXI ","J6STVYI ", & - "J6STVZI ","J6VXI ","J6VYI ","J6VZI ","J7AXI ","J7AYI ","J7AZI ","J7DYNP ","J7FAMXI ","J7FAMYI ", & - "J7FAMZI ","J7FBFXI ","J7FBFYI ","J7FBFZI ","J7FBXI ","J7FBYI ","J7FBZI ","J7FDXI ","J7FDYI ","J7FDZI ", & - "J7FIXI ","J7FIYI ","J7FIZI ","J7MBFXI ","J7MBFYI ","J7MBFZI ","J7MBXI ","J7MBYI ","J7MBZI ","J7STAXI ", & - "J7STAYI ","J7STAZI ","J7STVXI ","J7STVYI ","J7STVZI ","J7VXI ","J7VYI ","J7VZI ","J8AXI ","J8AYI ", & - "J8AZI ","J8DYNP ","J8FAMXI ","J8FAMYI ","J8FAMZI ","J8FBFXI ","J8FBFYI ","J8FBFZI ","J8FBXI ","J8FBYI ", & - "J8FBZI ","J8FDXI ","J8FDYI ","J8FDZI ","J8FIXI ","J8FIYI ","J8FIZI ","J8MBFXI ","J8MBFYI ","J8MBFZI ", & - "J8MBXI ","J8MBYI ","J8MBZI ","J8STAXI ","J8STAYI ","J8STAZI ","J8STVXI ","J8STVYI ","J8STVZI ","J8VXI ", & - "J8VYI ","J8VZI ","J9AXI ","J9AYI ","J9AZI ","J9DYNP ","J9FAMXI ","J9FAMYI ","J9FAMZI ","J9FBFXI ", & - "J9FBFYI ","J9FBFZI ","J9FBXI ","J9FBYI ","J9FBZI ","J9FDXI ","J9FDYI ","J9FDZI ","J9FIXI ","J9FIYI ", & - "J9FIZI ","J9MBFXI ","J9MBFYI ","J9MBFZI ","J9MBXI ","J9MBYI ","J9MBZI ","J9STAXI ","J9STAYI ","J9STAZI ", & - "J9STVXI ","J9STVYI ","J9STVZI ","J9VXI ","J9VYI ","J9VZI ","M1N1AXI ","M1N1AYI ","M1N1AZI ","M1N1DYNP ", & - "M1N1FAFXI","M1N1FAFYI","M1N1FAFZI","M1N1FAGXI","M1N1FAGYI","M1N1FAGZI","M1N1FAMXI","M1N1FAMYI","M1N1FAMZI","M1N1FAXI ", & - "M1N1FAYI ","M1N1FAZI ","M1N1FBFXI","M1N1FBFYI","M1N1FBFZI","M1N1FBXI ","M1N1FBYI ","M1N1FBZI ","M1N1FDXI ","M1N1FDYI ", & - "M1N1FDZI ","M1N1FIXI ","M1N1FIYI ","M1N1FIZI ","M1N1FMGXI","M1N1FMGYI","M1N1FMGZI","M1N1MBFXI","M1N1MBFYI","M1N1MBFZI", & - "M1N1MBXI ","M1N1MBYI ","M1N1MBZI ","M1N1STAXI","M1N1STAYI","M1N1STAZI","M1N1STVXI","M1N1STVYI","M1N1STVZI","M1N1VXI ", & - "M1N1VYI ","M1N1VZI ","M1N2AXI ","M1N2AYI ","M1N2AZI ","M1N2DYNP ","M1N2FAFXI","M1N2FAFYI","M1N2FAFZI","M1N2FAGXI", & - "M1N2FAGYI","M1N2FAGZI","M1N2FAMXI","M1N2FAMYI","M1N2FAMZI","M1N2FAXI ","M1N2FAYI ","M1N2FAZI ","M1N2FBFXI","M1N2FBFYI", & - "M1N2FBFZI","M1N2FBXI ","M1N2FBYI ","M1N2FBZI ","M1N2FDXI ","M1N2FDYI ","M1N2FDZI ","M1N2FIXI ","M1N2FIYI ","M1N2FIZI ", & - "M1N2FMGXI","M1N2FMGYI","M1N2FMGZI","M1N2MBFXI","M1N2MBFYI","M1N2MBFZI","M1N2MBXI ","M1N2MBYI ","M1N2MBZI ","M1N2STAXI", & - "M1N2STAYI","M1N2STAZI","M1N2STVXI","M1N2STVYI","M1N2STVZI","M1N2VXI ","M1N2VYI ","M1N2VZI ","M1N3AXI ","M1N3AYI ", & - "M1N3AZI ","M1N3DYNP ","M1N3FAFXI","M1N3FAFYI","M1N3FAFZI","M1N3FAGXI","M1N3FAGYI","M1N3FAGZI","M1N3FAMXI","M1N3FAMYI", & - "M1N3FAMZI","M1N3FAXI ","M1N3FAYI ","M1N3FAZI ","M1N3FBFXI","M1N3FBFYI","M1N3FBFZI","M1N3FBXI ","M1N3FBYI ","M1N3FBZI ", & - "M1N3FDXI ","M1N3FDYI ","M1N3FDZI ","M1N3FIXI ","M1N3FIYI ","M1N3FIZI ","M1N3FMGXI","M1N3FMGYI","M1N3FMGZI","M1N3MBFXI", & - "M1N3MBFYI","M1N3MBFZI","M1N3MBXI ","M1N3MBYI ","M1N3MBZI ","M1N3STAXI","M1N3STAYI","M1N3STAZI","M1N3STVXI","M1N3STVYI", & - "M1N3STVZI","M1N3VXI ","M1N3VYI ","M1N3VZI ","M1N4AXI ","M1N4AYI ","M1N4AZI ","M1N4DYNP ","M1N4FAFXI","M1N4FAFYI", & - "M1N4FAFZI","M1N4FAGXI","M1N4FAGYI","M1N4FAGZI","M1N4FAMXI","M1N4FAMYI","M1N4FAMZI","M1N4FAXI ","M1N4FAYI ","M1N4FAZI ", & - "M1N4FBFXI","M1N4FBFYI","M1N4FBFZI","M1N4FBXI ","M1N4FBYI ","M1N4FBZI ","M1N4FDXI ","M1N4FDYI ","M1N4FDZI ","M1N4FIXI ", & - "M1N4FIYI ","M1N4FIZI ","M1N4FMGXI","M1N4FMGYI","M1N4FMGZI","M1N4MBFXI","M1N4MBFYI","M1N4MBFZI","M1N4MBXI ","M1N4MBYI ", & - "M1N4MBZI ","M1N4STAXI","M1N4STAYI","M1N4STAZI","M1N4STVXI","M1N4STVYI","M1N4STVZI","M1N4VXI ","M1N4VYI ","M1N4VZI ", & - "M1N5AXI ","M1N5AYI ","M1N5AZI ","M1N5DYNP ","M1N5FAFXI","M1N5FAFYI","M1N5FAFZI","M1N5FAGXI","M1N5FAGYI","M1N5FAGZI", & - "M1N5FAMXI","M1N5FAMYI","M1N5FAMZI","M1N5FAXI ","M1N5FAYI ","M1N5FAZI ","M1N5FBFXI","M1N5FBFYI","M1N5FBFZI","M1N5FBXI ", & - "M1N5FBYI ","M1N5FBZI ","M1N5FDXI ","M1N5FDYI ","M1N5FDZI ","M1N5FIXI ","M1N5FIYI ","M1N5FIZI ","M1N5FMGXI","M1N5FMGYI", & - "M1N5FMGZI","M1N5MBFXI","M1N5MBFYI","M1N5MBFZI","M1N5MBXI ","M1N5MBYI ","M1N5MBZI ","M1N5STAXI","M1N5STAYI","M1N5STAZI", & - "M1N5STVXI","M1N5STVYI","M1N5STVZI","M1N5VXI ","M1N5VYI ","M1N5VZI ","M1N6AXI ","M1N6AYI ","M1N6AZI ","M1N6DYNP ", & - "M1N6FAFXI","M1N6FAFYI","M1N6FAFZI","M1N6FAGXI","M1N6FAGYI","M1N6FAGZI","M1N6FAMXI","M1N6FAMYI","M1N6FAMZI","M1N6FAXI ", & - "M1N6FAYI ","M1N6FAZI ","M1N6FBFXI","M1N6FBFYI","M1N6FBFZI","M1N6FBXI ","M1N6FBYI ","M1N6FBZI ","M1N6FDXI ","M1N6FDYI ", & - "M1N6FDZI ","M1N6FIXI ","M1N6FIYI ","M1N6FIZI ","M1N6FMGXI","M1N6FMGYI","M1N6FMGZI","M1N6MBFXI","M1N6MBFYI","M1N6MBFZI", & - "M1N6MBXI ","M1N6MBYI ","M1N6MBZI ","M1N6STAXI","M1N6STAYI","M1N6STAZI","M1N6STVXI","M1N6STVYI","M1N6STVZI","M1N6VXI ", & - "M1N6VYI ","M1N6VZI ","M1N7AXI ","M1N7AYI ","M1N7AZI ","M1N7DYNP ","M1N7FAFXI","M1N7FAFYI","M1N7FAFZI","M1N7FAGXI", & - "M1N7FAGYI","M1N7FAGZI","M1N7FAMXI","M1N7FAMYI","M1N7FAMZI","M1N7FAXI ","M1N7FAYI ","M1N7FAZI ","M1N7FBFXI","M1N7FBFYI", & - "M1N7FBFZI","M1N7FBXI ","M1N7FBYI ","M1N7FBZI ","M1N7FDXI ","M1N7FDYI ","M1N7FDZI ","M1N7FIXI ","M1N7FIYI ","M1N7FIZI ", & - "M1N7FMGXI","M1N7FMGYI","M1N7FMGZI","M1N7MBFXI","M1N7MBFYI","M1N7MBFZI","M1N7MBXI ","M1N7MBYI ","M1N7MBZI ","M1N7STAXI", & - "M1N7STAYI","M1N7STAZI","M1N7STVXI","M1N7STVYI","M1N7STVZI","M1N7VXI ","M1N7VYI ","M1N7VZI ","M1N8AXI ","M1N8AYI ", & - "M1N8AZI ","M1N8DYNP ","M1N8FAFXI","M1N8FAFYI","M1N8FAFZI","M1N8FAGXI","M1N8FAGYI","M1N8FAGZI","M1N8FAMXI","M1N8FAMYI", & - "M1N8FAMZI","M1N8FAXI ","M1N8FAYI ","M1N8FAZI ","M1N8FBFXI","M1N8FBFYI","M1N8FBFZI","M1N8FBXI ","M1N8FBYI ","M1N8FBZI ", & - "M1N8FDXI ","M1N8FDYI ","M1N8FDZI ","M1N8FIXI ","M1N8FIYI ","M1N8FIZI ","M1N8FMGXI","M1N8FMGYI","M1N8FMGZI","M1N8MBFXI", & - "M1N8MBFYI","M1N8MBFZI","M1N8MBXI ","M1N8MBYI ","M1N8MBZI ","M1N8STAXI","M1N8STAYI","M1N8STAZI","M1N8STVXI","M1N8STVYI", & - "M1N8STVZI","M1N8VXI ","M1N8VYI ","M1N8VZI ","M1N9AXI ","M1N9AYI ","M1N9AZI ","M1N9DYNP ","M1N9FAFXI","M1N9FAFYI", & - "M1N9FAFZI","M1N9FAGXI","M1N9FAGYI","M1N9FAGZI","M1N9FAMXI","M1N9FAMYI","M1N9FAMZI","M1N9FAXI ","M1N9FAYI ","M1N9FAZI ", & - "M1N9FBFXI","M1N9FBFYI","M1N9FBFZI","M1N9FBXI ","M1N9FBYI ","M1N9FBZI ","M1N9FDXI ","M1N9FDYI ","M1N9FDZI ","M1N9FIXI ", & - "M1N9FIYI ","M1N9FIZI ","M1N9FMGXI","M1N9FMGYI","M1N9FMGZI","M1N9MBFXI","M1N9MBFYI","M1N9MBFZI","M1N9MBXI ","M1N9MBYI ", & - "M1N9MBZI ","M1N9STAXI","M1N9STAYI","M1N9STAZI","M1N9STVXI","M1N9STVYI","M1N9STVZI","M1N9VXI ","M1N9VYI ","M1N9VZI ", & - "M2N1AXI ","M2N1AYI ","M2N1AZI ","M2N1DYNP ","M2N1FAFXI","M2N1FAFYI","M2N1FAFZI","M2N1FAGXI","M2N1FAGYI","M2N1FAGZI", & - "M2N1FAMXI","M2N1FAMYI","M2N1FAMZI","M2N1FAXI ","M2N1FAYI ","M2N1FAZI ","M2N1FBFXI","M2N1FBFYI","M2N1FBFZI","M2N1FBXI ", & - "M2N1FBYI ","M2N1FBZI ","M2N1FDXI ","M2N1FDYI ","M2N1FDZI ","M2N1FIXI ","M2N1FIYI ","M2N1FIZI ","M2N1FMGXI","M2N1FMGYI", & - "M2N1FMGZI","M2N1MBFXI","M2N1MBFYI","M2N1MBFZI","M2N1MBXI ","M2N1MBYI ","M2N1MBZI ","M2N1STAXI","M2N1STAYI","M2N1STAZI", & - "M2N1STVXI","M2N1STVYI","M2N1STVZI","M2N1VXI ","M2N1VYI ","M2N1VZI ","M2N2AXI ","M2N2AYI ","M2N2AZI ","M2N2DYNP ", & - "M2N2FAFXI","M2N2FAFYI","M2N2FAFZI","M2N2FAGXI","M2N2FAGYI","M2N2FAGZI","M2N2FAMXI","M2N2FAMYI","M2N2FAMZI","M2N2FAXI ", & - "M2N2FAYI ","M2N2FAZI ","M2N2FBFXI","M2N2FBFYI","M2N2FBFZI","M2N2FBXI ","M2N2FBYI ","M2N2FBZI ","M2N2FDXI ","M2N2FDYI ", & - "M2N2FDZI ","M2N2FIXI ","M2N2FIYI ","M2N2FIZI ","M2N2FMGXI","M2N2FMGYI","M2N2FMGZI","M2N2MBFXI","M2N2MBFYI","M2N2MBFZI", & - "M2N2MBXI ","M2N2MBYI ","M2N2MBZI ","M2N2STAXI","M2N2STAYI","M2N2STAZI","M2N2STVXI","M2N2STVYI","M2N2STVZI","M2N2VXI ", & - "M2N2VYI ","M2N2VZI ","M2N3AXI ","M2N3AYI ","M2N3AZI ","M2N3DYNP ","M2N3FAFXI","M2N3FAFYI","M2N3FAFZI","M2N3FAGXI", & - "M2N3FAGYI","M2N3FAGZI","M2N3FAMXI","M2N3FAMYI","M2N3FAMZI","M2N3FAXI ","M2N3FAYI ","M2N3FAZI ","M2N3FBFXI","M2N3FBFYI", & - "M2N3FBFZI","M2N3FBXI ","M2N3FBYI ","M2N3FBZI ","M2N3FDXI ","M2N3FDYI ","M2N3FDZI ","M2N3FIXI ","M2N3FIYI ","M2N3FIZI ", & - "M2N3FMGXI","M2N3FMGYI","M2N3FMGZI","M2N3MBFXI","M2N3MBFYI","M2N3MBFZI","M2N3MBXI ","M2N3MBYI ","M2N3MBZI ","M2N3STAXI", & - "M2N3STAYI","M2N3STAZI","M2N3STVXI","M2N3STVYI","M2N3STVZI","M2N3VXI ","M2N3VYI ","M2N3VZI ","M2N4AXI ","M2N4AYI ", & - "M2N4AZI ","M2N4DYNP ","M2N4FAFXI","M2N4FAFYI","M2N4FAFZI","M2N4FAGXI","M2N4FAGYI","M2N4FAGZI","M2N4FAMXI","M2N4FAMYI", & - "M2N4FAMZI","M2N4FAXI ","M2N4FAYI ","M2N4FAZI ","M2N4FBFXI","M2N4FBFYI","M2N4FBFZI","M2N4FBXI ","M2N4FBYI ","M2N4FBZI ", & - "M2N4FDXI ","M2N4FDYI ","M2N4FDZI ","M2N4FIXI ","M2N4FIYI ","M2N4FIZI ","M2N4FMGXI","M2N4FMGYI","M2N4FMGZI","M2N4MBFXI", & - "M2N4MBFYI","M2N4MBFZI","M2N4MBXI ","M2N4MBYI ","M2N4MBZI ","M2N4STAXI","M2N4STAYI","M2N4STAZI","M2N4STVXI","M2N4STVYI", & - "M2N4STVZI","M2N4VXI ","M2N4VYI ","M2N4VZI ","M2N5AXI ","M2N5AYI ","M2N5AZI ","M2N5DYNP ","M2N5FAFXI","M2N5FAFYI", & - "M2N5FAFZI","M2N5FAGXI","M2N5FAGYI","M2N5FAGZI","M2N5FAMXI","M2N5FAMYI","M2N5FAMZI","M2N5FAXI ","M2N5FAYI ","M2N5FAZI ", & - "M2N5FBFXI","M2N5FBFYI","M2N5FBFZI","M2N5FBXI ","M2N5FBYI ","M2N5FBZI ","M2N5FDXI ","M2N5FDYI ","M2N5FDZI ","M2N5FIXI ", & - "M2N5FIYI ","M2N5FIZI ","M2N5FMGXI","M2N5FMGYI","M2N5FMGZI","M2N5MBFXI","M2N5MBFYI","M2N5MBFZI","M2N5MBXI ","M2N5MBYI ", & - "M2N5MBZI ","M2N5STAXI","M2N5STAYI","M2N5STAZI","M2N5STVXI","M2N5STVYI","M2N5STVZI","M2N5VXI ","M2N5VYI ","M2N5VZI ", & - "M2N6AXI ","M2N6AYI ","M2N6AZI ","M2N6DYNP ","M2N6FAFXI","M2N6FAFYI","M2N6FAFZI","M2N6FAGXI","M2N6FAGYI","M2N6FAGZI", & - "M2N6FAMXI","M2N6FAMYI","M2N6FAMZI","M2N6FAXI ","M2N6FAYI ","M2N6FAZI ","M2N6FBFXI","M2N6FBFYI","M2N6FBFZI","M2N6FBXI ", & - "M2N6FBYI ","M2N6FBZI ","M2N6FDXI ","M2N6FDYI ","M2N6FDZI ","M2N6FIXI ","M2N6FIYI ","M2N6FIZI ","M2N6FMGXI","M2N6FMGYI", & - "M2N6FMGZI","M2N6MBFXI","M2N6MBFYI","M2N6MBFZI","M2N6MBXI ","M2N6MBYI ","M2N6MBZI ","M2N6STAXI","M2N6STAYI","M2N6STAZI", & - "M2N6STVXI","M2N6STVYI","M2N6STVZI","M2N6VXI ","M2N6VYI ","M2N6VZI ","M2N7AXI ","M2N7AYI ","M2N7AZI ","M2N7DYNP ", & - "M2N7FAFXI","M2N7FAFYI","M2N7FAFZI","M2N7FAGXI","M2N7FAGYI","M2N7FAGZI","M2N7FAMXI","M2N7FAMYI","M2N7FAMZI","M2N7FAXI ", & - "M2N7FAYI ","M2N7FAZI ","M2N7FBFXI","M2N7FBFYI","M2N7FBFZI","M2N7FBXI ","M2N7FBYI ","M2N7FBZI ","M2N7FDXI ","M2N7FDYI ", & - "M2N7FDZI ","M2N7FIXI ","M2N7FIYI ","M2N7FIZI ","M2N7FMGXI","M2N7FMGYI","M2N7FMGZI","M2N7MBFXI","M2N7MBFYI","M2N7MBFZI", & - "M2N7MBXI ","M2N7MBYI ","M2N7MBZI ","M2N7STAXI","M2N7STAYI","M2N7STAZI","M2N7STVXI","M2N7STVYI","M2N7STVZI","M2N7VXI ", & - "M2N7VYI ","M2N7VZI ","M2N8AXI ","M2N8AYI ","M2N8AZI ","M2N8DYNP ","M2N8FAFXI","M2N8FAFYI","M2N8FAFZI","M2N8FAGXI", & - "M2N8FAGYI","M2N8FAGZI","M2N8FAMXI","M2N8FAMYI","M2N8FAMZI","M2N8FAXI ","M2N8FAYI ","M2N8FAZI ","M2N8FBFXI","M2N8FBFYI", & - "M2N8FBFZI","M2N8FBXI ","M2N8FBYI ","M2N8FBZI ","M2N8FDXI ","M2N8FDYI ","M2N8FDZI ","M2N8FIXI ","M2N8FIYI ","M2N8FIZI ", & - "M2N8FMGXI","M2N8FMGYI","M2N8FMGZI","M2N8MBFXI","M2N8MBFYI","M2N8MBFZI","M2N8MBXI ","M2N8MBYI ","M2N8MBZI ","M2N8STAXI", & - "M2N8STAYI","M2N8STAZI","M2N8STVXI","M2N8STVYI","M2N8STVZI","M2N8VXI ","M2N8VYI ","M2N8VZI ","M2N9AXI ","M2N9AYI ", & - "M2N9AZI ","M2N9DYNP ","M2N9FAFXI","M2N9FAFYI","M2N9FAFZI","M2N9FAGXI","M2N9FAGYI","M2N9FAGZI","M2N9FAMXI","M2N9FAMYI", & - "M2N9FAMZI","M2N9FAXI ","M2N9FAYI ","M2N9FAZI ","M2N9FBFXI","M2N9FBFYI","M2N9FBFZI","M2N9FBXI ","M2N9FBYI ","M2N9FBZI ", & - "M2N9FDXI ","M2N9FDYI ","M2N9FDZI ","M2N9FIXI ","M2N9FIYI ","M2N9FIZI ","M2N9FMGXI","M2N9FMGYI","M2N9FMGZI","M2N9MBFXI", & - "M2N9MBFYI","M2N9MBFZI","M2N9MBXI ","M2N9MBYI ","M2N9MBZI ","M2N9STAXI","M2N9STAYI","M2N9STAZI","M2N9STVXI","M2N9STVYI", & - "M2N9STVZI","M2N9VXI ","M2N9VYI ","M2N9VZI ","M3N1AXI ","M3N1AYI ","M3N1AZI ","M3N1DYNP ","M3N1FAFXI","M3N1FAFYI", & - "M3N1FAFZI","M3N1FAGXI","M3N1FAGYI","M3N1FAGZI","M3N1FAMXI","M3N1FAMYI","M3N1FAMZI","M3N1FAXI ","M3N1FAYI ","M3N1FAZI ", & - "M3N1FBFXI","M3N1FBFYI","M3N1FBFZI","M3N1FBXI ","M3N1FBYI ","M3N1FBZI ","M3N1FDXI ","M3N1FDYI ","M3N1FDZI ","M3N1FIXI ", & - "M3N1FIYI ","M3N1FIZI ","M3N1FMGXI","M3N1FMGYI","M3N1FMGZI","M3N1MBFXI","M3N1MBFYI","M3N1MBFZI","M3N1MBXI ","M3N1MBYI ", & - "M3N1MBZI ","M3N1STAXI","M3N1STAYI","M3N1STAZI","M3N1STVXI","M3N1STVYI","M3N1STVZI","M3N1VXI ","M3N1VYI ","M3N1VZI ", & - "M3N2AXI ","M3N2AYI ","M3N2AZI ","M3N2DYNP ","M3N2FAFXI","M3N2FAFYI","M3N2FAFZI","M3N2FAGXI","M3N2FAGYI","M3N2FAGZI", & - "M3N2FAMXI","M3N2FAMYI","M3N2FAMZI","M3N2FAXI ","M3N2FAYI ","M3N2FAZI ","M3N2FBFXI","M3N2FBFYI","M3N2FBFZI","M3N2FBXI ", & - "M3N2FBYI ","M3N2FBZI ","M3N2FDXI ","M3N2FDYI ","M3N2FDZI ","M3N2FIXI ","M3N2FIYI ","M3N2FIZI ","M3N2FMGXI","M3N2FMGYI", & - "M3N2FMGZI","M3N2MBFXI","M3N2MBFYI","M3N2MBFZI","M3N2MBXI ","M3N2MBYI ","M3N2MBZI ","M3N2STAXI","M3N2STAYI","M3N2STAZI", & - "M3N2STVXI","M3N2STVYI","M3N2STVZI","M3N2VXI ","M3N2VYI ","M3N2VZI ","M3N3AXI ","M3N3AYI ","M3N3AZI ","M3N3DYNP ", & - "M3N3FAFXI","M3N3FAFYI","M3N3FAFZI","M3N3FAGXI","M3N3FAGYI","M3N3FAGZI","M3N3FAMXI","M3N3FAMYI","M3N3FAMZI","M3N3FAXI ", & - "M3N3FAYI ","M3N3FAZI ","M3N3FBFXI","M3N3FBFYI","M3N3FBFZI","M3N3FBXI ","M3N3FBYI ","M3N3FBZI ","M3N3FDXI ","M3N3FDYI ", & - "M3N3FDZI ","M3N3FIXI ","M3N3FIYI ","M3N3FIZI ","M3N3FMGXI","M3N3FMGYI","M3N3FMGZI","M3N3MBFXI","M3N3MBFYI","M3N3MBFZI", & - "M3N3MBXI ","M3N3MBYI ","M3N3MBZI ","M3N3STAXI","M3N3STAYI","M3N3STAZI","M3N3STVXI","M3N3STVYI","M3N3STVZI","M3N3VXI ", & - "M3N3VYI ","M3N3VZI ","M3N4AXI ","M3N4AYI ","M3N4AZI ","M3N4DYNP ","M3N4FAFXI","M3N4FAFYI","M3N4FAFZI","M3N4FAGXI", & - "M3N4FAGYI","M3N4FAGZI","M3N4FAMXI","M3N4FAMYI","M3N4FAMZI","M3N4FAXI ","M3N4FAYI ","M3N4FAZI ","M3N4FBFXI","M3N4FBFYI", & - "M3N4FBFZI","M3N4FBXI ","M3N4FBYI ","M3N4FBZI ","M3N4FDXI ","M3N4FDYI ","M3N4FDZI ","M3N4FIXI ","M3N4FIYI ","M3N4FIZI ", & - "M3N4FMGXI","M3N4FMGYI","M3N4FMGZI","M3N4MBFXI","M3N4MBFYI","M3N4MBFZI","M3N4MBXI ","M3N4MBYI ","M3N4MBZI ","M3N4STAXI", & - "M3N4STAYI","M3N4STAZI","M3N4STVXI","M3N4STVYI","M3N4STVZI","M3N4VXI ","M3N4VYI ","M3N4VZI ","M3N5AXI ","M3N5AYI ", & - "M3N5AZI ","M3N5DYNP ","M3N5FAFXI","M3N5FAFYI","M3N5FAFZI","M3N5FAGXI","M3N5FAGYI","M3N5FAGZI","M3N5FAMXI","M3N5FAMYI", & - "M3N5FAMZI","M3N5FAXI ","M3N5FAYI ","M3N5FAZI ","M3N5FBFXI","M3N5FBFYI","M3N5FBFZI","M3N5FBXI ","M3N5FBYI ","M3N5FBZI ", & - "M3N5FDXI ","M3N5FDYI ","M3N5FDZI ","M3N5FIXI ","M3N5FIYI ","M3N5FIZI ","M3N5FMGXI","M3N5FMGYI","M3N5FMGZI","M3N5MBFXI", & - "M3N5MBFYI","M3N5MBFZI","M3N5MBXI ","M3N5MBYI ","M3N5MBZI ","M3N5STAXI","M3N5STAYI","M3N5STAZI","M3N5STVXI","M3N5STVYI", & - "M3N5STVZI","M3N5VXI ","M3N5VYI ","M3N5VZI ","M3N6AXI ","M3N6AYI ","M3N6AZI ","M3N6DYNP ","M3N6FAFXI","M3N6FAFYI", & - "M3N6FAFZI","M3N6FAGXI","M3N6FAGYI","M3N6FAGZI","M3N6FAMXI","M3N6FAMYI","M3N6FAMZI","M3N6FAXI ","M3N6FAYI ","M3N6FAZI ", & - "M3N6FBFXI","M3N6FBFYI","M3N6FBFZI","M3N6FBXI ","M3N6FBYI ","M3N6FBZI ","M3N6FDXI ","M3N6FDYI ","M3N6FDZI ","M3N6FIXI ", & - "M3N6FIYI ","M3N6FIZI ","M3N6FMGXI","M3N6FMGYI","M3N6FMGZI","M3N6MBFXI","M3N6MBFYI","M3N6MBFZI","M3N6MBXI ","M3N6MBYI ", & - "M3N6MBZI ","M3N6STAXI","M3N6STAYI","M3N6STAZI","M3N6STVXI","M3N6STVYI","M3N6STVZI","M3N6VXI ","M3N6VYI ","M3N6VZI ", & - "M3N7AXI ","M3N7AYI ","M3N7AZI ","M3N7DYNP ","M3N7FAFXI","M3N7FAFYI","M3N7FAFZI","M3N7FAGXI","M3N7FAGYI","M3N7FAGZI", & - "M3N7FAMXI","M3N7FAMYI","M3N7FAMZI","M3N7FAXI ","M3N7FAYI ","M3N7FAZI ","M3N7FBFXI","M3N7FBFYI","M3N7FBFZI","M3N7FBXI ", & - "M3N7FBYI ","M3N7FBZI ","M3N7FDXI ","M3N7FDYI ","M3N7FDZI ","M3N7FIXI ","M3N7FIYI ","M3N7FIZI ","M3N7FMGXI","M3N7FMGYI", & - "M3N7FMGZI","M3N7MBFXI","M3N7MBFYI","M3N7MBFZI","M3N7MBXI ","M3N7MBYI ","M3N7MBZI ","M3N7STAXI","M3N7STAYI","M3N7STAZI", & - "M3N7STVXI","M3N7STVYI","M3N7STVZI","M3N7VXI ","M3N7VYI ","M3N7VZI ","M3N8AXI ","M3N8AYI ","M3N8AZI ","M3N8DYNP ", & - "M3N8FAFXI","M3N8FAFYI","M3N8FAFZI","M3N8FAGXI","M3N8FAGYI","M3N8FAGZI","M3N8FAMXI","M3N8FAMYI","M3N8FAMZI","M3N8FAXI ", & - "M3N8FAYI ","M3N8FAZI ","M3N8FBFXI","M3N8FBFYI","M3N8FBFZI","M3N8FBXI ","M3N8FBYI ","M3N8FBZI ","M3N8FDXI ","M3N8FDYI ", & - "M3N8FDZI ","M3N8FIXI ","M3N8FIYI ","M3N8FIZI ","M3N8FMGXI","M3N8FMGYI","M3N8FMGZI","M3N8MBFXI","M3N8MBFYI","M3N8MBFZI", & - "M3N8MBXI ","M3N8MBYI ","M3N8MBZI ","M3N8STAXI","M3N8STAYI","M3N8STAZI","M3N8STVXI","M3N8STVYI","M3N8STVZI","M3N8VXI ", & - "M3N8VYI ","M3N8VZI ","M3N9AXI ","M3N9AYI ","M3N9AZI ","M3N9DYNP ","M3N9FAFXI","M3N9FAFYI","M3N9FAFZI","M3N9FAGXI", & - "M3N9FAGYI","M3N9FAGZI","M3N9FAMXI","M3N9FAMYI","M3N9FAMZI","M3N9FAXI ","M3N9FAYI ","M3N9FAZI ","M3N9FBFXI","M3N9FBFYI", & - "M3N9FBFZI","M3N9FBXI ","M3N9FBYI ","M3N9FBZI ","M3N9FDXI ","M3N9FDYI ","M3N9FDZI ","M3N9FIXI ","M3N9FIYI ","M3N9FIZI ", & - "M3N9FMGXI","M3N9FMGYI","M3N9FMGZI","M3N9MBFXI","M3N9MBFYI","M3N9MBFZI","M3N9MBXI ","M3N9MBYI ","M3N9MBZI ","M3N9STAXI", & - "M3N9STAYI","M3N9STAZI","M3N9STVXI","M3N9STVYI","M3N9STVZI","M3N9VXI ","M3N9VYI ","M3N9VZI ","M4N1AXI ","M4N1AYI ", & - "M4N1AZI ","M4N1DYNP ","M4N1FAFXI","M4N1FAFYI","M4N1FAFZI","M4N1FAGXI","M4N1FAGYI","M4N1FAGZI","M4N1FAMXI","M4N1FAMYI", & - "M4N1FAMZI","M4N1FAXI ","M4N1FAYI ","M4N1FAZI ","M4N1FBFXI","M4N1FBFYI","M4N1FBFZI","M4N1FBXI ","M4N1FBYI ","M4N1FBZI ", & - "M4N1FDXI ","M4N1FDYI ","M4N1FDZI ","M4N1FIXI ","M4N1FIYI ","M4N1FIZI ","M4N1FMGXI","M4N1FMGYI","M4N1FMGZI","M4N1MBFXI", & - "M4N1MBFYI","M4N1MBFZI","M4N1MBXI ","M4N1MBYI ","M4N1MBZI ","M4N1STAXI","M4N1STAYI","M4N1STAZI","M4N1STVXI","M4N1STVYI", & - "M4N1STVZI","M4N1VXI ","M4N1VYI ","M4N1VZI ","M4N2AXI ","M4N2AYI ","M4N2AZI ","M4N2DYNP ","M4N2FAFXI","M4N2FAFYI", & - "M4N2FAFZI","M4N2FAGXI","M4N2FAGYI","M4N2FAGZI","M4N2FAMXI","M4N2FAMYI","M4N2FAMZI","M4N2FAXI ","M4N2FAYI ","M4N2FAZI ", & - "M4N2FBFXI","M4N2FBFYI","M4N2FBFZI","M4N2FBXI ","M4N2FBYI ","M4N2FBZI ","M4N2FDXI ","M4N2FDYI ","M4N2FDZI ","M4N2FIXI ", & - "M4N2FIYI ","M4N2FIZI ","M4N2FMGXI","M4N2FMGYI","M4N2FMGZI","M4N2MBFXI","M4N2MBFYI","M4N2MBFZI","M4N2MBXI ","M4N2MBYI ", & - "M4N2MBZI ","M4N2STAXI","M4N2STAYI","M4N2STAZI","M4N2STVXI","M4N2STVYI","M4N2STVZI","M4N2VXI ","M4N2VYI ","M4N2VZI ", & - "M4N3AXI ","M4N3AYI ","M4N3AZI ","M4N3DYNP ","M4N3FAFXI","M4N3FAFYI","M4N3FAFZI","M4N3FAGXI","M4N3FAGYI","M4N3FAGZI", & - "M4N3FAMXI","M4N3FAMYI","M4N3FAMZI","M4N3FAXI ","M4N3FAYI ","M4N3FAZI ","M4N3FBFXI","M4N3FBFYI","M4N3FBFZI","M4N3FBXI ", & - "M4N3FBYI ","M4N3FBZI ","M4N3FDXI ","M4N3FDYI ","M4N3FDZI ","M4N3FIXI ","M4N3FIYI ","M4N3FIZI ","M4N3FMGXI","M4N3FMGYI", & - "M4N3FMGZI","M4N3MBFXI","M4N3MBFYI","M4N3MBFZI","M4N3MBXI ","M4N3MBYI ","M4N3MBZI ","M4N3STAXI","M4N3STAYI","M4N3STAZI", & - "M4N3STVXI","M4N3STVYI","M4N3STVZI","M4N3VXI ","M4N3VYI ","M4N3VZI ","M4N4AXI ","M4N4AYI ","M4N4AZI ","M4N4DYNP ", & - "M4N4FAFXI","M4N4FAFYI","M4N4FAFZI","M4N4FAGXI","M4N4FAGYI","M4N4FAGZI","M4N4FAMXI","M4N4FAMYI","M4N4FAMZI","M4N4FAXI ", & - "M4N4FAYI ","M4N4FAZI ","M4N4FBFXI","M4N4FBFYI","M4N4FBFZI","M4N4FBXI ","M4N4FBYI ","M4N4FBZI ","M4N4FDXI ","M4N4FDYI ", & - "M4N4FDZI ","M4N4FIXI ","M4N4FIYI ","M4N4FIZI ","M4N4FMGXI","M4N4FMGYI","M4N4FMGZI","M4N4MBFXI","M4N4MBFYI","M4N4MBFZI", & - "M4N4MBXI ","M4N4MBYI ","M4N4MBZI ","M4N4STAXI","M4N4STAYI","M4N4STAZI","M4N4STVXI","M4N4STVYI","M4N4STVZI","M4N4VXI ", & - "M4N4VYI ","M4N4VZI ","M4N5AXI ","M4N5AYI ","M4N5AZI ","M4N5DYNP ","M4N5FAFXI","M4N5FAFYI","M4N5FAFZI","M4N5FAGXI", & - "M4N5FAGYI","M4N5FAGZI","M4N5FAMXI","M4N5FAMYI","M4N5FAMZI","M4N5FAXI ","M4N5FAYI ","M4N5FAZI ","M4N5FBFXI","M4N5FBFYI", & - "M4N5FBFZI","M4N5FBXI ","M4N5FBYI ","M4N5FBZI ","M4N5FDXI ","M4N5FDYI ","M4N5FDZI ","M4N5FIXI ","M4N5FIYI ","M4N5FIZI ", & - "M4N5FMGXI","M4N5FMGYI","M4N5FMGZI","M4N5MBFXI","M4N5MBFYI","M4N5MBFZI","M4N5MBXI ","M4N5MBYI ","M4N5MBZI ","M4N5STAXI", & - "M4N5STAYI","M4N5STAZI","M4N5STVXI","M4N5STVYI","M4N5STVZI","M4N5VXI ","M4N5VYI ","M4N5VZI ","M4N6AXI ","M4N6AYI ", & - "M4N6AZI ","M4N6DYNP ","M4N6FAFXI","M4N6FAFYI","M4N6FAFZI","M4N6FAGXI","M4N6FAGYI","M4N6FAGZI","M4N6FAMXI","M4N6FAMYI", & - "M4N6FAMZI","M4N6FAXI ","M4N6FAYI ","M4N6FAZI ","M4N6FBFXI","M4N6FBFYI","M4N6FBFZI","M4N6FBXI ","M4N6FBYI ","M4N6FBZI ", & - "M4N6FDXI ","M4N6FDYI ","M4N6FDZI ","M4N6FIXI ","M4N6FIYI ","M4N6FIZI ","M4N6FMGXI","M4N6FMGYI","M4N6FMGZI","M4N6MBFXI", & - "M4N6MBFYI","M4N6MBFZI","M4N6MBXI ","M4N6MBYI ","M4N6MBZI ","M4N6STAXI","M4N6STAYI","M4N6STAZI","M4N6STVXI","M4N6STVYI", & - "M4N6STVZI","M4N6VXI ","M4N6VYI ","M4N6VZI ","M4N7AXI ","M4N7AYI ","M4N7AZI ","M4N7DYNP ","M4N7FAFXI","M4N7FAFYI", & - "M4N7FAFZI","M4N7FAGXI","M4N7FAGYI","M4N7FAGZI","M4N7FAMXI","M4N7FAMYI","M4N7FAMZI","M4N7FAXI ","M4N7FAYI ","M4N7FAZI ", & - "M4N7FBFXI","M4N7FBFYI","M4N7FBFZI","M4N7FBXI ","M4N7FBYI ","M4N7FBZI ","M4N7FDXI ","M4N7FDYI ","M4N7FDZI ","M4N7FIXI ", & - "M4N7FIYI ","M4N7FIZI ","M4N7FMGXI","M4N7FMGYI","M4N7FMGZI","M4N7MBFXI","M4N7MBFYI","M4N7MBFZI","M4N7MBXI ","M4N7MBYI ", & - "M4N7MBZI ","M4N7STAXI","M4N7STAYI","M4N7STAZI","M4N7STVXI","M4N7STVYI","M4N7STVZI","M4N7VXI ","M4N7VYI ","M4N7VZI ", & - "M4N8AXI ","M4N8AYI ","M4N8AZI ","M4N8DYNP ","M4N8FAFXI","M4N8FAFYI","M4N8FAFZI","M4N8FAGXI","M4N8FAGYI","M4N8FAGZI", & - "M4N8FAMXI","M4N8FAMYI","M4N8FAMZI","M4N8FAXI ","M4N8FAYI ","M4N8FAZI ","M4N8FBFXI","M4N8FBFYI","M4N8FBFZI","M4N8FBXI ", & - "M4N8FBYI ","M4N8FBZI ","M4N8FDXI ","M4N8FDYI ","M4N8FDZI ","M4N8FIXI ","M4N8FIYI ","M4N8FIZI ","M4N8FMGXI","M4N8FMGYI", & - "M4N8FMGZI","M4N8MBFXI","M4N8MBFYI","M4N8MBFZI","M4N8MBXI ","M4N8MBYI ","M4N8MBZI ","M4N8STAXI","M4N8STAYI","M4N8STAZI", & - "M4N8STVXI","M4N8STVYI","M4N8STVZI","M4N8VXI ","M4N8VYI ","M4N8VZI ","M4N9AXI ","M4N9AYI ","M4N9AZI ","M4N9DYNP ", & - "M4N9FAFXI","M4N9FAFYI","M4N9FAFZI","M4N9FAGXI","M4N9FAGYI","M4N9FAGZI","M4N9FAMXI","M4N9FAMYI","M4N9FAMZI","M4N9FAXI ", & - "M4N9FAYI ","M4N9FAZI ","M4N9FBFXI","M4N9FBFYI","M4N9FBFZI","M4N9FBXI ","M4N9FBYI ","M4N9FBZI ","M4N9FDXI ","M4N9FDYI ", & - "M4N9FDZI ","M4N9FIXI ","M4N9FIYI ","M4N9FIZI ","M4N9FMGXI","M4N9FMGYI","M4N9FMGZI","M4N9MBFXI","M4N9MBFYI","M4N9MBFZI", & - "M4N9MBXI ","M4N9MBYI ","M4N9MBZI ","M4N9STAXI","M4N9STAYI","M4N9STAZI","M4N9STVXI","M4N9STVYI","M4N9STVZI","M4N9VXI ", & - "M4N9VYI ","M4N9VZI ","M5N1AXI ","M5N1AYI ","M5N1AZI ","M5N1DYNP ","M5N1FAFXI","M5N1FAFYI","M5N1FAFZI","M5N1FAGXI", & - "M5N1FAGYI","M5N1FAGZI","M5N1FAMXI","M5N1FAMYI","M5N1FAMZI","M5N1FAXI ","M5N1FAYI ","M5N1FAZI ","M5N1FBFXI","M5N1FBFYI", & - "M5N1FBFZI","M5N1FBXI ","M5N1FBYI ","M5N1FBZI ","M5N1FDXI ","M5N1FDYI ","M5N1FDZI ","M5N1FIXI ","M5N1FIYI ","M5N1FIZI ", & - "M5N1FMGXI","M5N1FMGYI","M5N1FMGZI","M5N1MBFXI","M5N1MBFYI","M5N1MBFZI","M5N1MBXI ","M5N1MBYI ","M5N1MBZI ","M5N1STAXI", & - "M5N1STAYI","M5N1STAZI","M5N1STVXI","M5N1STVYI","M5N1STVZI","M5N1VXI ","M5N1VYI ","M5N1VZI ","M5N2AXI ","M5N2AYI ", & - "M5N2AZI ","M5N2DYNP ","M5N2FAFXI","M5N2FAFYI","M5N2FAFZI","M5N2FAGXI","M5N2FAGYI","M5N2FAGZI","M5N2FAMXI","M5N2FAMYI", & - "M5N2FAMZI","M5N2FAXI ","M5N2FAYI ","M5N2FAZI ","M5N2FBFXI","M5N2FBFYI","M5N2FBFZI","M5N2FBXI ","M5N2FBYI ","M5N2FBZI ", & - "M5N2FDXI ","M5N2FDYI ","M5N2FDZI ","M5N2FIXI ","M5N2FIYI ","M5N2FIZI ","M5N2FMGXI","M5N2FMGYI","M5N2FMGZI","M5N2MBFXI", & - "M5N2MBFYI","M5N2MBFZI","M5N2MBXI ","M5N2MBYI ","M5N2MBZI ","M5N2STAXI","M5N2STAYI","M5N2STAZI","M5N2STVXI","M5N2STVYI", & - "M5N2STVZI","M5N2VXI ","M5N2VYI ","M5N2VZI ","M5N3AXI ","M5N3AYI ","M5N3AZI ","M5N3DYNP ","M5N3FAFXI","M5N3FAFYI", & - "M5N3FAFZI","M5N3FAGXI","M5N3FAGYI","M5N3FAGZI","M5N3FAMXI","M5N3FAMYI","M5N3FAMZI","M5N3FAXI ","M5N3FAYI ","M5N3FAZI ", & - "M5N3FBFXI","M5N3FBFYI","M5N3FBFZI","M5N3FBXI ","M5N3FBYI ","M5N3FBZI ","M5N3FDXI ","M5N3FDYI ","M5N3FDZI ","M5N3FIXI ", & - "M5N3FIYI ","M5N3FIZI ","M5N3FMGXI","M5N3FMGYI","M5N3FMGZI","M5N3MBFXI","M5N3MBFYI","M5N3MBFZI","M5N3MBXI ","M5N3MBYI ", & - "M5N3MBZI ","M5N3STAXI","M5N3STAYI","M5N3STAZI","M5N3STVXI","M5N3STVYI","M5N3STVZI","M5N3VXI ","M5N3VYI ","M5N3VZI ", & - "M5N4AXI ","M5N4AYI ","M5N4AZI ","M5N4DYNP ","M5N4FAFXI","M5N4FAFYI","M5N4FAFZI","M5N4FAGXI","M5N4FAGYI","M5N4FAGZI", & - "M5N4FAMXI","M5N4FAMYI","M5N4FAMZI","M5N4FAXI ","M5N4FAYI ","M5N4FAZI ","M5N4FBFXI","M5N4FBFYI","M5N4FBFZI","M5N4FBXI ", & - "M5N4FBYI ","M5N4FBZI ","M5N4FDXI ","M5N4FDYI ","M5N4FDZI ","M5N4FIXI ","M5N4FIYI ","M5N4FIZI ","M5N4FMGXI","M5N4FMGYI", & - "M5N4FMGZI","M5N4MBFXI","M5N4MBFYI","M5N4MBFZI","M5N4MBXI ","M5N4MBYI ","M5N4MBZI ","M5N4STAXI","M5N4STAYI","M5N4STAZI", & - "M5N4STVXI","M5N4STVYI","M5N4STVZI","M5N4VXI ","M5N4VYI ","M5N4VZI ","M5N5AXI ","M5N5AYI ","M5N5AZI ","M5N5DYNP ", & - "M5N5FAFXI","M5N5FAFYI","M5N5FAFZI","M5N5FAGXI","M5N5FAGYI","M5N5FAGZI","M5N5FAMXI","M5N5FAMYI","M5N5FAMZI","M5N5FAXI ", & - "M5N5FAYI ","M5N5FAZI ","M5N5FBFXI","M5N5FBFYI","M5N5FBFZI","M5N5FBXI ","M5N5FBYI ","M5N5FBZI ","M5N5FDXI ","M5N5FDYI ", & - "M5N5FDZI ","M5N5FIXI ","M5N5FIYI ","M5N5FIZI ","M5N5FMGXI","M5N5FMGYI","M5N5FMGZI","M5N5MBFXI","M5N5MBFYI","M5N5MBFZI", & - "M5N5MBXI ","M5N5MBYI ","M5N5MBZI ","M5N5STAXI","M5N5STAYI","M5N5STAZI","M5N5STVXI","M5N5STVYI","M5N5STVZI","M5N5VXI ", & - "M5N5VYI ","M5N5VZI ","M5N6AXI ","M5N6AYI ","M5N6AZI ","M5N6DYNP ","M5N6FAFXI","M5N6FAFYI","M5N6FAFZI","M5N6FAGXI", & - "M5N6FAGYI","M5N6FAGZI","M5N6FAMXI","M5N6FAMYI","M5N6FAMZI","M5N6FAXI ","M5N6FAYI ","M5N6FAZI ","M5N6FBFXI","M5N6FBFYI", & - "M5N6FBFZI","M5N6FBXI ","M5N6FBYI ","M5N6FBZI ","M5N6FDXI ","M5N6FDYI ","M5N6FDZI ","M5N6FIXI ","M5N6FIYI ","M5N6FIZI ", & - "M5N6FMGXI","M5N6FMGYI","M5N6FMGZI","M5N6MBFXI","M5N6MBFYI","M5N6MBFZI","M5N6MBXI ","M5N6MBYI ","M5N6MBZI ","M5N6STAXI", & - "M5N6STAYI","M5N6STAZI","M5N6STVXI","M5N6STVYI","M5N6STVZI","M5N6VXI ","M5N6VYI ","M5N6VZI ","M5N7AXI ","M5N7AYI ", & - "M5N7AZI ","M5N7DYNP ","M5N7FAFXI","M5N7FAFYI","M5N7FAFZI","M5N7FAGXI","M5N7FAGYI","M5N7FAGZI","M5N7FAMXI","M5N7FAMYI", & - "M5N7FAMZI","M5N7FAXI ","M5N7FAYI ","M5N7FAZI ","M5N7FBFXI","M5N7FBFYI","M5N7FBFZI","M5N7FBXI ","M5N7FBYI ","M5N7FBZI ", & - "M5N7FDXI ","M5N7FDYI ","M5N7FDZI ","M5N7FIXI ","M5N7FIYI ","M5N7FIZI ","M5N7FMGXI","M5N7FMGYI","M5N7FMGZI","M5N7MBFXI", & - "M5N7MBFYI","M5N7MBFZI","M5N7MBXI ","M5N7MBYI ","M5N7MBZI ","M5N7STAXI","M5N7STAYI","M5N7STAZI","M5N7STVXI","M5N7STVYI", & - "M5N7STVZI","M5N7VXI ","M5N7VYI ","M5N7VZI ","M5N8AXI ","M5N8AYI ","M5N8AZI ","M5N8DYNP ","M5N8FAFXI","M5N8FAFYI", & - "M5N8FAFZI","M5N8FAGXI","M5N8FAGYI","M5N8FAGZI","M5N8FAMXI","M5N8FAMYI","M5N8FAMZI","M5N8FAXI ","M5N8FAYI ","M5N8FAZI ", & - "M5N8FBFXI","M5N8FBFYI","M5N8FBFZI","M5N8FBXI ","M5N8FBYI ","M5N8FBZI ","M5N8FDXI ","M5N8FDYI ","M5N8FDZI ","M5N8FIXI ", & - "M5N8FIYI ","M5N8FIZI ","M5N8FMGXI","M5N8FMGYI","M5N8FMGZI","M5N8MBFXI","M5N8MBFYI","M5N8MBFZI","M5N8MBXI ","M5N8MBYI ", & - "M5N8MBZI ","M5N8STAXI","M5N8STAYI","M5N8STAZI","M5N8STVXI","M5N8STVYI","M5N8STVZI","M5N8VXI ","M5N8VYI ","M5N8VZI ", & - "M5N9AXI ","M5N9AYI ","M5N9AZI ","M5N9DYNP ","M5N9FAFXI","M5N9FAFYI","M5N9FAFZI","M5N9FAGXI","M5N9FAGYI","M5N9FAGZI", & - "M5N9FAMXI","M5N9FAMYI","M5N9FAMZI","M5N9FAXI ","M5N9FAYI ","M5N9FAZI ","M5N9FBFXI","M5N9FBFYI","M5N9FBFZI","M5N9FBXI ", & - "M5N9FBYI ","M5N9FBZI ","M5N9FDXI ","M5N9FDYI ","M5N9FDZI ","M5N9FIXI ","M5N9FIYI ","M5N9FIZI ","M5N9FMGXI","M5N9FMGYI", & - "M5N9FMGZI","M5N9MBFXI","M5N9MBFYI","M5N9MBFZI","M5N9MBXI ","M5N9MBYI ","M5N9MBZI ","M5N9STAXI","M5N9STAYI","M5N9STAZI", & - "M5N9STVXI","M5N9STVYI","M5N9STVZI","M5N9VXI ","M5N9VYI ","M5N9VZI ","M6N1AXI ","M6N1AYI ","M6N1AZI ","M6N1DYNP ", & - "M6N1FAFXI","M6N1FAFYI","M6N1FAFZI","M6N1FAGXI","M6N1FAGYI","M6N1FAGZI","M6N1FAMXI","M6N1FAMYI","M6N1FAMZI","M6N1FAXI ", & - "M6N1FAYI ","M6N1FAZI ","M6N1FBFXI","M6N1FBFYI","M6N1FBFZI","M6N1FBXI ","M6N1FBYI ","M6N1FBZI ","M6N1FDXI ","M6N1FDYI ", & - "M6N1FDZI ","M6N1FIXI ","M6N1FIYI ","M6N1FIZI ","M6N1FMGXI","M6N1FMGYI","M6N1FMGZI","M6N1MBFXI","M6N1MBFYI","M6N1MBFZI", & - "M6N1MBXI ","M6N1MBYI ","M6N1MBZI ","M6N1STAXI","M6N1STAYI","M6N1STAZI","M6N1STVXI","M6N1STVYI","M6N1STVZI","M6N1VXI ", & - "M6N1VYI ","M6N1VZI ","M6N2AXI ","M6N2AYI ","M6N2AZI ","M6N2DYNP ","M6N2FAFXI","M6N2FAFYI","M6N2FAFZI","M6N2FAGXI", & - "M6N2FAGYI","M6N2FAGZI","M6N2FAMXI","M6N2FAMYI","M6N2FAMZI","M6N2FAXI ","M6N2FAYI ","M6N2FAZI ","M6N2FBFXI","M6N2FBFYI", & - "M6N2FBFZI","M6N2FBXI ","M6N2FBYI ","M6N2FBZI ","M6N2FDXI ","M6N2FDYI ","M6N2FDZI ","M6N2FIXI ","M6N2FIYI ","M6N2FIZI ", & - "M6N2FMGXI","M6N2FMGYI","M6N2FMGZI","M6N2MBFXI","M6N2MBFYI","M6N2MBFZI","M6N2MBXI ","M6N2MBYI ","M6N2MBZI ","M6N2STAXI", & - "M6N2STAYI","M6N2STAZI","M6N2STVXI","M6N2STVYI","M6N2STVZI","M6N2VXI ","M6N2VYI ","M6N2VZI ","M6N3AXI ","M6N3AYI ", & - "M6N3AZI ","M6N3DYNP ","M6N3FAFXI","M6N3FAFYI","M6N3FAFZI","M6N3FAGXI","M6N3FAGYI","M6N3FAGZI","M6N3FAMXI","M6N3FAMYI", & - "M6N3FAMZI","M6N3FAXI ","M6N3FAYI ","M6N3FAZI ","M6N3FBFXI","M6N3FBFYI","M6N3FBFZI","M6N3FBXI ","M6N3FBYI ","M6N3FBZI ", & - "M6N3FDXI ","M6N3FDYI ","M6N3FDZI ","M6N3FIXI ","M6N3FIYI ","M6N3FIZI ","M6N3FMGXI","M6N3FMGYI","M6N3FMGZI","M6N3MBFXI", & - "M6N3MBFYI","M6N3MBFZI","M6N3MBXI ","M6N3MBYI ","M6N3MBZI ","M6N3STAXI","M6N3STAYI","M6N3STAZI","M6N3STVXI","M6N3STVYI", & - "M6N3STVZI","M6N3VXI ","M6N3VYI ","M6N3VZI ","M6N4AXI ","M6N4AYI ","M6N4AZI ","M6N4DYNP ","M6N4FAFXI","M6N4FAFYI", & - "M6N4FAFZI","M6N4FAGXI","M6N4FAGYI","M6N4FAGZI","M6N4FAMXI","M6N4FAMYI","M6N4FAMZI","M6N4FAXI ","M6N4FAYI ","M6N4FAZI ", & - "M6N4FBFXI","M6N4FBFYI","M6N4FBFZI","M6N4FBXI ","M6N4FBYI ","M6N4FBZI ","M6N4FDXI ","M6N4FDYI ","M6N4FDZI ","M6N4FIXI ", & - "M6N4FIYI ","M6N4FIZI ","M6N4FMGXI","M6N4FMGYI","M6N4FMGZI","M6N4MBFXI","M6N4MBFYI","M6N4MBFZI","M6N4MBXI ","M6N4MBYI ", & - "M6N4MBZI ","M6N4STAXI","M6N4STAYI","M6N4STAZI","M6N4STVXI","M6N4STVYI","M6N4STVZI","M6N4VXI ","M6N4VYI ","M6N4VZI ", & - "M6N5AXI ","M6N5AYI ","M6N5AZI ","M6N5DYNP ","M6N5FAFXI","M6N5FAFYI","M6N5FAFZI","M6N5FAGXI","M6N5FAGYI","M6N5FAGZI", & - "M6N5FAMXI","M6N5FAMYI","M6N5FAMZI","M6N5FAXI ","M6N5FAYI ","M6N5FAZI ","M6N5FBFXI","M6N5FBFYI","M6N5FBFZI","M6N5FBXI ", & - "M6N5FBYI ","M6N5FBZI ","M6N5FDXI ","M6N5FDYI ","M6N5FDZI ","M6N5FIXI ","M6N5FIYI ","M6N5FIZI ","M6N5FMGXI","M6N5FMGYI", & - "M6N5FMGZI","M6N5MBFXI","M6N5MBFYI","M6N5MBFZI","M6N5MBXI ","M6N5MBYI ","M6N5MBZI ","M6N5STAXI","M6N5STAYI","M6N5STAZI", & - "M6N5STVXI","M6N5STVYI","M6N5STVZI","M6N5VXI ","M6N5VYI ","M6N5VZI ","M6N6AXI ","M6N6AYI ","M6N6AZI ","M6N6DYNP ", & - "M6N6FAFXI","M6N6FAFYI","M6N6FAFZI","M6N6FAGXI","M6N6FAGYI","M6N6FAGZI","M6N6FAMXI","M6N6FAMYI","M6N6FAMZI","M6N6FAXI ", & - "M6N6FAYI ","M6N6FAZI ","M6N6FBFXI","M6N6FBFYI","M6N6FBFZI","M6N6FBXI ","M6N6FBYI ","M6N6FBZI ","M6N6FDXI ","M6N6FDYI ", & - "M6N6FDZI ","M6N6FIXI ","M6N6FIYI ","M6N6FIZI ","M6N6FMGXI","M6N6FMGYI","M6N6FMGZI","M6N6MBFXI","M6N6MBFYI","M6N6MBFZI", & - "M6N6MBXI ","M6N6MBYI ","M6N6MBZI ","M6N6STAXI","M6N6STAYI","M6N6STAZI","M6N6STVXI","M6N6STVYI","M6N6STVZI","M6N6VXI ", & - "M6N6VYI ","M6N6VZI ","M6N7AXI ","M6N7AYI ","M6N7AZI ","M6N7DYNP ","M6N7FAFXI","M6N7FAFYI","M6N7FAFZI","M6N7FAGXI", & - "M6N7FAGYI","M6N7FAGZI","M6N7FAMXI","M6N7FAMYI","M6N7FAMZI","M6N7FAXI ","M6N7FAYI ","M6N7FAZI ","M6N7FBFXI","M6N7FBFYI", & - "M6N7FBFZI","M6N7FBXI ","M6N7FBYI ","M6N7FBZI ","M6N7FDXI ","M6N7FDYI ","M6N7FDZI ","M6N7FIXI ","M6N7FIYI ","M6N7FIZI ", & - "M6N7FMGXI","M6N7FMGYI","M6N7FMGZI","M6N7MBFXI","M6N7MBFYI","M6N7MBFZI","M6N7MBXI ","M6N7MBYI ","M6N7MBZI ","M6N7STAXI", & - "M6N7STAYI","M6N7STAZI","M6N7STVXI","M6N7STVYI","M6N7STVZI","M6N7VXI ","M6N7VYI ","M6N7VZI ","M6N8AXI ","M6N8AYI ", & - "M6N8AZI ","M6N8DYNP ","M6N8FAFXI","M6N8FAFYI","M6N8FAFZI","M6N8FAGXI","M6N8FAGYI","M6N8FAGZI","M6N8FAMXI","M6N8FAMYI", & - "M6N8FAMZI","M6N8FAXI ","M6N8FAYI ","M6N8FAZI ","M6N8FBFXI","M6N8FBFYI","M6N8FBFZI","M6N8FBXI ","M6N8FBYI ","M6N8FBZI ", & - "M6N8FDXI ","M6N8FDYI ","M6N8FDZI ","M6N8FIXI ","M6N8FIYI ","M6N8FIZI ","M6N8FMGXI","M6N8FMGYI","M6N8FMGZI","M6N8MBFXI", & - "M6N8MBFYI","M6N8MBFZI","M6N8MBXI ","M6N8MBYI ","M6N8MBZI ","M6N8STAXI","M6N8STAYI","M6N8STAZI","M6N8STVXI","M6N8STVYI", & - "M6N8STVZI","M6N8VXI ","M6N8VYI ","M6N8VZI ","M6N9AXI ","M6N9AYI ","M6N9AZI ","M6N9DYNP ","M6N9FAFXI","M6N9FAFYI", & - "M6N9FAFZI","M6N9FAGXI","M6N9FAGYI","M6N9FAGZI","M6N9FAMXI","M6N9FAMYI","M6N9FAMZI","M6N9FAXI ","M6N9FAYI ","M6N9FAZI ", & - "M6N9FBFXI","M6N9FBFYI","M6N9FBFZI","M6N9FBXI ","M6N9FBYI ","M6N9FBZI ","M6N9FDXI ","M6N9FDYI ","M6N9FDZI ","M6N9FIXI ", & - "M6N9FIYI ","M6N9FIZI ","M6N9FMGXI","M6N9FMGYI","M6N9FMGZI","M6N9MBFXI","M6N9MBFYI","M6N9MBFZI","M6N9MBXI ","M6N9MBYI ", & - "M6N9MBZI ","M6N9STAXI","M6N9STAYI","M6N9STAZI","M6N9STVXI","M6N9STVYI","M6N9STVZI","M6N9VXI ","M6N9VYI ","M6N9VZI ", & - "M7N1AXI ","M7N1AYI ","M7N1AZI ","M7N1DYNP ","M7N1FAFXI","M7N1FAFYI","M7N1FAFZI","M7N1FAGXI","M7N1FAGYI","M7N1FAGZI", & - "M7N1FAMXI","M7N1FAMYI","M7N1FAMZI","M7N1FAXI ","M7N1FAYI ","M7N1FAZI ","M7N1FBFXI","M7N1FBFYI","M7N1FBFZI","M7N1FBXI ", & - "M7N1FBYI ","M7N1FBZI ","M7N1FDXI ","M7N1FDYI ","M7N1FDZI ","M7N1FIXI ","M7N1FIYI ","M7N1FIZI ","M7N1FMGXI","M7N1FMGYI", & - "M7N1FMGZI","M7N1MBFXI","M7N1MBFYI","M7N1MBFZI","M7N1MBXI ","M7N1MBYI ","M7N1MBZI ","M7N1STAXI","M7N1STAYI","M7N1STAZI", & - "M7N1STVXI","M7N1STVYI","M7N1STVZI","M7N1VXI ","M7N1VYI ","M7N1VZI ","M7N2AXI ","M7N2AYI ","M7N2AZI ","M7N2DYNP ", & - "M7N2FAFXI","M7N2FAFYI","M7N2FAFZI","M7N2FAGXI","M7N2FAGYI","M7N2FAGZI","M7N2FAMXI","M7N2FAMYI","M7N2FAMZI","M7N2FAXI ", & - "M7N2FAYI ","M7N2FAZI ","M7N2FBFXI","M7N2FBFYI","M7N2FBFZI","M7N2FBXI ","M7N2FBYI ","M7N2FBZI ","M7N2FDXI ","M7N2FDYI ", & - "M7N2FDZI ","M7N2FIXI ","M7N2FIYI ","M7N2FIZI ","M7N2FMGXI","M7N2FMGYI","M7N2FMGZI","M7N2MBFXI","M7N2MBFYI","M7N2MBFZI", & - "M7N2MBXI ","M7N2MBYI ","M7N2MBZI ","M7N2STAXI","M7N2STAYI","M7N2STAZI","M7N2STVXI","M7N2STVYI","M7N2STVZI","M7N2VXI ", & - "M7N2VYI ","M7N2VZI ","M7N3AXI ","M7N3AYI ","M7N3AZI ","M7N3DYNP ","M7N3FAFXI","M7N3FAFYI","M7N3FAFZI","M7N3FAGXI", & - "M7N3FAGYI","M7N3FAGZI","M7N3FAMXI","M7N3FAMYI","M7N3FAMZI","M7N3FAXI ","M7N3FAYI ","M7N3FAZI ","M7N3FBFXI","M7N3FBFYI", & - "M7N3FBFZI","M7N3FBXI ","M7N3FBYI ","M7N3FBZI ","M7N3FDXI ","M7N3FDYI ","M7N3FDZI ","M7N3FIXI ","M7N3FIYI ","M7N3FIZI ", & - "M7N3FMGXI","M7N3FMGYI","M7N3FMGZI","M7N3MBFXI","M7N3MBFYI","M7N3MBFZI","M7N3MBXI ","M7N3MBYI ","M7N3MBZI ","M7N3STAXI", & - "M7N3STAYI","M7N3STAZI","M7N3STVXI","M7N3STVYI","M7N3STVZI","M7N3VXI ","M7N3VYI ","M7N3VZI ","M7N4AXI ","M7N4AYI ", & - "M7N4AZI ","M7N4DYNP ","M7N4FAFXI","M7N4FAFYI","M7N4FAFZI","M7N4FAGXI","M7N4FAGYI","M7N4FAGZI","M7N4FAMXI","M7N4FAMYI", & - "M7N4FAMZI","M7N4FAXI ","M7N4FAYI ","M7N4FAZI ","M7N4FBFXI","M7N4FBFYI","M7N4FBFZI","M7N4FBXI ","M7N4FBYI ","M7N4FBZI ", & - "M7N4FDXI ","M7N4FDYI ","M7N4FDZI ","M7N4FIXI ","M7N4FIYI ","M7N4FIZI ","M7N4FMGXI","M7N4FMGYI","M7N4FMGZI","M7N4MBFXI", & - "M7N4MBFYI","M7N4MBFZI","M7N4MBXI ","M7N4MBYI ","M7N4MBZI ","M7N4STAXI","M7N4STAYI","M7N4STAZI","M7N4STVXI","M7N4STVYI", & - "M7N4STVZI","M7N4VXI ","M7N4VYI ","M7N4VZI ","M7N5AXI ","M7N5AYI ","M7N5AZI ","M7N5DYNP ","M7N5FAFXI","M7N5FAFYI", & - "M7N5FAFZI","M7N5FAGXI","M7N5FAGYI","M7N5FAGZI","M7N5FAMXI","M7N5FAMYI","M7N5FAMZI","M7N5FAXI ","M7N5FAYI ","M7N5FAZI ", & - "M7N5FBFXI","M7N5FBFYI","M7N5FBFZI","M7N5FBXI ","M7N5FBYI ","M7N5FBZI ","M7N5FDXI ","M7N5FDYI ","M7N5FDZI ","M7N5FIXI ", & - "M7N5FIYI ","M7N5FIZI ","M7N5FMGXI","M7N5FMGYI","M7N5FMGZI","M7N5MBFXI","M7N5MBFYI","M7N5MBFZI","M7N5MBXI ","M7N5MBYI ", & - "M7N5MBZI ","M7N5STAXI","M7N5STAYI","M7N5STAZI","M7N5STVXI","M7N5STVYI","M7N5STVZI","M7N5VXI ","M7N5VYI ","M7N5VZI ", & - "M7N6AXI ","M7N6AYI ","M7N6AZI ","M7N6DYNP ","M7N6FAFXI","M7N6FAFYI","M7N6FAFZI","M7N6FAGXI","M7N6FAGYI","M7N6FAGZI", & - "M7N6FAMXI","M7N6FAMYI","M7N6FAMZI","M7N6FAXI ","M7N6FAYI ","M7N6FAZI ","M7N6FBFXI","M7N6FBFYI","M7N6FBFZI","M7N6FBXI ", & - "M7N6FBYI ","M7N6FBZI ","M7N6FDXI ","M7N6FDYI ","M7N6FDZI ","M7N6FIXI ","M7N6FIYI ","M7N6FIZI ","M7N6FMGXI","M7N6FMGYI", & - "M7N6FMGZI","M7N6MBFXI","M7N6MBFYI","M7N6MBFZI","M7N6MBXI ","M7N6MBYI ","M7N6MBZI ","M7N6STAXI","M7N6STAYI","M7N6STAZI", & - "M7N6STVXI","M7N6STVYI","M7N6STVZI","M7N6VXI ","M7N6VYI ","M7N6VZI ","M7N7AXI ","M7N7AYI ","M7N7AZI ","M7N7DYNP ", & - "M7N7FAFXI","M7N7FAFYI","M7N7FAFZI","M7N7FAGXI","M7N7FAGYI","M7N7FAGZI","M7N7FAMXI","M7N7FAMYI","M7N7FAMZI","M7N7FAXI ", & - "M7N7FAYI ","M7N7FAZI ","M7N7FBFXI","M7N7FBFYI","M7N7FBFZI","M7N7FBXI ","M7N7FBYI ","M7N7FBZI ","M7N7FDXI ","M7N7FDYI ", & - "M7N7FDZI ","M7N7FIXI ","M7N7FIYI ","M7N7FIZI ","M7N7FMGXI","M7N7FMGYI","M7N7FMGZI","M7N7MBFXI","M7N7MBFYI","M7N7MBFZI", & - "M7N7MBXI ","M7N7MBYI ","M7N7MBZI ","M7N7STAXI","M7N7STAYI","M7N7STAZI","M7N7STVXI","M7N7STVYI","M7N7STVZI","M7N7VXI ", & - "M7N7VYI ","M7N7VZI ","M7N8AXI ","M7N8AYI ","M7N8AZI ","M7N8DYNP ","M7N8FAFXI","M7N8FAFYI","M7N8FAFZI","M7N8FAGXI", & - "M7N8FAGYI","M7N8FAGZI","M7N8FAMXI","M7N8FAMYI","M7N8FAMZI","M7N8FAXI ","M7N8FAYI ","M7N8FAZI ","M7N8FBFXI","M7N8FBFYI", & - "M7N8FBFZI","M7N8FBXI ","M7N8FBYI ","M7N8FBZI ","M7N8FDXI ","M7N8FDYI ","M7N8FDZI ","M7N8FIXI ","M7N8FIYI ","M7N8FIZI ", & - "M7N8FMGXI","M7N8FMGYI","M7N8FMGZI","M7N8MBFXI","M7N8MBFYI","M7N8MBFZI","M7N8MBXI ","M7N8MBYI ","M7N8MBZI ","M7N8STAXI", & - "M7N8STAYI","M7N8STAZI","M7N8STVXI","M7N8STVYI","M7N8STVZI","M7N8VXI ","M7N8VYI ","M7N8VZI ","M7N9AXI ","M7N9AYI ", & - "M7N9AZI ","M7N9DYNP ","M7N9FAFXI","M7N9FAFYI","M7N9FAFZI","M7N9FAGXI","M7N9FAGYI","M7N9FAGZI","M7N9FAMXI","M7N9FAMYI", & - "M7N9FAMZI","M7N9FAXI ","M7N9FAYI ","M7N9FAZI ","M7N9FBFXI","M7N9FBFYI","M7N9FBFZI","M7N9FBXI ","M7N9FBYI ","M7N9FBZI ", & - "M7N9FDXI ","M7N9FDYI ","M7N9FDZI ","M7N9FIXI ","M7N9FIYI ","M7N9FIZI ","M7N9FMGXI","M7N9FMGYI","M7N9FMGZI","M7N9MBFXI", & - "M7N9MBFYI","M7N9MBFZI","M7N9MBXI ","M7N9MBYI ","M7N9MBZI ","M7N9STAXI","M7N9STAYI","M7N9STAZI","M7N9STVXI","M7N9STVYI", & - "M7N9STVZI","M7N9VXI ","M7N9VYI ","M7N9VZI ","M8N1AXI ","M8N1AYI ","M8N1AZI ","M8N1DYNP ","M8N1FAFXI","M8N1FAFYI", & - "M8N1FAFZI","M8N1FAGXI","M8N1FAGYI","M8N1FAGZI","M8N1FAMXI","M8N1FAMYI","M8N1FAMZI","M8N1FAXI ","M8N1FAYI ","M8N1FAZI ", & - "M8N1FBFXI","M8N1FBFYI","M8N1FBFZI","M8N1FBXI ","M8N1FBYI ","M8N1FBZI ","M8N1FDXI ","M8N1FDYI ","M8N1FDZI ","M8N1FIXI ", & - "M8N1FIYI ","M8N1FIZI ","M8N1FMGXI","M8N1FMGYI","M8N1FMGZI","M8N1MBFXI","M8N1MBFYI","M8N1MBFZI","M8N1MBXI ","M8N1MBYI ", & - "M8N1MBZI ","M8N1STAXI","M8N1STAYI","M8N1STAZI","M8N1STVXI","M8N1STVYI","M8N1STVZI","M8N1VXI ","M8N1VYI ","M8N1VZI ", & - "M8N2AXI ","M8N2AYI ","M8N2AZI ","M8N2DYNP ","M8N2FAFXI","M8N2FAFYI","M8N2FAFZI","M8N2FAGXI","M8N2FAGYI","M8N2FAGZI", & - "M8N2FAMXI","M8N2FAMYI","M8N2FAMZI","M8N2FAXI ","M8N2FAYI ","M8N2FAZI ","M8N2FBFXI","M8N2FBFYI","M8N2FBFZI","M8N2FBXI ", & - "M8N2FBYI ","M8N2FBZI ","M8N2FDXI ","M8N2FDYI ","M8N2FDZI ","M8N2FIXI ","M8N2FIYI ","M8N2FIZI ","M8N2FMGXI","M8N2FMGYI", & - "M8N2FMGZI","M8N2MBFXI","M8N2MBFYI","M8N2MBFZI","M8N2MBXI ","M8N2MBYI ","M8N2MBZI ","M8N2STAXI","M8N2STAYI","M8N2STAZI", & - "M8N2STVXI","M8N2STVYI","M8N2STVZI","M8N2VXI ","M8N2VYI ","M8N2VZI ","M8N3AXI ","M8N3AYI ","M8N3AZI ","M8N3DYNP ", & - "M8N3FAFXI","M8N3FAFYI","M8N3FAFZI","M8N3FAGXI","M8N3FAGYI","M8N3FAGZI","M8N3FAMXI","M8N3FAMYI","M8N3FAMZI","M8N3FAXI ", & - "M8N3FAYI ","M8N3FAZI ","M8N3FBFXI","M8N3FBFYI","M8N3FBFZI","M8N3FBXI ","M8N3FBYI ","M8N3FBZI ","M8N3FDXI ","M8N3FDYI ", & - "M8N3FDZI ","M8N3FIXI ","M8N3FIYI ","M8N3FIZI ","M8N3FMGXI","M8N3FMGYI","M8N3FMGZI","M8N3MBFXI","M8N3MBFYI","M8N3MBFZI", & - "M8N3MBXI ","M8N3MBYI ","M8N3MBZI ","M8N3STAXI","M8N3STAYI","M8N3STAZI","M8N3STVXI","M8N3STVYI","M8N3STVZI","M8N3VXI ", & - "M8N3VYI ","M8N3VZI ","M8N4AXI ","M8N4AYI ","M8N4AZI ","M8N4DYNP ","M8N4FAFXI","M8N4FAFYI","M8N4FAFZI","M8N4FAGXI", & - "M8N4FAGYI","M8N4FAGZI","M8N4FAMXI","M8N4FAMYI","M8N4FAMZI","M8N4FAXI ","M8N4FAYI ","M8N4FAZI ","M8N4FBFXI","M8N4FBFYI", & - "M8N4FBFZI","M8N4FBXI ","M8N4FBYI ","M8N4FBZI ","M8N4FDXI ","M8N4FDYI ","M8N4FDZI ","M8N4FIXI ","M8N4FIYI ","M8N4FIZI ", & - "M8N4FMGXI","M8N4FMGYI","M8N4FMGZI","M8N4MBFXI","M8N4MBFYI","M8N4MBFZI","M8N4MBXI ","M8N4MBYI ","M8N4MBZI ","M8N4STAXI", & - "M8N4STAYI","M8N4STAZI","M8N4STVXI","M8N4STVYI","M8N4STVZI","M8N4VXI ","M8N4VYI ","M8N4VZI ","M8N5AXI ","M8N5AYI ", & - "M8N5AZI ","M8N5DYNP ","M8N5FAFXI","M8N5FAFYI","M8N5FAFZI","M8N5FAGXI","M8N5FAGYI","M8N5FAGZI","M8N5FAMXI","M8N5FAMYI", & - "M8N5FAMZI","M8N5FAXI ","M8N5FAYI ","M8N5FAZI ","M8N5FBFXI","M8N5FBFYI","M8N5FBFZI","M8N5FBXI ","M8N5FBYI ","M8N5FBZI ", & - "M8N5FDXI ","M8N5FDYI ","M8N5FDZI ","M8N5FIXI ","M8N5FIYI ","M8N5FIZI ","M8N5FMGXI","M8N5FMGYI","M8N5FMGZI","M8N5MBFXI", & - "M8N5MBFYI","M8N5MBFZI","M8N5MBXI ","M8N5MBYI ","M8N5MBZI ","M8N5STAXI","M8N5STAYI","M8N5STAZI","M8N5STVXI","M8N5STVYI", & - "M8N5STVZI","M8N5VXI ","M8N5VYI ","M8N5VZI ","M8N6AXI ","M8N6AYI ","M8N6AZI ","M8N6DYNP ","M8N6FAFXI","M8N6FAFYI", & - "M8N6FAFZI","M8N6FAGXI","M8N6FAGYI","M8N6FAGZI","M8N6FAMXI","M8N6FAMYI","M8N6FAMZI","M8N6FAXI ","M8N6FAYI ","M8N6FAZI ", & - "M8N6FBFXI","M8N6FBFYI","M8N6FBFZI","M8N6FBXI ","M8N6FBYI ","M8N6FBZI ","M8N6FDXI ","M8N6FDYI ","M8N6FDZI ","M8N6FIXI ", & - "M8N6FIYI ","M8N6FIZI ","M8N6FMGXI","M8N6FMGYI","M8N6FMGZI","M8N6MBFXI","M8N6MBFYI","M8N6MBFZI","M8N6MBXI ","M8N6MBYI ", & - "M8N6MBZI ","M8N6STAXI","M8N6STAYI","M8N6STAZI","M8N6STVXI","M8N6STVYI","M8N6STVZI","M8N6VXI ","M8N6VYI ","M8N6VZI ", & - "M8N7AXI ","M8N7AYI ","M8N7AZI ","M8N7DYNP ","M8N7FAFXI","M8N7FAFYI","M8N7FAFZI","M8N7FAGXI","M8N7FAGYI","M8N7FAGZI", & - "M8N7FAMXI","M8N7FAMYI","M8N7FAMZI","M8N7FAXI ","M8N7FAYI ","M8N7FAZI ","M8N7FBFXI","M8N7FBFYI","M8N7FBFZI","M8N7FBXI ", & - "M8N7FBYI ","M8N7FBZI ","M8N7FDXI ","M8N7FDYI ","M8N7FDZI ","M8N7FIXI ","M8N7FIYI ","M8N7FIZI ","M8N7FMGXI","M8N7FMGYI", & - "M8N7FMGZI","M8N7MBFXI","M8N7MBFYI","M8N7MBFZI","M8N7MBXI ","M8N7MBYI ","M8N7MBZI ","M8N7STAXI","M8N7STAYI","M8N7STAZI", & - "M8N7STVXI","M8N7STVYI","M8N7STVZI","M8N7VXI ","M8N7VYI ","M8N7VZI ","M8N8AXI ","M8N8AYI ","M8N8AZI ","M8N8DYNP ", & - "M8N8FAFXI","M8N8FAFYI","M8N8FAFZI","M8N8FAGXI","M8N8FAGYI","M8N8FAGZI","M8N8FAMXI","M8N8FAMYI","M8N8FAMZI","M8N8FAXI ", & - "M8N8FAYI ","M8N8FAZI ","M8N8FBFXI","M8N8FBFYI","M8N8FBFZI","M8N8FBXI ","M8N8FBYI ","M8N8FBZI ","M8N8FDXI ","M8N8FDYI ", & - "M8N8FDZI ","M8N8FIXI ","M8N8FIYI ","M8N8FIZI ","M8N8FMGXI","M8N8FMGYI","M8N8FMGZI","M8N8MBFXI","M8N8MBFYI","M8N8MBFZI", & - "M8N8MBXI ","M8N8MBYI ","M8N8MBZI ","M8N8STAXI","M8N8STAYI","M8N8STAZI","M8N8STVXI","M8N8STVYI","M8N8STVZI","M8N8VXI ", & - "M8N8VYI ","M8N8VZI ","M8N9AXI ","M8N9AYI ","M8N9AZI ","M8N9DYNP ","M8N9FAFXI","M8N9FAFYI","M8N9FAFZI","M8N9FAGXI", & - "M8N9FAGYI","M8N9FAGZI","M8N9FAMXI","M8N9FAMYI","M8N9FAMZI","M8N9FAXI ","M8N9FAYI ","M8N9FAZI ","M8N9FBFXI","M8N9FBFYI", & - "M8N9FBFZI","M8N9FBXI ","M8N9FBYI ","M8N9FBZI ","M8N9FDXI ","M8N9FDYI ","M8N9FDZI ","M8N9FIXI ","M8N9FIYI ","M8N9FIZI ", & - "M8N9FMGXI","M8N9FMGYI","M8N9FMGZI","M8N9MBFXI","M8N9MBFYI","M8N9MBFZI","M8N9MBXI ","M8N9MBYI ","M8N9MBZI ","M8N9STAXI", & - "M8N9STAYI","M8N9STAZI","M8N9STVXI","M8N9STVYI","M8N9STVZI","M8N9VXI ","M8N9VYI ","M8N9VZI ","M9N1AXI ","M9N1AYI ", & - "M9N1AZI ","M9N1DYNP ","M9N1FAFXI","M9N1FAFYI","M9N1FAFZI","M9N1FAGXI","M9N1FAGYI","M9N1FAGZI","M9N1FAMXI","M9N1FAMYI", & - "M9N1FAMZI","M9N1FAXI ","M9N1FAYI ","M9N1FAZI ","M9N1FBFXI","M9N1FBFYI","M9N1FBFZI","M9N1FBXI ","M9N1FBYI ","M9N1FBZI ", & - "M9N1FDXI ","M9N1FDYI ","M9N1FDZI ","M9N1FIXI ","M9N1FIYI ","M9N1FIZI ","M9N1FMGXI","M9N1FMGYI","M9N1FMGZI","M9N1MBFXI", & - "M9N1MBFYI","M9N1MBFZI","M9N1MBXI ","M9N1MBYI ","M9N1MBZI ","M9N1STAXI","M9N1STAYI","M9N1STAZI","M9N1STVXI","M9N1STVYI", & - "M9N1STVZI","M9N1VXI ","M9N1VYI ","M9N1VZI ","M9N2AXI ","M9N2AYI ","M9N2AZI ","M9N2DYNP ","M9N2FAFXI","M9N2FAFYI", & - "M9N2FAFZI","M9N2FAGXI","M9N2FAGYI","M9N2FAGZI","M9N2FAMXI","M9N2FAMYI","M9N2FAMZI","M9N2FAXI ","M9N2FAYI ","M9N2FAZI ", & - "M9N2FBFXI","M9N2FBFYI","M9N2FBFZI","M9N2FBXI ","M9N2FBYI ","M9N2FBZI ","M9N2FDXI ","M9N2FDYI ","M9N2FDZI ","M9N2FIXI ", & - "M9N2FIYI ","M9N2FIZI ","M9N2FMGXI","M9N2FMGYI","M9N2FMGZI","M9N2MBFXI","M9N2MBFYI","M9N2MBFZI","M9N2MBXI ","M9N2MBYI ", & - "M9N2MBZI ","M9N2STAXI","M9N2STAYI","M9N2STAZI","M9N2STVXI","M9N2STVYI","M9N2STVZI","M9N2VXI ","M9N2VYI ","M9N2VZI ", & - "M9N3AXI ","M9N3AYI ","M9N3AZI ","M9N3DYNP ","M9N3FAFXI","M9N3FAFYI","M9N3FAFZI","M9N3FAGXI","M9N3FAGYI","M9N3FAGZI", & - "M9N3FAMXI","M9N3FAMYI","M9N3FAMZI","M9N3FAXI ","M9N3FAYI ","M9N3FAZI ","M9N3FBFXI","M9N3FBFYI","M9N3FBFZI","M9N3FBXI ", & - "M9N3FBYI ","M9N3FBZI ","M9N3FDXI ","M9N3FDYI ","M9N3FDZI ","M9N3FIXI ","M9N3FIYI ","M9N3FIZI ","M9N3FMGXI","M9N3FMGYI", & - "M9N3FMGZI","M9N3MBFXI","M9N3MBFYI","M9N3MBFZI","M9N3MBXI ","M9N3MBYI ","M9N3MBZI ","M9N3STAXI","M9N3STAYI","M9N3STAZI", & - "M9N3STVXI","M9N3STVYI","M9N3STVZI","M9N3VXI ","M9N3VYI ","M9N3VZI ","M9N4AXI ","M9N4AYI ","M9N4AZI ","M9N4DYNP ", & - "M9N4FAFXI","M9N4FAFYI","M9N4FAFZI","M9N4FAGXI","M9N4FAGYI","M9N4FAGZI","M9N4FAMXI","M9N4FAMYI","M9N4FAMZI","M9N4FAXI ", & - "M9N4FAYI ","M9N4FAZI ","M9N4FBFXI","M9N4FBFYI","M9N4FBFZI","M9N4FBXI ","M9N4FBYI ","M9N4FBZI ","M9N4FDXI ","M9N4FDYI ", & - "M9N4FDZI ","M9N4FIXI ","M9N4FIYI ","M9N4FIZI ","M9N4FMGXI","M9N4FMGYI","M9N4FMGZI","M9N4MBFXI","M9N4MBFYI","M9N4MBFZI", & - "M9N4MBXI ","M9N4MBYI ","M9N4MBZI ","M9N4STAXI","M9N4STAYI","M9N4STAZI","M9N4STVXI","M9N4STVYI","M9N4STVZI","M9N4VXI ", & - "M9N4VYI ","M9N4VZI ","M9N5AXI ","M9N5AYI ","M9N5AZI ","M9N5DYNP ","M9N5FAFXI","M9N5FAFYI","M9N5FAFZI","M9N5FAGXI", & - "M9N5FAGYI","M9N5FAGZI","M9N5FAMXI","M9N5FAMYI","M9N5FAMZI","M9N5FAXI ","M9N5FAYI ","M9N5FAZI ","M9N5FBFXI","M9N5FBFYI", & - "M9N5FBFZI","M9N5FBXI ","M9N5FBYI ","M9N5FBZI ","M9N5FDXI ","M9N5FDYI ","M9N5FDZI ","M9N5FIXI ","M9N5FIYI ","M9N5FIZI ", & - "M9N5FMGXI","M9N5FMGYI","M9N5FMGZI","M9N5MBFXI","M9N5MBFYI","M9N5MBFZI","M9N5MBXI ","M9N5MBYI ","M9N5MBZI ","M9N5STAXI", & - "M9N5STAYI","M9N5STAZI","M9N5STVXI","M9N5STVYI","M9N5STVZI","M9N5VXI ","M9N5VYI ","M9N5VZI ","M9N6AXI ","M9N6AYI ", & - "M9N6AZI ","M9N6DYNP ","M9N6FAFXI","M9N6FAFYI","M9N6FAFZI","M9N6FAGXI","M9N6FAGYI","M9N6FAGZI","M9N6FAMXI","M9N6FAMYI", & - "M9N6FAMZI","M9N6FAXI ","M9N6FAYI ","M9N6FAZI ","M9N6FBFXI","M9N6FBFYI","M9N6FBFZI","M9N6FBXI ","M9N6FBYI ","M9N6FBZI ", & - "M9N6FDXI ","M9N6FDYI ","M9N6FDZI ","M9N6FIXI ","M9N6FIYI ","M9N6FIZI ","M9N6FMGXI","M9N6FMGYI","M9N6FMGZI","M9N6MBFXI", & - "M9N6MBFYI","M9N6MBFZI","M9N6MBXI ","M9N6MBYI ","M9N6MBZI ","M9N6STAXI","M9N6STAYI","M9N6STAZI","M9N6STVXI","M9N6STVYI", & - "M9N6STVZI","M9N6VXI ","M9N6VYI ","M9N6VZI ","M9N7AXI ","M9N7AYI ","M9N7AZI ","M9N7DYNP ","M9N7FAFXI","M9N7FAFYI", & - "M9N7FAFZI","M9N7FAGXI","M9N7FAGYI","M9N7FAGZI","M9N7FAMXI","M9N7FAMYI","M9N7FAMZI","M9N7FAXI ","M9N7FAYI ","M9N7FAZI ", & - "M9N7FBFXI","M9N7FBFYI","M9N7FBFZI","M9N7FBXI ","M9N7FBYI ","M9N7FBZI ","M9N7FDXI ","M9N7FDYI ","M9N7FDZI ","M9N7FIXI ", & - "M9N7FIYI ","M9N7FIZI ","M9N7FMGXI","M9N7FMGYI","M9N7FMGZI","M9N7MBFXI","M9N7MBFYI","M9N7MBFZI","M9N7MBXI ","M9N7MBYI ", & - "M9N7MBZI ","M9N7STAXI","M9N7STAYI","M9N7STAZI","M9N7STVXI","M9N7STVYI","M9N7STVZI","M9N7VXI ","M9N7VYI ","M9N7VZI ", & - "M9N8AXI ","M9N8AYI ","M9N8AZI ","M9N8DYNP ","M9N8FAFXI","M9N8FAFYI","M9N8FAFZI","M9N8FAGXI","M9N8FAGYI","M9N8FAGZI", & - "M9N8FAMXI","M9N8FAMYI","M9N8FAMZI","M9N8FAXI ","M9N8FAYI ","M9N8FAZI ","M9N8FBFXI","M9N8FBFYI","M9N8FBFZI","M9N8FBXI ", & - "M9N8FBYI ","M9N8FBZI ","M9N8FDXI ","M9N8FDYI ","M9N8FDZI ","M9N8FIXI ","M9N8FIYI ","M9N8FIZI ","M9N8FMGXI","M9N8FMGYI", & - "M9N8FMGZI","M9N8MBFXI","M9N8MBFYI","M9N8MBFZI","M9N8MBXI ","M9N8MBYI ","M9N8MBZI ","M9N8STAXI","M9N8STAYI","M9N8STAZI", & - "M9N8STVXI","M9N8STVYI","M9N8STVZI","M9N8VXI ","M9N8VYI ","M9N8VZI ","M9N9AXI ","M9N9AYI ","M9N9AZI ","M9N9DYNP ", & - "M9N9FAFXI","M9N9FAFYI","M9N9FAFZI","M9N9FAGXI","M9N9FAGYI","M9N9FAGZI","M9N9FAMXI","M9N9FAMYI","M9N9FAMZI","M9N9FAXI ", & - "M9N9FAYI ","M9N9FAZI ","M9N9FBFXI","M9N9FBFYI","M9N9FBFZI","M9N9FBXI ","M9N9FBYI ","M9N9FBZI ","M9N9FDXI ","M9N9FDYI ", & - "M9N9FDZI ","M9N9FIXI ","M9N9FIYI ","M9N9FIZI ","M9N9FMGXI","M9N9FMGYI","M9N9FMGZI","M9N9MBFXI","M9N9MBFYI","M9N9MBFZI", & - "M9N9MBXI ","M9N9MBYI ","M9N9MBZI ","M9N9STAXI","M9N9STAYI","M9N9STAZI","M9N9STVXI","M9N9STVYI","M9N9STVZI","M9N9VXI ", & - "M9N9VYI ","M9N9VZI "/) - INTEGER(IntKi), PARAMETER :: ParamIndxAry(4032) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) - J1Axi , J1Ayi , J1Azi , J1DynP , J1FAMxi , J1FAMyi , J1FAMzi , J1FBFxi , J1FBFyi , J1FBFzi , & - J1FBxi , J1FByi , J1FBzi , J1FDxi , J1FDyi , J1FDzi , J1FIxi , J1FIyi , J1FIzi , J1MBFxi , & - J1MBFyi , J1MBFzi , J1MBxi , J1MByi , J1MBzi , J1STAxi , J1STAyi , J1STAzi , J1STVxi , J1STVyi , & - J1STVzi , J1Vxi , J1Vyi , J1Vzi , J2Axi , J2Ayi , J2Azi , J2DynP , J2FAMxi , J2FAMyi , & - J2FAMzi , J2FBFxi , J2FBFyi , J2FBFzi , J2FBxi , J2FByi , J2FBzi , J2FDxi , J2FDyi , J2FDzi , & - J2FIxi , J2FIyi , J2FIzi , J2MBFxi , J2MBFyi , J2MBFzi , J2MBxi , J2MByi , J2MBzi , J2STAxi , & - J2STAyi , J2STAzi , J2STVxi , J2STVyi , J2STVzi , J2Vxi , J2Vyi , J2Vzi , J3Axi , J3Ayi , & - J3Azi , J3DynP , J3FAMxi , J3FAMyi , J3FAMzi , J3FBFxi , J3FBFyi , J3FBFzi , J3FBxi , J3FByi , & - J3FBzi , J3FDxi , J3FDyi , J3FDzi , J3FIxi , J3FIyi , J3FIzi , J3MBFxi , J3MBFyi , J3MBFzi , & - J3MBxi , J3MByi , J3MBzi , J3STAxi , J3STAyi , J3STAzi , J3STVxi , J3STVyi , J3STVzi , J3Vxi , & - J3Vyi , J3Vzi , J4Axi , J4Ayi , J4Azi , J4DynP , J4FAMxi , J4FAMyi , J4FAMzi , J4FBFxi , & - J4FBFyi , J4FBFzi , J4FBxi , J4FByi , J4FBzi , J4FDxi , J4FDyi , J4FDzi , J4FIxi , J4FIyi , & - J4FIzi , J4MBFxi , J4MBFyi , J4MBFzi , J4MBxi , J4MByi , J4MBzi , J4STAxi , J4STAyi , J4STAzi , & - J4STVxi , J4STVyi , J4STVzi , J4Vxi , J4Vyi , J4Vzi , J5Axi , J5Ayi , J5Azi , J5DynP , & - J5FAMxi , J5FAMyi , J5FAMzi , J5FBFxi , J5FBFyi , J5FBFzi , J5FBxi , J5FByi , J5FBzi , J5FDxi , & - J5FDyi , J5FDzi , J5FIxi , J5FIyi , J5FIzi , J5MBFxi , J5MBFyi , J5MBFzi , J5MBxi , J5MByi , & - J5MBzi , J5STAxi , J5STAyi , J5STAzi , J5STVxi , J5STVyi , J5STVzi , J5Vxi , J5Vyi , J5Vzi , & - J6Axi , J6Ayi , J6Azi , J6DynP , J6FAMxi , J6FAMyi , J6FAMzi , J6FBFxi , J6FBFyi , J6FBFzi , & - J6FBxi , J6FByi , J6FBzi , J6FDxi , J6FDyi , J6FDzi , J6FIxi , J6FIyi , J6FIzi , J6MBFxi , & - J6MBFyi , J6MBFzi , J6MBxi , J6MByi , J6MBzi , J6STAxi , J6STAyi , J6STAzi , J6STVxi , J6STVyi , & - J6STVzi , J6Vxi , J6Vyi , J6Vzi , J7Axi , J7Ayi , J7Azi , J7DynP , J7FAMxi , J7FAMyi , & - J7FAMzi , J7FBFxi , J7FBFyi , J7FBFzi , J7FBxi , J7FByi , J7FBzi , J7FDxi , J7FDyi , J7FDzi , & - J7FIxi , J7FIyi , J7FIzi , J7MBFxi , J7MBFyi , J7MBFzi , J7MBxi , J7MByi , J7MBzi , J7STAxi , & - J7STAyi , J7STAzi , J7STVxi , J7STVyi , J7STVzi , J7Vxi , J7Vyi , J7Vzi , J8Axi , J8Ayi , & - J8Azi , J8DynP , J8FAMxi , J8FAMyi , J8FAMzi , J8FBFxi , J8FBFyi , J8FBFzi , J8FBxi , J8FByi , & - J8FBzi , J8FDxi , J8FDyi , J8FDzi , J8FIxi , J8FIyi , J8FIzi , J8MBFxi , J8MBFyi , J8MBFzi , & - J8MBxi , J8MByi , J8MBzi , J8STAxi , J8STAyi , J8STAzi , J8STVxi , J8STVyi , J8STVzi , J8Vxi , & - J8Vyi , J8Vzi , J9Axi , J9Ayi , J9Azi , J9DynP , J9FAMxi , J9FAMyi , J9FAMzi , J9FBFxi , & - J9FBFyi , J9FBFzi , J9FBxi , J9FByi , J9FBzi , J9FDxi , J9FDyi , J9FDzi , J9FIxi , J9FIyi , & - J9FIzi , J9MBFxi , J9MBFyi , J9MBFzi , J9MBxi , J9MByi , J9MBzi , J9STAxi , J9STAyi , J9STAzi , & - J9STVxi , J9STVyi , J9STVzi , J9Vxi , J9Vyi , J9Vzi , M1N1Axi , M1N1Ayi , M1N1Azi , M1N1DynP , & - M1N1FAFxi , M1N1FAFyi , M1N1FAFzi , M1N1FAGxi , M1N1FAGyi , M1N1FAGzi , M1N1FAMxi , M1N1FAMyi , M1N1FAMzi , M1N1FAxi , & - M1N1FAyi , M1N1FAzi , M1N1FBFxi , M1N1FBFyi , M1N1FBFzi , M1N1FBxi , M1N1FByi , M1N1FBzi , M1N1FDxi , M1N1FDyi , & - M1N1FDzi , M1N1FIxi , M1N1FIyi , M1N1FIzi , M1N1FMGxi , M1N1FMGyi , M1N1FMGzi , M1N1MBFxi , M1N1MBFyi , M1N1MBFzi , & - M1N1MBxi , M1N1MByi , M1N1MBzi , M1N1STAxi , M1N1STAyi , M1N1STAzi , M1N1STVxi , M1N1STVyi , M1N1STVzi , M1N1Vxi , & - M1N1Vyi , M1N1Vzi , M1N2Axi , M1N2Ayi , M1N2Azi , M1N2DynP , M1N2FAFxi , M1N2FAFyi , M1N2FAFzi , M1N2FAGxi , & - M1N2FAGyi , M1N2FAGzi , M1N2FAMxi , M1N2FAMyi , M1N2FAMzi , M1N2FAxi , M1N2FAyi , M1N2FAzi , M1N2FBFxi , M1N2FBFyi , & - M1N2FBFzi , M1N2FBxi , M1N2FByi , M1N2FBzi , M1N2FDxi , M1N2FDyi , M1N2FDzi , M1N2FIxi , M1N2FIyi , M1N2FIzi , & - M1N2FMGxi , M1N2FMGyi , M1N2FMGzi , M1N2MBFxi , M1N2MBFyi , M1N2MBFzi , M1N2MBxi , M1N2MByi , M1N2MBzi , M1N2STAxi , & - M1N2STAyi , M1N2STAzi , M1N2STVxi , M1N2STVyi , M1N2STVzi , M1N2Vxi , M1N2Vyi , M1N2Vzi , M1N3Axi , M1N3Ayi , & - M1N3Azi , M1N3DynP , M1N3FAFxi , M1N3FAFyi , M1N3FAFzi , M1N3FAGxi , M1N3FAGyi , M1N3FAGzi , M1N3FAMxi , M1N3FAMyi , & - M1N3FAMzi , M1N3FAxi , M1N3FAyi , M1N3FAzi , M1N3FBFxi , M1N3FBFyi , M1N3FBFzi , M1N3FBxi , M1N3FByi , M1N3FBzi , & - M1N3FDxi , M1N3FDyi , M1N3FDzi , M1N3FIxi , M1N3FIyi , M1N3FIzi , M1N3FMGxi , M1N3FMGyi , M1N3FMGzi , M1N3MBFxi , & - M1N3MBFyi , M1N3MBFzi , M1N3MBxi , M1N3MByi , M1N3MBzi , M1N3STAxi , M1N3STAyi , M1N3STAzi , M1N3STVxi , M1N3STVyi , & - M1N3STVzi , M1N3Vxi , M1N3Vyi , M1N3Vzi , M1N4Axi , M1N4Ayi , M1N4Azi , M1N4DynP , M1N4FAFxi , M1N4FAFyi , & - M1N4FAFzi , M1N4FAGxi , M1N4FAGyi , M1N4FAGzi , M1N4FAMxi , M1N4FAMyi , M1N4FAMzi , M1N4FAxi , M1N4FAyi , M1N4FAzi , & - M1N4FBFxi , M1N4FBFyi , M1N4FBFzi , M1N4FBxi , M1N4FByi , M1N4FBzi , M1N4FDxi , M1N4FDyi , M1N4FDzi , M1N4FIxi , & - M1N4FIyi , M1N4FIzi , M1N4FMGxi , M1N4FMGyi , M1N4FMGzi , M1N4MBFxi , M1N4MBFyi , M1N4MBFzi , M1N4MBxi , M1N4MByi , & - M1N4MBzi , M1N4STAxi , M1N4STAyi , M1N4STAzi , M1N4STVxi , M1N4STVyi , M1N4STVzi , M1N4Vxi , M1N4Vyi , M1N4Vzi , & - M1N5Axi , M1N5Ayi , M1N5Azi , M1N5DynP , M1N5FAFxi , M1N5FAFyi , M1N5FAFzi , M1N5FAGxi , M1N5FAGyi , M1N5FAGzi , & - M1N5FAMxi , M1N5FAMyi , M1N5FAMzi , M1N5FAxi , M1N5FAyi , M1N5FAzi , M1N5FBFxi , M1N5FBFyi , M1N5FBFzi , M1N5FBxi , & - M1N5FByi , M1N5FBzi , M1N5FDxi , M1N5FDyi , M1N5FDzi , M1N5FIxi , M1N5FIyi , M1N5FIzi , M1N5FMGxi , M1N5FMGyi , & - M1N5FMGzi , M1N5MBFxi , M1N5MBFyi , M1N5MBFzi , M1N5MBxi , M1N5MByi , M1N5MBzi , M1N5STAxi , M1N5STAyi , M1N5STAzi , & - M1N5STVxi , M1N5STVyi , M1N5STVzi , M1N5Vxi , M1N5Vyi , M1N5Vzi , M1N6Axi , M1N6Ayi , M1N6Azi , M1N6DynP , & - M1N6FAFxi , M1N6FAFyi , M1N6FAFzi , M1N6FAGxi , M1N6FAGyi , M1N6FAGzi , M1N6FAMxi , M1N6FAMyi , M1N6FAMzi , M1N6FAxi , & - M1N6FAyi , M1N6FAzi , M1N6FBFxi , M1N6FBFyi , M1N6FBFzi , M1N6FBxi , M1N6FByi , M1N6FBzi , M1N6FDxi , M1N6FDyi , & - M1N6FDzi , M1N6FIxi , M1N6FIyi , M1N6FIzi , M1N6FMGxi , M1N6FMGyi , M1N6FMGzi , M1N6MBFxi , M1N6MBFyi , M1N6MBFzi , & - M1N6MBxi , M1N6MByi , M1N6MBzi , M1N6STAxi , M1N6STAyi , M1N6STAzi , M1N6STVxi , M1N6STVyi , M1N6STVzi , M1N6Vxi , & - M1N6Vyi , M1N6Vzi , M1N7Axi , M1N7Ayi , M1N7Azi , M1N7DynP , M1N7FAFxi , M1N7FAFyi , M1N7FAFzi , M1N7FAGxi , & - M1N7FAGyi , M1N7FAGzi , M1N7FAMxi , M1N7FAMyi , M1N7FAMzi , M1N7FAxi , M1N7FAyi , M1N7FAzi , M1N7FBFxi , M1N7FBFyi , & - M1N7FBFzi , M1N7FBxi , M1N7FByi , M1N7FBzi , M1N7FDxi , M1N7FDyi , M1N7FDzi , M1N7FIxi , M1N7FIyi , M1N7FIzi , & - M1N7FMGxi , M1N7FMGyi , M1N7FMGzi , M1N7MBFxi , M1N7MBFyi , M1N7MBFzi , M1N7MBxi , M1N7MByi , M1N7MBzi , M1N7STAxi , & - M1N7STAyi , M1N7STAzi , M1N7STVxi , M1N7STVyi , M1N7STVzi , M1N7Vxi , M1N7Vyi , M1N7Vzi , M1N8Axi , M1N8Ayi , & - M1N8Azi , M1N8DynP , M1N8FAFxi , M1N8FAFyi , M1N8FAFzi , M1N8FAGxi , M1N8FAGyi , M1N8FAGzi , M1N8FAMxi , M1N8FAMyi , & - M1N8FAMzi , M1N8FAxi , M1N8FAyi , M1N8FAzi , M1N8FBFxi , M1N8FBFyi , M1N8FBFzi , M1N8FBxi , M1N8FByi , M1N8FBzi , & - M1N8FDxi , M1N8FDyi , M1N8FDzi , M1N8FIxi , M1N8FIyi , M1N8FIzi , M1N8FMGxi , M1N8FMGyi , M1N8FMGzi , M1N8MBFxi , & - M1N8MBFyi , M1N8MBFzi , M1N8MBxi , M1N8MByi , M1N8MBzi , M1N8STAxi , M1N8STAyi , M1N8STAzi , M1N8STVxi , M1N8STVyi , & - M1N8STVzi , M1N8Vxi , M1N8Vyi , M1N8Vzi , M1N9Axi , M1N9Ayi , M1N9Azi , M1N9DynP , M1N9FAFxi , M1N9FAFyi , & - M1N9FAFzi , M1N9FAGxi , M1N9FAGyi , M1N9FAGzi , M1N9FAMxi , M1N9FAMyi , M1N9FAMzi , M1N9FAxi , M1N9FAyi , M1N9FAzi , & - M1N9FBFxi , M1N9FBFyi , M1N9FBFzi , M1N9FBxi , M1N9FByi , M1N9FBzi , M1N9FDxi , M1N9FDyi , M1N9FDzi , M1N9FIxi , & - M1N9FIyi , M1N9FIzi , M1N9FMGxi , M1N9FMGyi , M1N9FMGzi , M1N9MBFxi , M1N9MBFyi , M1N9MBFzi , M1N9MBxi , M1N9MByi , & - M1N9MBzi , M1N9STAxi , M1N9STAyi , M1N9STAzi , M1N9STVxi , M1N9STVyi , M1N9STVzi , M1N9Vxi , M1N9Vyi , M1N9Vzi , & - M2N1Axi , M2N1Ayi , M2N1Azi , M2N1DynP , M2N1FAFxi , M2N1FAFyi , M2N1FAFzi , M2N1FAGxi , M2N1FAGyi , M2N1FAGzi , & - M2N1FAMxi , M2N1FAMyi , M2N1FAMzi , M2N1FAxi , M2N1FAyi , M2N1FAzi , M2N1FBFxi , M2N1FBFyi , M2N1FBFzi , M2N1FBxi , & - M2N1FByi , M2N1FBzi , M2N1FDxi , M2N1FDyi , M2N1FDzi , M2N1FIxi , M2N1FIyi , M2N1FIzi , M2N1FMGxi , M2N1FMGyi , & - M2N1FMGzi , M2N1MBFxi , M2N1MBFyi , M2N1MBFzi , M2N1MBxi , M2N1MByi , M2N1MBzi , M2N1STAxi , M2N1STAyi , M2N1STAzi , & - M2N1STVxi , M2N1STVyi , M2N1STVzi , M2N1Vxi , M2N1Vyi , M2N1Vzi , M2N2Axi , M2N2Ayi , M2N2Azi , M2N2DynP , & - M2N2FAFxi , M2N2FAFyi , M2N2FAFzi , M2N2FAGxi , M2N2FAGyi , M2N2FAGzi , M2N2FAMxi , M2N2FAMyi , M2N2FAMzi , M2N2FAxi , & - M2N2FAyi , M2N2FAzi , M2N2FBFxi , M2N2FBFyi , M2N2FBFzi , M2N2FBxi , M2N2FByi , M2N2FBzi , M2N2FDxi , M2N2FDyi , & - M2N2FDzi , M2N2FIxi , M2N2FIyi , M2N2FIzi , M2N2FMGxi , M2N2FMGyi , M2N2FMGzi , M2N2MBFxi , M2N2MBFyi , M2N2MBFzi , & - M2N2MBxi , M2N2MByi , M2N2MBzi , M2N2STAxi , M2N2STAyi , M2N2STAzi , M2N2STVxi , M2N2STVyi , M2N2STVzi , M2N2Vxi , & - M2N2Vyi , M2N2Vzi , M2N3Axi , M2N3Ayi , M2N3Azi , M2N3DynP , M2N3FAFxi , M2N3FAFyi , M2N3FAFzi , M2N3FAGxi , & - M2N3FAGyi , M2N3FAGzi , M2N3FAMxi , M2N3FAMyi , M2N3FAMzi , M2N3FAxi , M2N3FAyi , M2N3FAzi , M2N3FBFxi , M2N3FBFyi , & - M2N3FBFzi , M2N3FBxi , M2N3FByi , M2N3FBzi , M2N3FDxi , M2N3FDyi , M2N3FDzi , M2N3FIxi , M2N3FIyi , M2N3FIzi , & - M2N3FMGxi , M2N3FMGyi , M2N3FMGzi , M2N3MBFxi , M2N3MBFyi , M2N3MBFzi , M2N3MBxi , M2N3MByi , M2N3MBzi , M2N3STAxi , & - M2N3STAyi , M2N3STAzi , M2N3STVxi , M2N3STVyi , M2N3STVzi , M2N3Vxi , M2N3Vyi , M2N3Vzi , M2N4Axi , M2N4Ayi , & - M2N4Azi , M2N4DynP , M2N4FAFxi , M2N4FAFyi , M2N4FAFzi , M2N4FAGxi , M2N4FAGyi , M2N4FAGzi , M2N4FAMxi , M2N4FAMyi , & - M2N4FAMzi , M2N4FAxi , M2N4FAyi , M2N4FAzi , M2N4FBFxi , M2N4FBFyi , M2N4FBFzi , M2N4FBxi , M2N4FByi , M2N4FBzi , & - M2N4FDxi , M2N4FDyi , M2N4FDzi , M2N4FIxi , M2N4FIyi , M2N4FIzi , M2N4FMGxi , M2N4FMGyi , M2N4FMGzi , M2N4MBFxi , & - M2N4MBFyi , M2N4MBFzi , M2N4MBxi , M2N4MByi , M2N4MBzi , M2N4STAxi , M2N4STAyi , M2N4STAzi , M2N4STVxi , M2N4STVyi , & - M2N4STVzi , M2N4Vxi , M2N4Vyi , M2N4Vzi , M2N5Axi , M2N5Ayi , M2N5Azi , M2N5DynP , M2N5FAFxi , M2N5FAFyi , & - M2N5FAFzi , M2N5FAGxi , M2N5FAGyi , M2N5FAGzi , M2N5FAMxi , M2N5FAMyi , M2N5FAMzi , M2N5FAxi , M2N5FAyi , M2N5FAzi , & - M2N5FBFxi , M2N5FBFyi , M2N5FBFzi , M2N5FBxi , M2N5FByi , M2N5FBzi , M2N5FDxi , M2N5FDyi , M2N5FDzi , M2N5FIxi , & - M2N5FIyi , M2N5FIzi , M2N5FMGxi , M2N5FMGyi , M2N5FMGzi , M2N5MBFxi , M2N5MBFyi , M2N5MBFzi , M2N5MBxi , M2N5MByi , & - M2N5MBzi , M2N5STAxi , M2N5STAyi , M2N5STAzi , M2N5STVxi , M2N5STVyi , M2N5STVzi , M2N5Vxi , M2N5Vyi , M2N5Vzi , & - M2N6Axi , M2N6Ayi , M2N6Azi , M2N6DynP , M2N6FAFxi , M2N6FAFyi , M2N6FAFzi , M2N6FAGxi , M2N6FAGyi , M2N6FAGzi , & - M2N6FAMxi , M2N6FAMyi , M2N6FAMzi , M2N6FAxi , M2N6FAyi , M2N6FAzi , M2N6FBFxi , M2N6FBFyi , M2N6FBFzi , M2N6FBxi , & - M2N6FByi , M2N6FBzi , M2N6FDxi , M2N6FDyi , M2N6FDzi , M2N6FIxi , M2N6FIyi , M2N6FIzi , M2N6FMGxi , M2N6FMGyi , & - M2N6FMGzi , M2N6MBFxi , M2N6MBFyi , M2N6MBFzi , M2N6MBxi , M2N6MByi , M2N6MBzi , M2N6STAxi , M2N6STAyi , M2N6STAzi , & - M2N6STVxi , M2N6STVyi , M2N6STVzi , M2N6Vxi , M2N6Vyi , M2N6Vzi , M2N7Axi , M2N7Ayi , M2N7Azi , M2N7DynP , & - M2N7FAFxi , M2N7FAFyi , M2N7FAFzi , M2N7FAGxi , M2N7FAGyi , M2N7FAGzi , M2N7FAMxi , M2N7FAMyi , M2N7FAMzi , M2N7FAxi , & - M2N7FAyi , M2N7FAzi , M2N7FBFxi , M2N7FBFyi , M2N7FBFzi , M2N7FBxi , M2N7FByi , M2N7FBzi , M2N7FDxi , M2N7FDyi , & - M2N7FDzi , M2N7FIxi , M2N7FIyi , M2N7FIzi , M2N7FMGxi , M2N7FMGyi , M2N7FMGzi , M2N7MBFxi , M2N7MBFyi , M2N7MBFzi , & - M2N7MBxi , M2N7MByi , M2N7MBzi , M2N7STAxi , M2N7STAyi , M2N7STAzi , M2N7STVxi , M2N7STVyi , M2N7STVzi , M2N7Vxi , & - M2N7Vyi , M2N7Vzi , M2N8Axi , M2N8Ayi , M2N8Azi , M2N8DynP , M2N8FAFxi , M2N8FAFyi , M2N8FAFzi , M2N8FAGxi , & - M2N8FAGyi , M2N8FAGzi , M2N8FAMxi , M2N8FAMyi , M2N8FAMzi , M2N8FAxi , M2N8FAyi , M2N8FAzi , M2N8FBFxi , M2N8FBFyi , & - M2N8FBFzi , M2N8FBxi , M2N8FByi , M2N8FBzi , M2N8FDxi , M2N8FDyi , M2N8FDzi , M2N8FIxi , M2N8FIyi , M2N8FIzi , & - M2N8FMGxi , M2N8FMGyi , M2N8FMGzi , M2N8MBFxi , M2N8MBFyi , M2N8MBFzi , M2N8MBxi , M2N8MByi , M2N8MBzi , M2N8STAxi , & - M2N8STAyi , M2N8STAzi , M2N8STVxi , M2N8STVyi , M2N8STVzi , M2N8Vxi , M2N8Vyi , M2N8Vzi , M2N9Axi , M2N9Ayi , & - M2N9Azi , M2N9DynP , M2N9FAFxi , M2N9FAFyi , M2N9FAFzi , M2N9FAGxi , M2N9FAGyi , M2N9FAGzi , M2N9FAMxi , M2N9FAMyi , & - M2N9FAMzi , M2N9FAxi , M2N9FAyi , M2N9FAzi , M2N9FBFxi , M2N9FBFyi , M2N9FBFzi , M2N9FBxi , M2N9FByi , M2N9FBzi , & - M2N9FDxi , M2N9FDyi , M2N9FDzi , M2N9FIxi , M2N9FIyi , M2N9FIzi , M2N9FMGxi , M2N9FMGyi , M2N9FMGzi , M2N9MBFxi , & - M2N9MBFyi , M2N9MBFzi , M2N9MBxi , M2N9MByi , M2N9MBzi , M2N9STAxi , M2N9STAyi , M2N9STAzi , M2N9STVxi , M2N9STVyi , & - M2N9STVzi , M2N9Vxi , M2N9Vyi , M2N9Vzi , M3N1Axi , M3N1Ayi , M3N1Azi , M3N1DynP , M3N1FAFxi , M3N1FAFyi , & - M3N1FAFzi , M3N1FAGxi , M3N1FAGyi , M3N1FAGzi , M3N1FAMxi , M3N1FAMyi , M3N1FAMzi , M3N1FAxi , M3N1FAyi , M3N1FAzi , & - M3N1FBFxi , M3N1FBFyi , M3N1FBFzi , M3N1FBxi , M3N1FByi , M3N1FBzi , M3N1FDxi , M3N1FDyi , M3N1FDzi , M3N1FIxi , & - M3N1FIyi , M3N1FIzi , M3N1FMGxi , M3N1FMGyi , M3N1FMGzi , M3N1MBFxi , M3N1MBFyi , M3N1MBFzi , M3N1MBxi , M3N1MByi , & - M3N1MBzi , M3N1STAxi , M3N1STAyi , M3N1STAzi , M3N1STVxi , M3N1STVyi , M3N1STVzi , M3N1Vxi , M3N1Vyi , M3N1Vzi , & - M3N2Axi , M3N2Ayi , M3N2Azi , M3N2DynP , M3N2FAFxi , M3N2FAFyi , M3N2FAFzi , M3N2FAGxi , M3N2FAGyi , M3N2FAGzi , & - M3N2FAMxi , M3N2FAMyi , M3N2FAMzi , M3N2FAxi , M3N2FAyi , M3N2FAzi , M3N2FBFxi , M3N2FBFyi , M3N2FBFzi , M3N2FBxi , & - M3N2FByi , M3N2FBzi , M3N2FDxi , M3N2FDyi , M3N2FDzi , M3N2FIxi , M3N2FIyi , M3N2FIzi , M3N2FMGxi , M3N2FMGyi , & - M3N2FMGzi , M3N2MBFxi , M3N2MBFyi , M3N2MBFzi , M3N2MBxi , M3N2MByi , M3N2MBzi , M3N2STAxi , M3N2STAyi , M3N2STAzi , & - M3N2STVxi , M3N2STVyi , M3N2STVzi , M3N2Vxi , M3N2Vyi , M3N2Vzi , M3N3Axi , M3N3Ayi , M3N3Azi , M3N3DynP , & - M3N3FAFxi , M3N3FAFyi , M3N3FAFzi , M3N3FAGxi , M3N3FAGyi , M3N3FAGzi , M3N3FAMxi , M3N3FAMyi , M3N3FAMzi , M3N3FAxi , & - M3N3FAyi , M3N3FAzi , M3N3FBFxi , M3N3FBFyi , M3N3FBFzi , M3N3FBxi , M3N3FByi , M3N3FBzi , M3N3FDxi , M3N3FDyi , & - M3N3FDzi , M3N3FIxi , M3N3FIyi , M3N3FIzi , M3N3FMGxi , M3N3FMGyi , M3N3FMGzi , M3N3MBFxi , M3N3MBFyi , M3N3MBFzi , & - M3N3MBxi , M3N3MByi , M3N3MBzi , M3N3STAxi , M3N3STAyi , M3N3STAzi , M3N3STVxi , M3N3STVyi , M3N3STVzi , M3N3Vxi , & - M3N3Vyi , M3N3Vzi , M3N4Axi , M3N4Ayi , M3N4Azi , M3N4DynP , M3N4FAFxi , M3N4FAFyi , M3N4FAFzi , M3N4FAGxi , & - M3N4FAGyi , M3N4FAGzi , M3N4FAMxi , M3N4FAMyi , M3N4FAMzi , M3N4FAxi , M3N4FAyi , M3N4FAzi , M3N4FBFxi , M3N4FBFyi , & - M3N4FBFzi , M3N4FBxi , M3N4FByi , M3N4FBzi , M3N4FDxi , M3N4FDyi , M3N4FDzi , M3N4FIxi , M3N4FIyi , M3N4FIzi , & - M3N4FMGxi , M3N4FMGyi , M3N4FMGzi , M3N4MBFxi , M3N4MBFyi , M3N4MBFzi , M3N4MBxi , M3N4MByi , M3N4MBzi , M3N4STAxi , & - M3N4STAyi , M3N4STAzi , M3N4STVxi , M3N4STVyi , M3N4STVzi , M3N4Vxi , M3N4Vyi , M3N4Vzi , M3N5Axi , M3N5Ayi , & - M3N5Azi , M3N5DynP , M3N5FAFxi , M3N5FAFyi , M3N5FAFzi , M3N5FAGxi , M3N5FAGyi , M3N5FAGzi , M3N5FAMxi , M3N5FAMyi , & - M3N5FAMzi , M3N5FAxi , M3N5FAyi , M3N5FAzi , M3N5FBFxi , M3N5FBFyi , M3N5FBFzi , M3N5FBxi , M3N5FByi , M3N5FBzi , & - M3N5FDxi , M3N5FDyi , M3N5FDzi , M3N5FIxi , M3N5FIyi , M3N5FIzi , M3N5FMGxi , M3N5FMGyi , M3N5FMGzi , M3N5MBFxi , & - M3N5MBFyi , M3N5MBFzi , M3N5MBxi , M3N5MByi , M3N5MBzi , M3N5STAxi , M3N5STAyi , M3N5STAzi , M3N5STVxi , M3N5STVyi , & - M3N5STVzi , M3N5Vxi , M3N5Vyi , M3N5Vzi , M3N6Axi , M3N6Ayi , M3N6Azi , M3N6DynP , M3N6FAFxi , M3N6FAFyi , & - M3N6FAFzi , M3N6FAGxi , M3N6FAGyi , M3N6FAGzi , M3N6FAMxi , M3N6FAMyi , M3N6FAMzi , M3N6FAxi , M3N6FAyi , M3N6FAzi , & - M3N6FBFxi , M3N6FBFyi , M3N6FBFzi , M3N6FBxi , M3N6FByi , M3N6FBzi , M3N6FDxi , M3N6FDyi , M3N6FDzi , M3N6FIxi , & - M3N6FIyi , M3N6FIzi , M3N6FMGxi , M3N6FMGyi , M3N6FMGzi , M3N6MBFxi , M3N6MBFyi , M3N6MBFzi , M3N6MBxi , M3N6MByi , & - M3N6MBzi , M3N6STAxi , M3N6STAyi , M3N6STAzi , M3N6STVxi , M3N6STVyi , M3N6STVzi , M3N6Vxi , M3N6Vyi , M3N6Vzi , & - M3N7Axi , M3N7Ayi , M3N7Azi , M3N7DynP , M3N7FAFxi , M3N7FAFyi , M3N7FAFzi , M3N7FAGxi , M3N7FAGyi , M3N7FAGzi , & - M3N7FAMxi , M3N7FAMyi , M3N7FAMzi , M3N7FAxi , M3N7FAyi , M3N7FAzi , M3N7FBFxi , M3N7FBFyi , M3N7FBFzi , M3N7FBxi , & - M3N7FByi , M3N7FBzi , M3N7FDxi , M3N7FDyi , M3N7FDzi , M3N7FIxi , M3N7FIyi , M3N7FIzi , M3N7FMGxi , M3N7FMGyi , & - M3N7FMGzi , M3N7MBFxi , M3N7MBFyi , M3N7MBFzi , M3N7MBxi , M3N7MByi , M3N7MBzi , M3N7STAxi , M3N7STAyi , M3N7STAzi , & - M3N7STVxi , M3N7STVyi , M3N7STVzi , M3N7Vxi , M3N7Vyi , M3N7Vzi , M3N8Axi , M3N8Ayi , M3N8Azi , M3N8DynP , & - M3N8FAFxi , M3N8FAFyi , M3N8FAFzi , M3N8FAGxi , M3N8FAGyi , M3N8FAGzi , M3N8FAMxi , M3N8FAMyi , M3N8FAMzi , M3N8FAxi , & - M3N8FAyi , M3N8FAzi , M3N8FBFxi , M3N8FBFyi , M3N8FBFzi , M3N8FBxi , M3N8FByi , M3N8FBzi , M3N8FDxi , M3N8FDyi , & - M3N8FDzi , M3N8FIxi , M3N8FIyi , M3N8FIzi , M3N8FMGxi , M3N8FMGyi , M3N8FMGzi , M3N8MBFxi , M3N8MBFyi , M3N8MBFzi , & - M3N8MBxi , M3N8MByi , M3N8MBzi , M3N8STAxi , M3N8STAyi , M3N8STAzi , M3N8STVxi , M3N8STVyi , M3N8STVzi , M3N8Vxi , & - M3N8Vyi , M3N8Vzi , M3N9Axi , M3N9Ayi , M3N9Azi , M3N9DynP , M3N9FAFxi , M3N9FAFyi , M3N9FAFzi , M3N9FAGxi , & - M3N9FAGyi , M3N9FAGzi , M3N9FAMxi , M3N9FAMyi , M3N9FAMzi , M3N9FAxi , M3N9FAyi , M3N9FAzi , M3N9FBFxi , M3N9FBFyi , & - M3N9FBFzi , M3N9FBxi , M3N9FByi , M3N9FBzi , M3N9FDxi , M3N9FDyi , M3N9FDzi , M3N9FIxi , M3N9FIyi , M3N9FIzi , & - M3N9FMGxi , M3N9FMGyi , M3N9FMGzi , M3N9MBFxi , M3N9MBFyi , M3N9MBFzi , M3N9MBxi , M3N9MByi , M3N9MBzi , M3N9STAxi , & - M3N9STAyi , M3N9STAzi , M3N9STVxi , M3N9STVyi , M3N9STVzi , M3N9Vxi , M3N9Vyi , M3N9Vzi , M4N1Axi , M4N1Ayi , & - M4N1Azi , M4N1DynP , M4N1FAFxi , M4N1FAFyi , M4N1FAFzi , M4N1FAGxi , M4N1FAGyi , M4N1FAGzi , M4N1FAMxi , M4N1FAMyi , & - M4N1FAMzi , M4N1FAxi , M4N1FAyi , M4N1FAzi , M4N1FBFxi , M4N1FBFyi , M4N1FBFzi , M4N1FBxi , M4N1FByi , M4N1FBzi , & - M4N1FDxi , M4N1FDyi , M4N1FDzi , M4N1FIxi , M4N1FIyi , M4N1FIzi , M4N1FMGxi , M4N1FMGyi , M4N1FMGzi , M4N1MBFxi , & - M4N1MBFyi , M4N1MBFzi , M4N1MBxi , M4N1MByi , M4N1MBzi , M4N1STAxi , M4N1STAyi , M4N1STAzi , M4N1STVxi , M4N1STVyi , & - M4N1STVzi , M4N1Vxi , M4N1Vyi , M4N1Vzi , M4N2Axi , M4N2Ayi , M4N2Azi , M4N2DynP , M4N2FAFxi , M4N2FAFyi , & - M4N2FAFzi , M4N2FAGxi , M4N2FAGyi , M4N2FAGzi , M4N2FAMxi , M4N2FAMyi , M4N2FAMzi , M4N2FAxi , M4N2FAyi , M4N2FAzi , & - M4N2FBFxi , M4N2FBFyi , M4N2FBFzi , M4N2FBxi , M4N2FByi , M4N2FBzi , M4N2FDxi , M4N2FDyi , M4N2FDzi , M4N2FIxi , & - M4N2FIyi , M4N2FIzi , M4N2FMGxi , M4N2FMGyi , M4N2FMGzi , M4N2MBFxi , M4N2MBFyi , M4N2MBFzi , M4N2MBxi , M4N2MByi , & - M4N2MBzi , M4N2STAxi , M4N2STAyi , M4N2STAzi , M4N2STVxi , M4N2STVyi , M4N2STVzi , M4N2Vxi , M4N2Vyi , M4N2Vzi , & - M4N3Axi , M4N3Ayi , M4N3Azi , M4N3DynP , M4N3FAFxi , M4N3FAFyi , M4N3FAFzi , M4N3FAGxi , M4N3FAGyi , M4N3FAGzi , & - M4N3FAMxi , M4N3FAMyi , M4N3FAMzi , M4N3FAxi , M4N3FAyi , M4N3FAzi , M4N3FBFxi , M4N3FBFyi , M4N3FBFzi , M4N3FBxi , & - M4N3FByi , M4N3FBzi , M4N3FDxi , M4N3FDyi , M4N3FDzi , M4N3FIxi , M4N3FIyi , M4N3FIzi , M4N3FMGxi , M4N3FMGyi , & - M4N3FMGzi , M4N3MBFxi , M4N3MBFyi , M4N3MBFzi , M4N3MBxi , M4N3MByi , M4N3MBzi , M4N3STAxi , M4N3STAyi , M4N3STAzi , & - M4N3STVxi , M4N3STVyi , M4N3STVzi , M4N3Vxi , M4N3Vyi , M4N3Vzi , M4N4Axi , M4N4Ayi , M4N4Azi , M4N4DynP , & - M4N4FAFxi , M4N4FAFyi , M4N4FAFzi , M4N4FAGxi , M4N4FAGyi , M4N4FAGzi , M4N4FAMxi , M4N4FAMyi , M4N4FAMzi , M4N4FAxi , & - M4N4FAyi , M4N4FAzi , M4N4FBFxi , M4N4FBFyi , M4N4FBFzi , M4N4FBxi , M4N4FByi , M4N4FBzi , M4N4FDxi , M4N4FDyi , & - M4N4FDzi , M4N4FIxi , M4N4FIyi , M4N4FIzi , M4N4FMGxi , M4N4FMGyi , M4N4FMGzi , M4N4MBFxi , M4N4MBFyi , M4N4MBFzi , & - M4N4MBxi , M4N4MByi , M4N4MBzi , M4N4STAxi , M4N4STAyi , M4N4STAzi , M4N4STVxi , M4N4STVyi , M4N4STVzi , M4N4Vxi , & - M4N4Vyi , M4N4Vzi , M4N5Axi , M4N5Ayi , M4N5Azi , M4N5DynP , M4N5FAFxi , M4N5FAFyi , M4N5FAFzi , M4N5FAGxi , & - M4N5FAGyi , M4N5FAGzi , M4N5FAMxi , M4N5FAMyi , M4N5FAMzi , M4N5FAxi , M4N5FAyi , M4N5FAzi , M4N5FBFxi , M4N5FBFyi , & - M4N5FBFzi , M4N5FBxi , M4N5FByi , M4N5FBzi , M4N5FDxi , M4N5FDyi , M4N5FDzi , M4N5FIxi , M4N5FIyi , M4N5FIzi , & - M4N5FMGxi , M4N5FMGyi , M4N5FMGzi , M4N5MBFxi , M4N5MBFyi , M4N5MBFzi , M4N5MBxi , M4N5MByi , M4N5MBzi , M4N5STAxi , & - M4N5STAyi , M4N5STAzi , M4N5STVxi , M4N5STVyi , M4N5STVzi , M4N5Vxi , M4N5Vyi , M4N5Vzi , M4N6Axi , M4N6Ayi , & - M4N6Azi , M4N6DynP , M4N6FAFxi , M4N6FAFyi , M4N6FAFzi , M4N6FAGxi , M4N6FAGyi , M4N6FAGzi , M4N6FAMxi , M4N6FAMyi , & - M4N6FAMzi , M4N6FAxi , M4N6FAyi , M4N6FAzi , M4N6FBFxi , M4N6FBFyi , M4N6FBFzi , M4N6FBxi , M4N6FByi , M4N6FBzi , & - M4N6FDxi , M4N6FDyi , M4N6FDzi , M4N6FIxi , M4N6FIyi , M4N6FIzi , M4N6FMGxi , M4N6FMGyi , M4N6FMGzi , M4N6MBFxi , & - M4N6MBFyi , M4N6MBFzi , M4N6MBxi , M4N6MByi , M4N6MBzi , M4N6STAxi , M4N6STAyi , M4N6STAzi , M4N6STVxi , M4N6STVyi , & - M4N6STVzi , M4N6Vxi , M4N6Vyi , M4N6Vzi , M4N7Axi , M4N7Ayi , M4N7Azi , M4N7DynP , M4N7FAFxi , M4N7FAFyi , & - M4N7FAFzi , M4N7FAGxi , M4N7FAGyi , M4N7FAGzi , M4N7FAMxi , M4N7FAMyi , M4N7FAMzi , M4N7FAxi , M4N7FAyi , M4N7FAzi , & - M4N7FBFxi , M4N7FBFyi , M4N7FBFzi , M4N7FBxi , M4N7FByi , M4N7FBzi , M4N7FDxi , M4N7FDyi , M4N7FDzi , M4N7FIxi , & - M4N7FIyi , M4N7FIzi , M4N7FMGxi , M4N7FMGyi , M4N7FMGzi , M4N7MBFxi , M4N7MBFyi , M4N7MBFzi , M4N7MBxi , M4N7MByi , & - M4N7MBzi , M4N7STAxi , M4N7STAyi , M4N7STAzi , M4N7STVxi , M4N7STVyi , M4N7STVzi , M4N7Vxi , M4N7Vyi , M4N7Vzi , & - M4N8Axi , M4N8Ayi , M4N8Azi , M4N8DynP , M4N8FAFxi , M4N8FAFyi , M4N8FAFzi , M4N8FAGxi , M4N8FAGyi , M4N8FAGzi , & - M4N8FAMxi , M4N8FAMyi , M4N8FAMzi , M4N8FAxi , M4N8FAyi , M4N8FAzi , M4N8FBFxi , M4N8FBFyi , M4N8FBFzi , M4N8FBxi , & - M4N8FByi , M4N8FBzi , M4N8FDxi , M4N8FDyi , M4N8FDzi , M4N8FIxi , M4N8FIyi , M4N8FIzi , M4N8FMGxi , M4N8FMGyi , & - M4N8FMGzi , M4N8MBFxi , M4N8MBFyi , M4N8MBFzi , M4N8MBxi , M4N8MByi , M4N8MBzi , M4N8STAxi , M4N8STAyi , M4N8STAzi , & - M4N8STVxi , M4N8STVyi , M4N8STVzi , M4N8Vxi , M4N8Vyi , M4N8Vzi , M4N9Axi , M4N9Ayi , M4N9Azi , M4N9DynP , & - M4N9FAFxi , M4N9FAFyi , M4N9FAFzi , M4N9FAGxi , M4N9FAGyi , M4N9FAGzi , M4N9FAMxi , M4N9FAMyi , M4N9FAMzi , M4N9FAxi , & - M4N9FAyi , M4N9FAzi , M4N9FBFxi , M4N9FBFyi , M4N9FBFzi , M4N9FBxi , M4N9FByi , M4N9FBzi , M4N9FDxi , M4N9FDyi , & - M4N9FDzi , M4N9FIxi , M4N9FIyi , M4N9FIzi , M4N9FMGxi , M4N9FMGyi , M4N9FMGzi , M4N9MBFxi , M4N9MBFyi , M4N9MBFzi , & - M4N9MBxi , M4N9MByi , M4N9MBzi , M4N9STAxi , M4N9STAyi , M4N9STAzi , M4N9STVxi , M4N9STVyi , M4N9STVzi , M4N9Vxi , & - M4N9Vyi , M4N9Vzi , M5N1Axi , M5N1Ayi , M5N1Azi , M5N1DynP , M5N1FAFxi , M5N1FAFyi , M5N1FAFzi , M5N1FAGxi , & - M5N1FAGyi , M5N1FAGzi , M5N1FAMxi , M5N1FAMyi , M5N1FAMzi , M5N1FAxi , M5N1FAyi , M5N1FAzi , M5N1FBFxi , M5N1FBFyi , & - M5N1FBFzi , M5N1FBxi , M5N1FByi , M5N1FBzi , M5N1FDxi , M5N1FDyi , M5N1FDzi , M5N1FIxi , M5N1FIyi , M5N1FIzi , & - M5N1FMGxi , M5N1FMGyi , M5N1FMGzi , M5N1MBFxi , M5N1MBFyi , M5N1MBFzi , M5N1MBxi , M5N1MByi , M5N1MBzi , M5N1STAxi , & - M5N1STAyi , M5N1STAzi , M5N1STVxi , M5N1STVyi , M5N1STVzi , M5N1Vxi , M5N1Vyi , M5N1Vzi , M5N2Axi , M5N2Ayi , & - M5N2Azi , M5N2DynP , M5N2FAFxi , M5N2FAFyi , M5N2FAFzi , M5N2FAGxi , M5N2FAGyi , M5N2FAGzi , M5N2FAMxi , M5N2FAMyi , & - M5N2FAMzi , M5N2FAxi , M5N2FAyi , M5N2FAzi , M5N2FBFxi , M5N2FBFyi , M5N2FBFzi , M5N2FBxi , M5N2FByi , M5N2FBzi , & - M5N2FDxi , M5N2FDyi , M5N2FDzi , M5N2FIxi , M5N2FIyi , M5N2FIzi , M5N2FMGxi , M5N2FMGyi , M5N2FMGzi , M5N2MBFxi , & - M5N2MBFyi , M5N2MBFzi , M5N2MBxi , M5N2MByi , M5N2MBzi , M5N2STAxi , M5N2STAyi , M5N2STAzi , M5N2STVxi , M5N2STVyi , & - M5N2STVzi , M5N2Vxi , M5N2Vyi , M5N2Vzi , M5N3Axi , M5N3Ayi , M5N3Azi , M5N3DynP , M5N3FAFxi , M5N3FAFyi , & - M5N3FAFzi , M5N3FAGxi , M5N3FAGyi , M5N3FAGzi , M5N3FAMxi , M5N3FAMyi , M5N3FAMzi , M5N3FAxi , M5N3FAyi , M5N3FAzi , & - M5N3FBFxi , M5N3FBFyi , M5N3FBFzi , M5N3FBxi , M5N3FByi , M5N3FBzi , M5N3FDxi , M5N3FDyi , M5N3FDzi , M5N3FIxi , & - M5N3FIyi , M5N3FIzi , M5N3FMGxi , M5N3FMGyi , M5N3FMGzi , M5N3MBFxi , M5N3MBFyi , M5N3MBFzi , M5N3MBxi , M5N3MByi , & - M5N3MBzi , M5N3STAxi , M5N3STAyi , M5N3STAzi , M5N3STVxi , M5N3STVyi , M5N3STVzi , M5N3Vxi , M5N3Vyi , M5N3Vzi , & - M5N4Axi , M5N4Ayi , M5N4Azi , M5N4DynP , M5N4FAFxi , M5N4FAFyi , M5N4FAFzi , M5N4FAGxi , M5N4FAGyi , M5N4FAGzi , & - M5N4FAMxi , M5N4FAMyi , M5N4FAMzi , M5N4FAxi , M5N4FAyi , M5N4FAzi , M5N4FBFxi , M5N4FBFyi , M5N4FBFzi , M5N4FBxi , & - M5N4FByi , M5N4FBzi , M5N4FDxi , M5N4FDyi , M5N4FDzi , M5N4FIxi , M5N4FIyi , M5N4FIzi , M5N4FMGxi , M5N4FMGyi , & - M5N4FMGzi , M5N4MBFxi , M5N4MBFyi , M5N4MBFzi , M5N4MBxi , M5N4MByi , M5N4MBzi , M5N4STAxi , M5N4STAyi , M5N4STAzi , & - M5N4STVxi , M5N4STVyi , M5N4STVzi , M5N4Vxi , M5N4Vyi , M5N4Vzi , M5N5Axi , M5N5Ayi , M5N5Azi , M5N5DynP , & - M5N5FAFxi , M5N5FAFyi , M5N5FAFzi , M5N5FAGxi , M5N5FAGyi , M5N5FAGzi , M5N5FAMxi , M5N5FAMyi , M5N5FAMzi , M5N5FAxi , & - M5N5FAyi , M5N5FAzi , M5N5FBFxi , M5N5FBFyi , M5N5FBFzi , M5N5FBxi , M5N5FByi , M5N5FBzi , M5N5FDxi , M5N5FDyi , & - M5N5FDzi , M5N5FIxi , M5N5FIyi , M5N5FIzi , M5N5FMGxi , M5N5FMGyi , M5N5FMGzi , M5N5MBFxi , M5N5MBFyi , M5N5MBFzi , & - M5N5MBxi , M5N5MByi , M5N5MBzi , M5N5STAxi , M5N5STAyi , M5N5STAzi , M5N5STVxi , M5N5STVyi , M5N5STVzi , M5N5Vxi , & - M5N5Vyi , M5N5Vzi , M5N6Axi , M5N6Ayi , M5N6Azi , M5N6DynP , M5N6FAFxi , M5N6FAFyi , M5N6FAFzi , M5N6FAGxi , & - M5N6FAGyi , M5N6FAGzi , M5N6FAMxi , M5N6FAMyi , M5N6FAMzi , M5N6FAxi , M5N6FAyi , M5N6FAzi , M5N6FBFxi , M5N6FBFyi , & - M5N6FBFzi , M5N6FBxi , M5N6FByi , M5N6FBzi , M5N6FDxi , M5N6FDyi , M5N6FDzi , M5N6FIxi , M5N6FIyi , M5N6FIzi , & - M5N6FMGxi , M5N6FMGyi , M5N6FMGzi , M5N6MBFxi , M5N6MBFyi , M5N6MBFzi , M5N6MBxi , M5N6MByi , M5N6MBzi , M5N6STAxi , & - M5N6STAyi , M5N6STAzi , M5N6STVxi , M5N6STVyi , M5N6STVzi , M5N6Vxi , M5N6Vyi , M5N6Vzi , M5N7Axi , M5N7Ayi , & - M5N7Azi , M5N7DynP , M5N7FAFxi , M5N7FAFyi , M5N7FAFzi , M5N7FAGxi , M5N7FAGyi , M5N7FAGzi , M5N7FAMxi , M5N7FAMyi , & - M5N7FAMzi , M5N7FAxi , M5N7FAyi , M5N7FAzi , M5N7FBFxi , M5N7FBFyi , M5N7FBFzi , M5N7FBxi , M5N7FByi , M5N7FBzi , & - M5N7FDxi , M5N7FDyi , M5N7FDzi , M5N7FIxi , M5N7FIyi , M5N7FIzi , M5N7FMGxi , M5N7FMGyi , M5N7FMGzi , M5N7MBFxi , & - M5N7MBFyi , M5N7MBFzi , M5N7MBxi , M5N7MByi , M5N7MBzi , M5N7STAxi , M5N7STAyi , M5N7STAzi , M5N7STVxi , M5N7STVyi , & - M5N7STVzi , M5N7Vxi , M5N7Vyi , M5N7Vzi , M5N8Axi , M5N8Ayi , M5N8Azi , M5N8DynP , M5N8FAFxi , M5N8FAFyi , & - M5N8FAFzi , M5N8FAGxi , M5N8FAGyi , M5N8FAGzi , M5N8FAMxi , M5N8FAMyi , M5N8FAMzi , M5N8FAxi , M5N8FAyi , M5N8FAzi , & - M5N8FBFxi , M5N8FBFyi , M5N8FBFzi , M5N8FBxi , M5N8FByi , M5N8FBzi , M5N8FDxi , M5N8FDyi , M5N8FDzi , M5N8FIxi , & - M5N8FIyi , M5N8FIzi , M5N8FMGxi , M5N8FMGyi , M5N8FMGzi , M5N8MBFxi , M5N8MBFyi , M5N8MBFzi , M5N8MBxi , M5N8MByi , & - M5N8MBzi , M5N8STAxi , M5N8STAyi , M5N8STAzi , M5N8STVxi , M5N8STVyi , M5N8STVzi , M5N8Vxi , M5N8Vyi , M5N8Vzi , & - M5N9Axi , M5N9Ayi , M5N9Azi , M5N9DynP , M5N9FAFxi , M5N9FAFyi , M5N9FAFzi , M5N9FAGxi , M5N9FAGyi , M5N9FAGzi , & - M5N9FAMxi , M5N9FAMyi , M5N9FAMzi , M5N9FAxi , M5N9FAyi , M5N9FAzi , M5N9FBFxi , M5N9FBFyi , M5N9FBFzi , M5N9FBxi , & - M5N9FByi , M5N9FBzi , M5N9FDxi , M5N9FDyi , M5N9FDzi , M5N9FIxi , M5N9FIyi , M5N9FIzi , M5N9FMGxi , M5N9FMGyi , & - M5N9FMGzi , M5N9MBFxi , M5N9MBFyi , M5N9MBFzi , M5N9MBxi , M5N9MByi , M5N9MBzi , M5N9STAxi , M5N9STAyi , M5N9STAzi , & - M5N9STVxi , M5N9STVyi , M5N9STVzi , M5N9Vxi , M5N9Vyi , M5N9Vzi , M6N1Axi , M6N1Ayi , M6N1Azi , M6N1DynP , & - M6N1FAFxi , M6N1FAFyi , M6N1FAFzi , M6N1FAGxi , M6N1FAGyi , M6N1FAGzi , M6N1FAMxi , M6N1FAMyi , M6N1FAMzi , M6N1FAxi , & - M6N1FAyi , M6N1FAzi , M6N1FBFxi , M6N1FBFyi , M6N1FBFzi , M6N1FBxi , M6N1FByi , M6N1FBzi , M6N1FDxi , M6N1FDyi , & - M6N1FDzi , M6N1FIxi , M6N1FIyi , M6N1FIzi , M6N1FMGxi , M6N1FMGyi , M6N1FMGzi , M6N1MBFxi , M6N1MBFyi , M6N1MBFzi , & - M6N1MBxi , M6N1MByi , M6N1MBzi , M6N1STAxi , M6N1STAyi , M6N1STAzi , M6N1STVxi , M6N1STVyi , M6N1STVzi , M6N1Vxi , & - M6N1Vyi , M6N1Vzi , M6N2Axi , M6N2Ayi , M6N2Azi , M6N2DynP , M6N2FAFxi , M6N2FAFyi , M6N2FAFzi , M6N2FAGxi , & - M6N2FAGyi , M6N2FAGzi , M6N2FAMxi , M6N2FAMyi , M6N2FAMzi , M6N2FAxi , M6N2FAyi , M6N2FAzi , M6N2FBFxi , M6N2FBFyi , & - M6N2FBFzi , M6N2FBxi , M6N2FByi , M6N2FBzi , M6N2FDxi , M6N2FDyi , M6N2FDzi , M6N2FIxi , M6N2FIyi , M6N2FIzi , & - M6N2FMGxi , M6N2FMGyi , M6N2FMGzi , M6N2MBFxi , M6N2MBFyi , M6N2MBFzi , M6N2MBxi , M6N2MByi , M6N2MBzi , M6N2STAxi , & - M6N2STAyi , M6N2STAzi , M6N2STVxi , M6N2STVyi , M6N2STVzi , M6N2Vxi , M6N2Vyi , M6N2Vzi , M6N3Axi , M6N3Ayi , & - M6N3Azi , M6N3DynP , M6N3FAFxi , M6N3FAFyi , M6N3FAFzi , M6N3FAGxi , M6N3FAGyi , M6N3FAGzi , M6N3FAMxi , M6N3FAMyi , & - M6N3FAMzi , M6N3FAxi , M6N3FAyi , M6N3FAzi , M6N3FBFxi , M6N3FBFyi , M6N3FBFzi , M6N3FBxi , M6N3FByi , M6N3FBzi , & - M6N3FDxi , M6N3FDyi , M6N3FDzi , M6N3FIxi , M6N3FIyi , M6N3FIzi , M6N3FMGxi , M6N3FMGyi , M6N3FMGzi , M6N3MBFxi , & - M6N3MBFyi , M6N3MBFzi , M6N3MBxi , M6N3MByi , M6N3MBzi , M6N3STAxi , M6N3STAyi , M6N3STAzi , M6N3STVxi , M6N3STVyi , & - M6N3STVzi , M6N3Vxi , M6N3Vyi , M6N3Vzi , M6N4Axi , M6N4Ayi , M6N4Azi , M6N4DynP , M6N4FAFxi , M6N4FAFyi , & - M6N4FAFzi , M6N4FAGxi , M6N4FAGyi , M6N4FAGzi , M6N4FAMxi , M6N4FAMyi , M6N4FAMzi , M6N4FAxi , M6N4FAyi , M6N4FAzi , & - M6N4FBFxi , M6N4FBFyi , M6N4FBFzi , M6N4FBxi , M6N4FByi , M6N4FBzi , M6N4FDxi , M6N4FDyi , M6N4FDzi , M6N4FIxi , & - M6N4FIyi , M6N4FIzi , M6N4FMGxi , M6N4FMGyi , M6N4FMGzi , M6N4MBFxi , M6N4MBFyi , M6N4MBFzi , M6N4MBxi , M6N4MByi , & - M6N4MBzi , M6N4STAxi , M6N4STAyi , M6N4STAzi , M6N4STVxi , M6N4STVyi , M6N4STVzi , M6N4Vxi , M6N4Vyi , M6N4Vzi , & - M6N5Axi , M6N5Ayi , M6N5Azi , M6N5DynP , M6N5FAFxi , M6N5FAFyi , M6N5FAFzi , M6N5FAGxi , M6N5FAGyi , M6N5FAGzi , & - M6N5FAMxi , M6N5FAMyi , M6N5FAMzi , M6N5FAxi , M6N5FAyi , M6N5FAzi , M6N5FBFxi , M6N5FBFyi , M6N5FBFzi , M6N5FBxi , & - M6N5FByi , M6N5FBzi , M6N5FDxi , M6N5FDyi , M6N5FDzi , M6N5FIxi , M6N5FIyi , M6N5FIzi , M6N5FMGxi , M6N5FMGyi , & - M6N5FMGzi , M6N5MBFxi , M6N5MBFyi , M6N5MBFzi , M6N5MBxi , M6N5MByi , M6N5MBzi , M6N5STAxi , M6N5STAyi , M6N5STAzi , & - M6N5STVxi , M6N5STVyi , M6N5STVzi , M6N5Vxi , M6N5Vyi , M6N5Vzi , M6N6Axi , M6N6Ayi , M6N6Azi , M6N6DynP , & - M6N6FAFxi , M6N6FAFyi , M6N6FAFzi , M6N6FAGxi , M6N6FAGyi , M6N6FAGzi , M6N6FAMxi , M6N6FAMyi , M6N6FAMzi , M6N6FAxi , & - M6N6FAyi , M6N6FAzi , M6N6FBFxi , M6N6FBFyi , M6N6FBFzi , M6N6FBxi , M6N6FByi , M6N6FBzi , M6N6FDxi , M6N6FDyi , & - M6N6FDzi , M6N6FIxi , M6N6FIyi , M6N6FIzi , M6N6FMGxi , M6N6FMGyi , M6N6FMGzi , M6N6MBFxi , M6N6MBFyi , M6N6MBFzi , & - M6N6MBxi , M6N6MByi , M6N6MBzi , M6N6STAxi , M6N6STAyi , M6N6STAzi , M6N6STVxi , M6N6STVyi , M6N6STVzi , M6N6Vxi , & - M6N6Vyi , M6N6Vzi , M6N7Axi , M6N7Ayi , M6N7Azi , M6N7DynP , M6N7FAFxi , M6N7FAFyi , M6N7FAFzi , M6N7FAGxi , & - M6N7FAGyi , M6N7FAGzi , M6N7FAMxi , M6N7FAMyi , M6N7FAMzi , M6N7FAxi , M6N7FAyi , M6N7FAzi , M6N7FBFxi , M6N7FBFyi , & - M6N7FBFzi , M6N7FBxi , M6N7FByi , M6N7FBzi , M6N7FDxi , M6N7FDyi , M6N7FDzi , M6N7FIxi , M6N7FIyi , M6N7FIzi , & - M6N7FMGxi , M6N7FMGyi , M6N7FMGzi , M6N7MBFxi , M6N7MBFyi , M6N7MBFzi , M6N7MBxi , M6N7MByi , M6N7MBzi , M6N7STAxi , & - M6N7STAyi , M6N7STAzi , M6N7STVxi , M6N7STVyi , M6N7STVzi , M6N7Vxi , M6N7Vyi , M6N7Vzi , M6N8Axi , M6N8Ayi , & - M6N8Azi , M6N8DynP , M6N8FAFxi , M6N8FAFyi , M6N8FAFzi , M6N8FAGxi , M6N8FAGyi , M6N8FAGzi , M6N8FAMxi , M6N8FAMyi , & - M6N8FAMzi , M6N8FAxi , M6N8FAyi , M6N8FAzi , M6N8FBFxi , M6N8FBFyi , M6N8FBFzi , M6N8FBxi , M6N8FByi , M6N8FBzi , & - M6N8FDxi , M6N8FDyi , M6N8FDzi , M6N8FIxi , M6N8FIyi , M6N8FIzi , M6N8FMGxi , M6N8FMGyi , M6N8FMGzi , M6N8MBFxi , & - M6N8MBFyi , M6N8MBFzi , M6N8MBxi , M6N8MByi , M6N8MBzi , M6N8STAxi , M6N8STAyi , M6N8STAzi , M6N8STVxi , M6N8STVyi , & - M6N8STVzi , M6N8Vxi , M6N8Vyi , M6N8Vzi , M6N9Axi , M6N9Ayi , M6N9Azi , M6N9DynP , M6N9FAFxi , M6N9FAFyi , & - M6N9FAFzi , M6N9FAGxi , M6N9FAGyi , M6N9FAGzi , M6N9FAMxi , M6N9FAMyi , M6N9FAMzi , M6N9FAxi , M6N9FAyi , M6N9FAzi , & - M6N9FBFxi , M6N9FBFyi , M6N9FBFzi , M6N9FBxi , M6N9FByi , M6N9FBzi , M6N9FDxi , M6N9FDyi , M6N9FDzi , M6N9FIxi , & - M6N9FIyi , M6N9FIzi , M6N9FMGxi , M6N9FMGyi , M6N9FMGzi , M6N9MBFxi , M6N9MBFyi , M6N9MBFzi , M6N9MBxi , M6N9MByi , & - M6N9MBzi , M6N9STAxi , M6N9STAyi , M6N9STAzi , M6N9STVxi , M6N9STVyi , M6N9STVzi , M6N9Vxi , M6N9Vyi , M6N9Vzi , & - M7N1Axi , M7N1Ayi , M7N1Azi , M7N1DynP , M7N1FAFxi , M7N1FAFyi , M7N1FAFzi , M7N1FAGxi , M7N1FAGyi , M7N1FAGzi , & - M7N1FAMxi , M7N1FAMyi , M7N1FAMzi , M7N1FAxi , M7N1FAyi , M7N1FAzi , M7N1FBFxi , M7N1FBFyi , M7N1FBFzi , M7N1FBxi , & - M7N1FByi , M7N1FBzi , M7N1FDxi , M7N1FDyi , M7N1FDzi , M7N1FIxi , M7N1FIyi , M7N1FIzi , M7N1FMGxi , M7N1FMGyi , & - M7N1FMGzi , M7N1MBFxi , M7N1MBFyi , M7N1MBFzi , M7N1MBxi , M7N1MByi , M7N1MBzi , M7N1STAxi , M7N1STAyi , M7N1STAzi , & - M7N1STVxi , M7N1STVyi , M7N1STVzi , M7N1Vxi , M7N1Vyi , M7N1Vzi , M7N2Axi , M7N2Ayi , M7N2Azi , M7N2DynP , & - M7N2FAFxi , M7N2FAFyi , M7N2FAFzi , M7N2FAGxi , M7N2FAGyi , M7N2FAGzi , M7N2FAMxi , M7N2FAMyi , M7N2FAMzi , M7N2FAxi , & - M7N2FAyi , M7N2FAzi , M7N2FBFxi , M7N2FBFyi , M7N2FBFzi , M7N2FBxi , M7N2FByi , M7N2FBzi , M7N2FDxi , M7N2FDyi , & - M7N2FDzi , M7N2FIxi , M7N2FIyi , M7N2FIzi , M7N2FMGxi , M7N2FMGyi , M7N2FMGzi , M7N2MBFxi , M7N2MBFyi , M7N2MBFzi , & - M7N2MBxi , M7N2MByi , M7N2MBzi , M7N2STAxi , M7N2STAyi , M7N2STAzi , M7N2STVxi , M7N2STVyi , M7N2STVzi , M7N2Vxi , & - M7N2Vyi , M7N2Vzi , M7N3Axi , M7N3Ayi , M7N3Azi , M7N3DynP , M7N3FAFxi , M7N3FAFyi , M7N3FAFzi , M7N3FAGxi , & - M7N3FAGyi , M7N3FAGzi , M7N3FAMxi , M7N3FAMyi , M7N3FAMzi , M7N3FAxi , M7N3FAyi , M7N3FAzi , M7N3FBFxi , M7N3FBFyi , & - M7N3FBFzi , M7N3FBxi , M7N3FByi , M7N3FBzi , M7N3FDxi , M7N3FDyi , M7N3FDzi , M7N3FIxi , M7N3FIyi , M7N3FIzi , & - M7N3FMGxi , M7N3FMGyi , M7N3FMGzi , M7N3MBFxi , M7N3MBFyi , M7N3MBFzi , M7N3MBxi , M7N3MByi , M7N3MBzi , M7N3STAxi , & - M7N3STAyi , M7N3STAzi , M7N3STVxi , M7N3STVyi , M7N3STVzi , M7N3Vxi , M7N3Vyi , M7N3Vzi , M7N4Axi , M7N4Ayi , & - M7N4Azi , M7N4DynP , M7N4FAFxi , M7N4FAFyi , M7N4FAFzi , M7N4FAGxi , M7N4FAGyi , M7N4FAGzi , M7N4FAMxi , M7N4FAMyi , & - M7N4FAMzi , M7N4FAxi , M7N4FAyi , M7N4FAzi , M7N4FBFxi , M7N4FBFyi , M7N4FBFzi , M7N4FBxi , M7N4FByi , M7N4FBzi , & - M7N4FDxi , M7N4FDyi , M7N4FDzi , M7N4FIxi , M7N4FIyi , M7N4FIzi , M7N4FMGxi , M7N4FMGyi , M7N4FMGzi , M7N4MBFxi , & - M7N4MBFyi , M7N4MBFzi , M7N4MBxi , M7N4MByi , M7N4MBzi , M7N4STAxi , M7N4STAyi , M7N4STAzi , M7N4STVxi , M7N4STVyi , & - M7N4STVzi , M7N4Vxi , M7N4Vyi , M7N4Vzi , M7N5Axi , M7N5Ayi , M7N5Azi , M7N5DynP , M7N5FAFxi , M7N5FAFyi , & - M7N5FAFzi , M7N5FAGxi , M7N5FAGyi , M7N5FAGzi , M7N5FAMxi , M7N5FAMyi , M7N5FAMzi , M7N5FAxi , M7N5FAyi , M7N5FAzi , & - M7N5FBFxi , M7N5FBFyi , M7N5FBFzi , M7N5FBxi , M7N5FByi , M7N5FBzi , M7N5FDxi , M7N5FDyi , M7N5FDzi , M7N5FIxi , & - M7N5FIyi , M7N5FIzi , M7N5FMGxi , M7N5FMGyi , M7N5FMGzi , M7N5MBFxi , M7N5MBFyi , M7N5MBFzi , M7N5MBxi , M7N5MByi , & - M7N5MBzi , M7N5STAxi , M7N5STAyi , M7N5STAzi , M7N5STVxi , M7N5STVyi , M7N5STVzi , M7N5Vxi , M7N5Vyi , M7N5Vzi , & - M7N6Axi , M7N6Ayi , M7N6Azi , M7N6DynP , M7N6FAFxi , M7N6FAFyi , M7N6FAFzi , M7N6FAGxi , M7N6FAGyi , M7N6FAGzi , & - M7N6FAMxi , M7N6FAMyi , M7N6FAMzi , M7N6FAxi , M7N6FAyi , M7N6FAzi , M7N6FBFxi , M7N6FBFyi , M7N6FBFzi , M7N6FBxi , & - M7N6FByi , M7N6FBzi , M7N6FDxi , M7N6FDyi , M7N6FDzi , M7N6FIxi , M7N6FIyi , M7N6FIzi , M7N6FMGxi , M7N6FMGyi , & - M7N6FMGzi , M7N6MBFxi , M7N6MBFyi , M7N6MBFzi , M7N6MBxi , M7N6MByi , M7N6MBzi , M7N6STAxi , M7N6STAyi , M7N6STAzi , & - M7N6STVxi , M7N6STVyi , M7N6STVzi , M7N6Vxi , M7N6Vyi , M7N6Vzi , M7N7Axi , M7N7Ayi , M7N7Azi , M7N7DynP , & - M7N7FAFxi , M7N7FAFyi , M7N7FAFzi , M7N7FAGxi , M7N7FAGyi , M7N7FAGzi , M7N7FAMxi , M7N7FAMyi , M7N7FAMzi , M7N7FAxi , & - M7N7FAyi , M7N7FAzi , M7N7FBFxi , M7N7FBFyi , M7N7FBFzi , M7N7FBxi , M7N7FByi , M7N7FBzi , M7N7FDxi , M7N7FDyi , & - M7N7FDzi , M7N7FIxi , M7N7FIyi , M7N7FIzi , M7N7FMGxi , M7N7FMGyi , M7N7FMGzi , M7N7MBFxi , M7N7MBFyi , M7N7MBFzi , & - M7N7MBxi , M7N7MByi , M7N7MBzi , M7N7STAxi , M7N7STAyi , M7N7STAzi , M7N7STVxi , M7N7STVyi , M7N7STVzi , M7N7Vxi , & - M7N7Vyi , M7N7Vzi , M7N8Axi , M7N8Ayi , M7N8Azi , M7N8DynP , M7N8FAFxi , M7N8FAFyi , M7N8FAFzi , M7N8FAGxi , & - M7N8FAGyi , M7N8FAGzi , M7N8FAMxi , M7N8FAMyi , M7N8FAMzi , M7N8FAxi , M7N8FAyi , M7N8FAzi , M7N8FBFxi , M7N8FBFyi , & - M7N8FBFzi , M7N8FBxi , M7N8FByi , M7N8FBzi , M7N8FDxi , M7N8FDyi , M7N8FDzi , M7N8FIxi , M7N8FIyi , M7N8FIzi , & - M7N8FMGxi , M7N8FMGyi , M7N8FMGzi , M7N8MBFxi , M7N8MBFyi , M7N8MBFzi , M7N8MBxi , M7N8MByi , M7N8MBzi , M7N8STAxi , & - M7N8STAyi , M7N8STAzi , M7N8STVxi , M7N8STVyi , M7N8STVzi , M7N8Vxi , M7N8Vyi , M7N8Vzi , M7N9Axi , M7N9Ayi , & - M7N9Azi , M7N9DynP , M7N9FAFxi , M7N9FAFyi , M7N9FAFzi , M7N9FAGxi , M7N9FAGyi , M7N9FAGzi , M7N9FAMxi , M7N9FAMyi , & - M7N9FAMzi , M7N9FAxi , M7N9FAyi , M7N9FAzi , M7N9FBFxi , M7N9FBFyi , M7N9FBFzi , M7N9FBxi , M7N9FByi , M7N9FBzi , & - M7N9FDxi , M7N9FDyi , M7N9FDzi , M7N9FIxi , M7N9FIyi , M7N9FIzi , M7N9FMGxi , M7N9FMGyi , M7N9FMGzi , M7N9MBFxi , & - M7N9MBFyi , M7N9MBFzi , M7N9MBxi , M7N9MByi , M7N9MBzi , M7N9STAxi , M7N9STAyi , M7N9STAzi , M7N9STVxi , M7N9STVyi , & - M7N9STVzi , M7N9Vxi , M7N9Vyi , M7N9Vzi , M8N1Axi , M8N1Ayi , M8N1Azi , M8N1DynP , M8N1FAFxi , M8N1FAFyi , & - M8N1FAFzi , M8N1FAGxi , M8N1FAGyi , M8N1FAGzi , M8N1FAMxi , M8N1FAMyi , M8N1FAMzi , M8N1FAxi , M8N1FAyi , M8N1FAzi , & - M8N1FBFxi , M8N1FBFyi , M8N1FBFzi , M8N1FBxi , M8N1FByi , M8N1FBzi , M8N1FDxi , M8N1FDyi , M8N1FDzi , M8N1FIxi , & - M8N1FIyi , M8N1FIzi , M8N1FMGxi , M8N1FMGyi , M8N1FMGzi , M8N1MBFxi , M8N1MBFyi , M8N1MBFzi , M8N1MBxi , M8N1MByi , & - M8N1MBzi , M8N1STAxi , M8N1STAyi , M8N1STAzi , M8N1STVxi , M8N1STVyi , M8N1STVzi , M8N1Vxi , M8N1Vyi , M8N1Vzi , & - M8N2Axi , M8N2Ayi , M8N2Azi , M8N2DynP , M8N2FAFxi , M8N2FAFyi , M8N2FAFzi , M8N2FAGxi , M8N2FAGyi , M8N2FAGzi , & - M8N2FAMxi , M8N2FAMyi , M8N2FAMzi , M8N2FAxi , M8N2FAyi , M8N2FAzi , M8N2FBFxi , M8N2FBFyi , M8N2FBFzi , M8N2FBxi , & - M8N2FByi , M8N2FBzi , M8N2FDxi , M8N2FDyi , M8N2FDzi , M8N2FIxi , M8N2FIyi , M8N2FIzi , M8N2FMGxi , M8N2FMGyi , & - M8N2FMGzi , M8N2MBFxi , M8N2MBFyi , M8N2MBFzi , M8N2MBxi , M8N2MByi , M8N2MBzi , M8N2STAxi , M8N2STAyi , M8N2STAzi , & - M8N2STVxi , M8N2STVyi , M8N2STVzi , M8N2Vxi , M8N2Vyi , M8N2Vzi , M8N3Axi , M8N3Ayi , M8N3Azi , M8N3DynP , & - M8N3FAFxi , M8N3FAFyi , M8N3FAFzi , M8N3FAGxi , M8N3FAGyi , M8N3FAGzi , M8N3FAMxi , M8N3FAMyi , M8N3FAMzi , M8N3FAxi , & - M8N3FAyi , M8N3FAzi , M8N3FBFxi , M8N3FBFyi , M8N3FBFzi , M8N3FBxi , M8N3FByi , M8N3FBzi , M8N3FDxi , M8N3FDyi , & - M8N3FDzi , M8N3FIxi , M8N3FIyi , M8N3FIzi , M8N3FMGxi , M8N3FMGyi , M8N3FMGzi , M8N3MBFxi , M8N3MBFyi , M8N3MBFzi , & - M8N3MBxi , M8N3MByi , M8N3MBzi , M8N3STAxi , M8N3STAyi , M8N3STAzi , M8N3STVxi , M8N3STVyi , M8N3STVzi , M8N3Vxi , & - M8N3Vyi , M8N3Vzi , M8N4Axi , M8N4Ayi , M8N4Azi , M8N4DynP , M8N4FAFxi , M8N4FAFyi , M8N4FAFzi , M8N4FAGxi , & - M8N4FAGyi , M8N4FAGzi , M8N4FAMxi , M8N4FAMyi , M8N4FAMzi , M8N4FAxi , M8N4FAyi , M8N4FAzi , M8N4FBFxi , M8N4FBFyi , & - M8N4FBFzi , M8N4FBxi , M8N4FByi , M8N4FBzi , M8N4FDxi , M8N4FDyi , M8N4FDzi , M8N4FIxi , M8N4FIyi , M8N4FIzi , & - M8N4FMGxi , M8N4FMGyi , M8N4FMGzi , M8N4MBFxi , M8N4MBFyi , M8N4MBFzi , M8N4MBxi , M8N4MByi , M8N4MBzi , M8N4STAxi , & - M8N4STAyi , M8N4STAzi , M8N4STVxi , M8N4STVyi , M8N4STVzi , M8N4Vxi , M8N4Vyi , M8N4Vzi , M8N5Axi , M8N5Ayi , & - M8N5Azi , M8N5DynP , M8N5FAFxi , M8N5FAFyi , M8N5FAFzi , M8N5FAGxi , M8N5FAGyi , M8N5FAGzi , M8N5FAMxi , M8N5FAMyi , & - M8N5FAMzi , M8N5FAxi , M8N5FAyi , M8N5FAzi , M8N5FBFxi , M8N5FBFyi , M8N5FBFzi , M8N5FBxi , M8N5FByi , M8N5FBzi , & - M8N5FDxi , M8N5FDyi , M8N5FDzi , M8N5FIxi , M8N5FIyi , M8N5FIzi , M8N5FMGxi , M8N5FMGyi , M8N5FMGzi , M8N5MBFxi , & - M8N5MBFyi , M8N5MBFzi , M8N5MBxi , M8N5MByi , M8N5MBzi , M8N5STAxi , M8N5STAyi , M8N5STAzi , M8N5STVxi , M8N5STVyi , & - M8N5STVzi , M8N5Vxi , M8N5Vyi , M8N5Vzi , M8N6Axi , M8N6Ayi , M8N6Azi , M8N6DynP , M8N6FAFxi , M8N6FAFyi , & - M8N6FAFzi , M8N6FAGxi , M8N6FAGyi , M8N6FAGzi , M8N6FAMxi , M8N6FAMyi , M8N6FAMzi , M8N6FAxi , M8N6FAyi , M8N6FAzi , & - M8N6FBFxi , M8N6FBFyi , M8N6FBFzi , M8N6FBxi , M8N6FByi , M8N6FBzi , M8N6FDxi , M8N6FDyi , M8N6FDzi , M8N6FIxi , & - M8N6FIyi , M8N6FIzi , M8N6FMGxi , M8N6FMGyi , M8N6FMGzi , M8N6MBFxi , M8N6MBFyi , M8N6MBFzi , M8N6MBxi , M8N6MByi , & - M8N6MBzi , M8N6STAxi , M8N6STAyi , M8N6STAzi , M8N6STVxi , M8N6STVyi , M8N6STVzi , M8N6Vxi , M8N6Vyi , M8N6Vzi , & - M8N7Axi , M8N7Ayi , M8N7Azi , M8N7DynP , M8N7FAFxi , M8N7FAFyi , M8N7FAFzi , M8N7FAGxi , M8N7FAGyi , M8N7FAGzi , & - M8N7FAMxi , M8N7FAMyi , M8N7FAMzi , M8N7FAxi , M8N7FAyi , M8N7FAzi , M8N7FBFxi , M8N7FBFyi , M8N7FBFzi , M8N7FBxi , & - M8N7FByi , M8N7FBzi , M8N7FDxi , M8N7FDyi , M8N7FDzi , M8N7FIxi , M8N7FIyi , M8N7FIzi , M8N7FMGxi , M8N7FMGyi , & - M8N7FMGzi , M8N7MBFxi , M8N7MBFyi , M8N7MBFzi , M8N7MBxi , M8N7MByi , M8N7MBzi , M8N7STAxi , M8N7STAyi , M8N7STAzi , & - M8N7STVxi , M8N7STVyi , M8N7STVzi , M8N7Vxi , M8N7Vyi , M8N7Vzi , M8N8Axi , M8N8Ayi , M8N8Azi , M8N8DynP , & - M8N8FAFxi , M8N8FAFyi , M8N8FAFzi , M8N8FAGxi , M8N8FAGyi , M8N8FAGzi , M8N8FAMxi , M8N8FAMyi , M8N8FAMzi , M8N8FAxi , & - M8N8FAyi , M8N8FAzi , M8N8FBFxi , M8N8FBFyi , M8N8FBFzi , M8N8FBxi , M8N8FByi , M8N8FBzi , M8N8FDxi , M8N8FDyi , & - M8N8FDzi , M8N8FIxi , M8N8FIyi , M8N8FIzi , M8N8FMGxi , M8N8FMGyi , M8N8FMGzi , M8N8MBFxi , M8N8MBFyi , M8N8MBFzi , & - M8N8MBxi , M8N8MByi , M8N8MBzi , M8N8STAxi , M8N8STAyi , M8N8STAzi , M8N8STVxi , M8N8STVyi , M8N8STVzi , M8N8Vxi , & - M8N8Vyi , M8N8Vzi , M8N9Axi , M8N9Ayi , M8N9Azi , M8N9DynP , M8N9FAFxi , M8N9FAFyi , M8N9FAFzi , M8N9FAGxi , & - M8N9FAGyi , M8N9FAGzi , M8N9FAMxi , M8N9FAMyi , M8N9FAMzi , M8N9FAxi , M8N9FAyi , M8N9FAzi , M8N9FBFxi , M8N9FBFyi , & - M8N9FBFzi , M8N9FBxi , M8N9FByi , M8N9FBzi , M8N9FDxi , M8N9FDyi , M8N9FDzi , M8N9FIxi , M8N9FIyi , M8N9FIzi , & - M8N9FMGxi , M8N9FMGyi , M8N9FMGzi , M8N9MBFxi , M8N9MBFyi , M8N9MBFzi , M8N9MBxi , M8N9MByi , M8N9MBzi , M8N9STAxi , & - M8N9STAyi , M8N9STAzi , M8N9STVxi , M8N9STVyi , M8N9STVzi , M8N9Vxi , M8N9Vyi , M8N9Vzi , M9N1Axi , M9N1Ayi , & - M9N1Azi , M9N1DynP , M9N1FAFxi , M9N1FAFyi , M9N1FAFzi , M9N1FAGxi , M9N1FAGyi , M9N1FAGzi , M9N1FAMxi , M9N1FAMyi , & - M9N1FAMzi , M9N1FAxi , M9N1FAyi , M9N1FAzi , M9N1FBFxi , M9N1FBFyi , M9N1FBFzi , M9N1FBxi , M9N1FByi , M9N1FBzi , & - M9N1FDxi , M9N1FDyi , M9N1FDzi , M9N1FIxi , M9N1FIyi , M9N1FIzi , M9N1FMGxi , M9N1FMGyi , M9N1FMGzi , M9N1MBFxi , & - M9N1MBFyi , M9N1MBFzi , M9N1MBxi , M9N1MByi , M9N1MBzi , M9N1STAxi , M9N1STAyi , M9N1STAzi , M9N1STVxi , M9N1STVyi , & - M9N1STVzi , M9N1Vxi , M9N1Vyi , M9N1Vzi , M9N2Axi , M9N2Ayi , M9N2Azi , M9N2DynP , M9N2FAFxi , M9N2FAFyi , & - M9N2FAFzi , M9N2FAGxi , M9N2FAGyi , M9N2FAGzi , M9N2FAMxi , M9N2FAMyi , M9N2FAMzi , M9N2FAxi , M9N2FAyi , M9N2FAzi , & - M9N2FBFxi , M9N2FBFyi , M9N2FBFzi , M9N2FBxi , M9N2FByi , M9N2FBzi , M9N2FDxi , M9N2FDyi , M9N2FDzi , M9N2FIxi , & - M9N2FIyi , M9N2FIzi , M9N2FMGxi , M9N2FMGyi , M9N2FMGzi , M9N2MBFxi , M9N2MBFyi , M9N2MBFzi , M9N2MBxi , M9N2MByi , & - M9N2MBzi , M9N2STAxi , M9N2STAyi , M9N2STAzi , M9N2STVxi , M9N2STVyi , M9N2STVzi , M9N2Vxi , M9N2Vyi , M9N2Vzi , & - M9N3Axi , M9N3Ayi , M9N3Azi , M9N3DynP , M9N3FAFxi , M9N3FAFyi , M9N3FAFzi , M9N3FAGxi , M9N3FAGyi , M9N3FAGzi , & - M9N3FAMxi , M9N3FAMyi , M9N3FAMzi , M9N3FAxi , M9N3FAyi , M9N3FAzi , M9N3FBFxi , M9N3FBFyi , M9N3FBFzi , M9N3FBxi , & - M9N3FByi , M9N3FBzi , M9N3FDxi , M9N3FDyi , M9N3FDzi , M9N3FIxi , M9N3FIyi , M9N3FIzi , M9N3FMGxi , M9N3FMGyi , & - M9N3FMGzi , M9N3MBFxi , M9N3MBFyi , M9N3MBFzi , M9N3MBxi , M9N3MByi , M9N3MBzi , M9N3STAxi , M9N3STAyi , M9N3STAzi , & - M9N3STVxi , M9N3STVyi , M9N3STVzi , M9N3Vxi , M9N3Vyi , M9N3Vzi , M9N4Axi , M9N4Ayi , M9N4Azi , M9N4DynP , & - M9N4FAFxi , M9N4FAFyi , M9N4FAFzi , M9N4FAGxi , M9N4FAGyi , M9N4FAGzi , M9N4FAMxi , M9N4FAMyi , M9N4FAMzi , M9N4FAxi , & - M9N4FAyi , M9N4FAzi , M9N4FBFxi , M9N4FBFyi , M9N4FBFzi , M9N4FBxi , M9N4FByi , M9N4FBzi , M9N4FDxi , M9N4FDyi , & - M9N4FDzi , M9N4FIxi , M9N4FIyi , M9N4FIzi , M9N4FMGxi , M9N4FMGyi , M9N4FMGzi , M9N4MBFxi , M9N4MBFyi , M9N4MBFzi , & - M9N4MBxi , M9N4MByi , M9N4MBzi , M9N4STAxi , M9N4STAyi , M9N4STAzi , M9N4STVxi , M9N4STVyi , M9N4STVzi , M9N4Vxi , & - M9N4Vyi , M9N4Vzi , M9N5Axi , M9N5Ayi , M9N5Azi , M9N5DynP , M9N5FAFxi , M9N5FAFyi , M9N5FAFzi , M9N5FAGxi , & - M9N5FAGyi , M9N5FAGzi , M9N5FAMxi , M9N5FAMyi , M9N5FAMzi , M9N5FAxi , M9N5FAyi , M9N5FAzi , M9N5FBFxi , M9N5FBFyi , & - M9N5FBFzi , M9N5FBxi , M9N5FByi , M9N5FBzi , M9N5FDxi , M9N5FDyi , M9N5FDzi , M9N5FIxi , M9N5FIyi , M9N5FIzi , & - M9N5FMGxi , M9N5FMGyi , M9N5FMGzi , M9N5MBFxi , M9N5MBFyi , M9N5MBFzi , M9N5MBxi , M9N5MByi , M9N5MBzi , M9N5STAxi , & - M9N5STAyi , M9N5STAzi , M9N5STVxi , M9N5STVyi , M9N5STVzi , M9N5Vxi , M9N5Vyi , M9N5Vzi , M9N6Axi , M9N6Ayi , & - M9N6Azi , M9N6DynP , M9N6FAFxi , M9N6FAFyi , M9N6FAFzi , M9N6FAGxi , M9N6FAGyi , M9N6FAGzi , M9N6FAMxi , M9N6FAMyi , & - M9N6FAMzi , M9N6FAxi , M9N6FAyi , M9N6FAzi , M9N6FBFxi , M9N6FBFyi , M9N6FBFzi , M9N6FBxi , M9N6FByi , M9N6FBzi , & - M9N6FDxi , M9N6FDyi , M9N6FDzi , M9N6FIxi , M9N6FIyi , M9N6FIzi , M9N6FMGxi , M9N6FMGyi , M9N6FMGzi , M9N6MBFxi , & - M9N6MBFyi , M9N6MBFzi , M9N6MBxi , M9N6MByi , M9N6MBzi , M9N6STAxi , M9N6STAyi , M9N6STAzi , M9N6STVxi , M9N6STVyi , & - M9N6STVzi , M9N6Vxi , M9N6Vyi , M9N6Vzi , M9N7Axi , M9N7Ayi , M9N7Azi , M9N7DynP , M9N7FAFxi , M9N7FAFyi , & - M9N7FAFzi , M9N7FAGxi , M9N7FAGyi , M9N7FAGzi , M9N7FAMxi , M9N7FAMyi , M9N7FAMzi , M9N7FAxi , M9N7FAyi , M9N7FAzi , & - M9N7FBFxi , M9N7FBFyi , M9N7FBFzi , M9N7FBxi , M9N7FByi , M9N7FBzi , M9N7FDxi , M9N7FDyi , M9N7FDzi , M9N7FIxi , & - M9N7FIyi , M9N7FIzi , M9N7FMGxi , M9N7FMGyi , M9N7FMGzi , M9N7MBFxi , M9N7MBFyi , M9N7MBFzi , M9N7MBxi , M9N7MByi , & - M9N7MBzi , M9N7STAxi , M9N7STAyi , M9N7STAzi , M9N7STVxi , M9N7STVyi , M9N7STVzi , M9N7Vxi , M9N7Vyi , M9N7Vzi , & - M9N8Axi , M9N8Ayi , M9N8Azi , M9N8DynP , M9N8FAFxi , M9N8FAFyi , M9N8FAFzi , M9N8FAGxi , M9N8FAGyi , M9N8FAGzi , & - M9N8FAMxi , M9N8FAMyi , M9N8FAMzi , M9N8FAxi , M9N8FAyi , M9N8FAzi , M9N8FBFxi , M9N8FBFyi , M9N8FBFzi , M9N8FBxi , & - M9N8FByi , M9N8FBzi , M9N8FDxi , M9N8FDyi , M9N8FDzi , M9N8FIxi , M9N8FIyi , M9N8FIzi , M9N8FMGxi , M9N8FMGyi , & - M9N8FMGzi , M9N8MBFxi , M9N8MBFyi , M9N8MBFzi , M9N8MBxi , M9N8MByi , M9N8MBzi , M9N8STAxi , M9N8STAyi , M9N8STAzi , & - M9N8STVxi , M9N8STVyi , M9N8STVzi , M9N8Vxi , M9N8Vyi , M9N8Vzi , M9N9Axi , M9N9Ayi , M9N9Azi , M9N9DynP , & - M9N9FAFxi , M9N9FAFyi , M9N9FAFzi , M9N9FAGxi , M9N9FAGyi , M9N9FAGzi , M9N9FAMxi , M9N9FAMyi , M9N9FAMzi , M9N9FAxi , & - M9N9FAyi , M9N9FAzi , M9N9FBFxi , M9N9FBFyi , M9N9FBFzi , M9N9FBxi , M9N9FByi , M9N9FBzi , M9N9FDxi , M9N9FDyi , & - M9N9FDzi , M9N9FIxi , M9N9FIyi , M9N9FIzi , M9N9FMGxi , M9N9FMGyi , M9N9FMGzi , M9N9MBFxi , M9N9MBFyi , M9N9MBFzi , & - M9N9MBxi , M9N9MByi , M9N9MBzi , M9N9STAxi , M9N9STAyi , M9N9STAzi , M9N9STVxi , M9N9STVyi , M9N9STVzi , M9N9Vxi , & - M9N9Vyi , M9N9Vzi /) - CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(4032) = (/ & ! This lists the units corresponding to the allowed parameters - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ", & - "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & - "(N-m) ","(N-m) ","(N-m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & - "(N-m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ", & - "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & - "(N-m) ","(N-m) ","(N-m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) "/) - + CHARACTER(OutStrLenM1) :: ValidParamAry(4599) ! This lists the names of the allowed parameters, which must be sorted alphabetically + INTEGER(IntKi) :: ParamIndxAry(4599) ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + CHARACTER(OutStrLenM1) :: ParamUnitsAry(4599) ! This lists the names of the allowed parameters, which must be sorted alphabetically + ! ..... Public Subroutines ................................................................................................... PUBLIC :: MrsnOut_MapOutputs @@ -6896,8 +6441,10 @@ SUBROUTINE MrsnOut_MapOutputs( CurrentTime, y, p, u, m, AllOuts, ErrStat, ErrMsg INTEGER :: I, J - INTEGER :: m1, m2 ! Indices of the markers which surround the requested output location - REAL(ReKi) :: s ! The linear interpolation factor for the requested location + INTEGER :: im, m1, m2, im1, im2 ! Indices of the markers which surround the requested output location + real(ReKi) :: mult1, mult2 ! Load multiplier for joint nodes vs interior nodes + real(ReKi) :: dl ! member element length (m) + REAL(ReKi) :: s ! The linear interpolation factor for the requested location ErrStat = ErrID_None @@ -6906,98 +6453,121 @@ SUBROUTINE MrsnOut_MapOutputs( CurrentTime, y, p, u, m, AllOuts, ErrStat, ErrMsg ! Only generate member-based outputs for the number of user-requested member outputs IF ( p%NumOuts > 0 ) THEN - DO J=1,p%NMOutputs + DO J=1,p%NMOutputs + im = p%MOutLst(J)%MemberIDIndx DO I=1,p%MOutLst(J)%NOutLoc - ! These indices are in the DistribMesh index system, not the overall nodes index system, so distribToNodeIndx() mapping needs to be performed if you want to index into the nodes array or wave kinematics arrays - ! But, all of the D_* arrays are already using the DistribMesh index system, so we are OK for those - - m1 = p%MOutLst(J)%Marker1(I) - m2 = p%MOutLst(J)%Marker2(I) + + m1 = p%MOutLst(J)%MeshIndx1(I) + m2 = p%MOutLst(J)%MeshIndx2(I) + im1 = p%MOutLst(J)%MemberIndx1(I) + im2 = p%MOutLst(J)%MemberIndx2(I) s = p%MOutLst(J)%s (I) - - ! The member output is computed as a linear interpolation of the nearest two markers + dl = p%Members(p%MOutLst(J)%MemberIDIndx)%dl + + ! The member output is computed as a linear interpolation of the nearest two member nodes + ! These nodes have the loads stored as concentrated loads, we will report per unit length versions of these loads + ! Member joint nodes will have their values doubled, interior member loads will not. + ! The concentrated load is then divided by the member's dl (element length) + if ( m1 <= p%NJoints ) then + mult1 = 2.0 + else + mult1 = 1.0 + end if + if ( m2 <= p%NJoints ) then + mult2 = 2.0 + else + mult2 = 1.0 + end if ! wave kinematics along the member - AllOuts(MNVi (:,I,J)) = m%D_FV (: ,m1)*(1-s) + m%D_FV (: ,m2)*s - AllOuts(MNAi (:,I,J)) = m%D_FA (: ,m1)*(1-s) + m%D_FA (: ,m2)*s - AllOuts(MNDynP( I,J)) = m%D_FDynP( m1)*(1-s) + m%D_FDynP( m2)*s + AllOuts(MNVi (:,I,J)) = m%FV (: ,m1)*(1-s) + m%FV (: ,m2)*s + AllOuts(MNAi (:,I,J)) = m%FA (: ,m1)*(1-s) + m%FA (: ,m2)*s + AllOuts(MNDynP( I,J)) = m%FDynP( m1)*(1-s) + m%FDynP( m2)*s ! Input motions - AllOuts(MNSTVi(:,I,J)) = u%DistribMesh%TranslationVel(: ,m1)*(1-s) + u%DistribMesh%TranslationVel(: ,m2)*s + AllOuts(MNSTVi(:,I,J)) = u%Mesh%TranslationVel(: ,m1)*(1-s) + u%Mesh%TranslationVel(: ,m2)*s ! AllOuts(MNSRVi(:,I,J)) = u%DistribMesh%RotationVel (: ,m1)*(1-s) + u%DistribMesh%RotationVel (: ,m2)*s - AllOuts(MNSTAi(:,I,J)) = u%DistribMesh%TranslationAcc(: ,m1)*(1-s) + u%DistribMesh%TranslationAcc(: ,m2)*s + AllOuts(MNSTAi(:,I,J)) = u%Mesh%TranslationAcc(: ,m1)*(1-s) + u%Mesh%TranslationAcc(: ,m2)*s ! AllOuts(MNSRAi(:,I,J)) = u%DistribMesh%RotationAcc (: ,m1)*(1-s) + u%DistribMesh%RotationAcc (: ,m2)*s - ! transverse drag force - AllOuts(MNFDi (:,I,J)) = m%D_F_D (: ,m1)*(1-s) + m%D_F_D (: ,m2)*s - ! inertial force - AllOuts(MNFIi (:,I,J)) = m%D_F_I (: ,m1)*(1-s) + m%D_F_I (: ,m2)*s - - ! marine growth weight - AllOuts(MNFMGi(:,I,J)) = p%D_F_MG (1:3,m1)*(1-s) + p%D_F_MG (1:3,m2)*s + ! ! transverse drag force + !AllOuts(MNFDi (:,I,J)) =(mult1*m%F_D (1:3,m1)*(1-s) + mult2*m%F_D (1:3,m2)*s)/dl + ! ! inertial force + !AllOuts(MNFIi (:,I,J)) =(mult1*m%F_I (1:3,m1)*(1-s) + mult2*m%F_I (1:3,m2)*s)/dl + ! + ! ! marine growth weight + !AllOuts(MNFMGi(:,I,J)) =(mult1*m%F_WMG (1:3,m1)*(1-s) + mult2*m%F_WMG(1:3,m2)*s)/dl + !AllOuts(MNMMGi(:,I,J)) =(mult1*m%F_WMG (4:6,m1)*(1-s) + mult2*m%F_WMG(4:6,m2)*s)/dl + ! + ! ! buoyancy forces + !AllOuts(MNFBi (:,I,J)) =(mult1*m%F_B (1:3,m1)*(1-s) + mult2*m%F_B (1:3,m2)*s)/dl + !AllOuts(MNFBFi(:,I,J)) =(mult1*m%F_BF (1:3,m1)*(1-s) + mult2*m%F_BF (1:3,m2)*s)/dl + ! + ! ! buoyancy moments + !AllOuts(MNMBi (:,I,J)) =(mult1*m%F_B (4:6,m1)*(1-s) + mult2*m%F_B (4:6,m2)*s)/dl + !AllOuts(MNMBFi(:,I,J)) =(mult1*m%F_BF (4:6,m1)*(1-s) + mult2*m%F_BF (4:6,m2)*s)/dl + ! + ! ! added mass forces + !AllOuts(MNFAGi(:,I,J)) =(mult1*m%F_IMG (1:3,m1)*(1-s) + mult2*m%F_IMG(1:3,m2)*s)/dl ! due to marine growth + !AllOuts(MNMAGi(:,I,J)) =(mult1*m%F_IMG (4:6,m1)*(1-s) + mult2*m%F_IMG(4:6,m2)*s)/dl + !AllOuts(MNFAMi (:,I,J)) =(mult1*m%F_A (1:3,m1)*(1-s) + mult2*m%F_A (1:3,m2)*s)/dl ! due to the structural member moving the fluid + !AllOuts(MNFAFi (:,I,J)) =(mult1*m%F_If (1:3,m1)*(1-s) + mult2*m%F_If(1:3 ,m2)*s)/dl ! due to the ballasted/flooded fluid + !AllOuts(MNMAFi (:,I,J)) =(mult1*m%F_If (4:6,m1)*(1-s) + mult2*m%F_If(4:6 ,m2)*s)/dl - ! buoyancy forces - AllOuts(MNFBi (:,I,J)) = m%D_F_B (1:3,m1)*(1-s) + m%D_F_B (1:3,m2)*s - AllOuts(MNFBFi(:,I,J)) = p%D_F_BF (1:3,m1)*(1-s) + p%D_F_BF (1:3,m2)*s - + ! transverse drag force + AllOuts(MNFDi (:,I,J)) =(mult1*m%memberLoads(im)%F_D (1:3,im1)*(1-s) + mult2*m%memberLoads(im)%F_D (1:3,im2)*s)/dl + ! inertial force + AllOuts(MNFIi (:,I,J)) =(mult1*m%memberLoads(im)%F_I (1:3,im1)*(1-s) + mult2*m%memberLoads(im)%F_I (1:3,im2)*s)/dl + + ! marine growth weight + AllOuts(MNFMGi(:,I,J)) =(mult1*m%memberLoads(im)%F_WMG (1:3,im1)*(1-s) + mult2*m%memberLoads(im)%F_WMG(1:3,im2)*s)/dl + AllOuts(MNMMGi(:,I,J)) =(mult1*m%memberLoads(im)%F_WMG (4:6,im1)*(1-s) + mult2*m%memberLoads(im)%F_WMG(4:6,im2)*s)/dl + + ! buoyancy forces + AllOuts(MNFBi (:,I,J)) =(mult1*m%memberLoads(im)%F_B (1:3,im1)*(1-s) + mult2*m%memberLoads(im)%F_B (1:3,im2)*s)/dl + AllOuts(MNFBFi(:,I,J)) =(mult1*m%memberLoads(im)%F_BF (1:3,im1)*(1-s) + mult2*m%memberLoads(im)%F_BF (1:3,im2)*s)/dl + ! buoyancy moments - AllOuts(MNMBi (:,I,J)) = m%D_F_B (4:6,m1)*(1-s) + m%D_F_B (4:6,m2)*s - AllOuts(MNMBFi(:,I,J)) = p%D_F_BF (4:6,m1)*(1-s) + p%D_F_BF (4:6,m2)*s - - ! added mass forces - AllOuts(MNFAGi(:,I,J)) = m%D_F_AM_MG(:,m1)*(1-s) + m%D_F_AM_MG(:,m2)*s ! due to marine growth - AllOuts(MNFAMi (:,I,J)) = m%D_F_AM_M(: ,m1)*(1-s) + m%D_F_AM_M(: ,m2)*s ! due to the structural member moving the fluid - AllOuts(MNFAFi (:,I,J)) = m%D_F_AM_F(: ,m1)*(1-s) + m%D_F_AM_F(: ,m2)*s ! due to the ballasted/flooded fluid - AllOuts(MNFAi (:,I,J)) = m%D_F_AM(: ,m1)*(1-s) + m%D_F_AM(: ,m2)*s ! the combined added mass force - - + AllOuts(MNMBi (:,I,J)) =(mult1*m%memberLoads(im)%F_B (4:6,im1)*(1-s) + mult2*m%memberLoads(im)%F_B (4:6,im2)*s)/dl + AllOuts(MNMBFi(:,I,J)) =(mult1*m%memberLoads(im)%F_BF (4:6,im1)*(1-s) + mult2*m%memberLoads(im)%F_BF (4:6,im2)*s)/dl + + ! added mass forces + AllOuts(MNFAGi(:,I,J)) =(mult1*m%memberLoads(im)%F_IMG (1:3,im1)*(1-s) + mult2*m%memberLoads(im)%F_IMG(1:3,im2)*s)/dl ! due to marine growth + AllOuts(MNMAGi(:,I,J)) =(mult1*m%memberLoads(im)%F_IMG (4:6,im1)*(1-s) + mult2*m%memberLoads(im)%F_IMG(4:6,im2)*s)/dl + AllOuts(MNFAMi (:,I,J)) =(mult1*m%memberLoads(im)%F_A (1:3,im1)*(1-s) + mult2*m%memberLoads(im)%F_A (1:3,im2)*s)/dl ! due to the structural member moving the fluid + AllOuts(MNFAFi (:,I,J)) =(mult1*m%memberLoads(im)%F_If (1:3,im1)*(1-s) + mult2*m%memberLoads(im)%F_If(1:3 ,im2)*s)/dl ! due to the ballasted/flooded fluid + AllOuts(MNMAFi (:,I,J)) =(mult1*m%memberLoads(im)%F_If (4:6,im1)*(1-s) + mult2*m%memberLoads(im)%F_If(4:6 ,im2)*s)/dl + END DO END DO ! Only generate joint-based outputs for the number of user-requested joint outputs - DO I=1,p%NJOutputs - - ! Zero-out the channels because we will be accumulating results - AllOuts(JVi (:,I)) = 0.0 - AllOuts(JAi (:,I)) = 0.0 - AllOuts(JDynP( I)) = 0.0 - AllOuts(JSTVi (:,I)) = 0.0 - AllOuts(JSTAi (:,I)) = 0.0 - AllOuts(JFDi (:,I)) = 0.0 - AllOuts(JFIi (:,I)) = 0.0 - AllOuts(JFBi (:,I)) = 0.0 - AllOuts(JMBi (:,I)) = 0.0 - AllOuts(JFBFi(:,I)) = 0.0 - AllOuts(JMBFi(:,I)) = 0.0 - - AllOuts(JFAMi(:,I)) = 0.0 + DO I=1,p%NJOutputs - - ! Which of the lumped mesh marker does this Output Joint point to? - DO J=1,p%JOutLst(I)%NumMarkers - m1 = p%JOutlst(I)%Markers(J) + ! Which of the mesh nodes does this Output Joint point to? + m1 = p%JOutlst(I)%JointIDIndx - ! Do not accumulate the wave kinematics and structural kinematics quantities - IF ( J == 1 ) THEN - AllOuts(JVi (:,I)) = m%L_FV (1:3,m1) ! fluid velocity - AllOuts(JAi (:,I)) = m%L_FA (1:3,m1) ! fluid acceleration - AllOuts(JDynP( I)) = m%L_FDynP( m1) ! fluid dynamic pressure - AllOuts(JSTVi (:,I)) = u%LumpedMesh%TranslationVel(: ,m1) ! structural velocity - AllOuts(JSTAi (:,I)) = u%LumpedMesh%TranslationAcc(: ,m1) ! structural acceleration - END IF + + AllOuts(JVi (:,I)) = m%FV (1:3,m1) ! fluid velocity + AllOuts(JAi (:,I)) = m%FA (1:3,m1) ! fluid acceleration + AllOuts(JDynP( I)) = m%FDynP( m1) ! fluid dynamic pressure + AllOuts(JSTVi (:,I)) = u%Mesh%TranslationVel(: ,m1) ! structural velocity + AllOuts(JSTAi (:,I)) = u%Mesh%TranslationAcc(: ,m1) ! structural acceleration + + AllOuts(JFDi (:,I)) = m%F_D_End (1:3, m1) ! axial drag force + AllOuts(JFBi (:,I)) = m%F_B_End (1:3, m1) ! buoyancy force + AllOuts(JMBi (:,I)) = m%F_B_End (4:6, m1) ! buoyancy moment + AllOuts(JFBFi(:,I)) = m%F_BF_End(1:3, m1) ! ballasted/filled buoyancy force + AllOuts(JMBFi(:,I)) = m%F_BF_End(4:6, m1) ! ballasted/filled buoyancy moment + AllOuts(JFIi (:,I)) = m%F_I_End (1:3, m1) ! inertial force + AllOuts(JFAMi(:,I)) = m%F_A_End(1:3, m1) ! added mass force + AllOuts(JFAGi(:,I)) = m%F_IMG_End(1:3, m1) ! marine growth inertia + AllOuts(JMAGi(:,I)) = m%F_IMG_End(4:6, m1) ! marine growth inertia + AllOuts(JFMGi(:,I)) = p%F_WMG_End(1:3, m1) ! marine growth weight - AllOuts(JFDi (:,I)) = AllOuts(JFDi (:,I)) + m%L_F_D (1:3, m1) ! axial drag force - AllOuts(JFBi (:,I)) = AllOuts(JFBi (:,I)) + m%L_F_B (1:3, m1) ! buoyancy force - AllOuts(JMBi (:,I)) = AllOuts(JMBi (:,I)) + m%L_F_B (4:6, m1) ! buoyancy moment - AllOuts(JFBFi(:,I)) = AllOuts(JFBFi(:,I)) + p%L_F_BF(1:3, m1) ! ballasted/filled buoyancy force - AllOuts(JMBFi(:,I)) = AllOuts(JMBFi(:,I)) + p%L_F_BF(4:6, m1) ! ballasted/filled buoyancy moment - AllOuts(JFIi (:,I)) = AllOuts(JFIi(:,I)) + m%L_F_I (1:3, m1) ! inertial force - AllOuts(JFAMi(:,I)) = AllOuts(JFAMi(:,I)) + m%L_F_AM(1:3, m1) ! added mass force - - END DO END DO @@ -7219,64 +6789,42 @@ SUBROUTINE MrsnOut_WriteOutputs( UnOutFile, Time, y, p, ErrStat, ErrMsg ) END SUBROUTINE MrsnOut_WriteOutputs -SUBROUTINE GetNeighboringMarkers(memberIndx, d, numMarkers, nodes, distribToNodeIndx, m1, m2, s, ErrStat, ErrMsg) +SUBROUTINE GetNeighboringNodes(member, d, m1, m2, i1, i2, s, ErrStat, ErrMsg) - INTEGER, INTENT( IN ) :: numMarkers - TYPE(Morison_NodeType), INTENT( IN ) :: nodes(:) - INTEGER, INTENT( IN ) :: distribToNodeIndx(:) - INTEGER, INTENT( IN ) :: memberIndx + TYPE(Morison_MemberType), INTENT( IN ) :: member REAL(ReKi), INTENT( IN ) :: d INTEGER, INTENT( OUT ) :: m1 INTEGER, INTENT( OUT ) :: m2 + INTEGER, INTENT( OUT ) :: i1 + INTEGER, INTENT( OUT ) :: i2 REAL(ReKi), INTENT( OUT ) :: s INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - - INTEGER :: I - REAL(ReKi) :: dLess - REAL(ReKi) :: dGreater - TYPE(Morison_NodeType) :: node - - !TODO: This is not working correctly! Fix it now! - - - ! Find all nodes which have the desired memberIndx and then look for the ones with the smallest neg and pos distance from the target point + ErrStat = ErrID_None ErrMsg = '' - dLess = -1000000.0 - dGreater = 1000000.0 + ! This only works because the member nodes are equally spaced + ! d is in the range [0,1] and is from the member starting node to the member ending node + ! s is in the range [0,1] but is the normalized distance between any two adjacent member nodes. - DO I=1,numMarkers - node = nodes(distribToNodeIndx(I)) - IF ( node%InpMbrIndx == memberIndx ) THEN - - IF ( node%InpMbrDist >= d ) THEN - IF ( node%InpMbrDist < dGreater ) THEN - dGreater = node%InpMbrDist - m2 = I - END IF - END IF - IF ( node%InpMbrDist <= d ) THEN - IF ( node%InpMbrDist > dLess ) THEN - dLess = node%InpMbrDist - m1 = I - END IF - END IF - END IF - - - END DO + i1 = floor(member%NElements*d) ! 0<= d <= 1.0 - IF ( EqualRealNos(dGreater - dLess, 0.0_ReKi ) ) THEN - s = 0.0 - ELSE - s = (d - dLess ) / ( dGreater - dLess ) - END IF + if ( i1 == member%NElements ) then + ! special case when d = 1.0_ReKi + i2 = i1 + 1 ! In this case, i1 = N and i2 = N+1 (one-based indexing which is what is needed to index into the NodeIndx arrays, below. + s = 1.0_ReKi + else + s = member%NElements*d - i1 ! here i1 is zero-based, s is fractional amount of between adjacent nodes, s = [0,1] + i1 = i1 + 1 ! Shift to one-based indices for work to follow, below + i2 = i1 + 1 + end if + + m1 = member%NodeIndx(i1) + m2 = member%NodeIndx(i2) -END SUBROUTINE GetNeighboringMarkers +END SUBROUTINE GetNeighboringNodes !==================================================================================================== @@ -7302,7 +6850,7 @@ SUBROUTINE MrsnOut_Init( InitInp, y, p, InitOut, ErrStat, ErrMsg ) ! INTEGER :: Indx ! Counts the current index into the WaveKinNd array ! CHARACTER(1024) :: OutFileName ! The name of the output file including the full path. ! CHARACTER(200) :: Frmt ! a string to hold a format statement - INTEGER :: m1, m2, memberIndx ! marker1, marker2, and member indices + INTEGER :: i1, i2, m1, m2, memberIndx ! marker1, marker2, and member indices REAL(ReKi) :: s ! interpolation factor ! INTEGER :: count ! node index @@ -7314,6 +6862,7 @@ SUBROUTINE MrsnOut_Init( InitInp, y, p, InitOut, ErrStat, ErrMsg ) ErrStat = ErrID_None ErrMsg = "" + !------------------------------------------------------------------------------------------------- ! Check that the variables in OutList are valid !------------------------------------------------------------------------------------------------- @@ -7354,35 +6903,20 @@ SUBROUTINE MrsnOut_Init( InitInp, y, p, InitOut, ErrStat, ErrMsg ) ! Need to search mesh for the two markers which surround the requested output location and then store those marker indices and compute the ! scale factor based on how far they are from the requested output location. ! Since this is being done on markers and not nodes, the subroutine must be called after the Morison_Init() subroutine is called - CALL GetNeighboringMarkers(memberIndx, p%MOutLst(I)%NodeLocs(J), p%NDistribMarkers, p%Nodes, p%distribToNodeIndx, m1, m2, s, ErrStat, ErrMsg) - - ! These indices are in the DistribMesh index system, not the overal nodes index system, so distribToNodeIndx() mapping needs to be performed if you - ! want to index into the nodes array or wave kinematics arrays - p%MOutLst(I)%Marker1(J) = m1 - p%MOutLst(I)%Marker2(J) = m2 ! The 2nd marker indx which is used to + + CALL GetNeighboringNodes(p%Members(memberIndx), p%MOutLst(I)%NodeLocs(J), m1, m2, i1, i2, s, ErrStat, ErrMsg) + + p%MOutLst(I)%MeshIndx1(J) = m1 + p%MOutLst(I)%MeshIndx2(J) = m2 + p%MOutLst(I)%MemberIndx1(J) = i1 + p%MOutLst(I)%MemberIndx2(J) = i2 p%MOutLst(I)%s(J) = s ! linear interpolation factor END DO END DO - - ! We need to map each Output Joint the user requested to the correct marker in the lumped mesh - - DO I=1,p%NJOutputs - - p%JOutlst(I)%NumMarkers = 0 - - DO J=1,p%NLumpedMarkers - IF ( p%Nodes(p%lumpedToNodeIndx(J))%JointIndx == p%JOutlst(I)%JointIDIndx ) THEN - p%JOutlst(I)%NumMarkers = p%JOutlst(I)%NumMarkers + 1 - p%JOutlst(I)%Markers(p%JOutlst(I)%NumMarkers) = J - END IF - END DO - - END DO - - + ! These variables are to help follow the framework template, but the data in them is simply a copy of data ! already available in the OutParam data structure @@ -7453,6 +6987,2029 @@ FUNCTION GetMorisonChannels ( NUserOutputs, UserOutputs, OutList, foundMask ErrStat = ErrID_None ErrMsg = "" + + ValidParamAry(1:500) = (/ & + "J1AXI ","J1AYI ","J1AZI ","J1DYNP ","J1FAGXI ","J1FAGYI ","J1FAGZI ", & + "J1FAMXI ","J1FAMYI ","J1FAMZI ","J1FBFXI ","J1FBFYI ","J1FBFZI ","J1FBXI ", & + "J1FBYI ","J1FBZI ","J1FDXI ","J1FDYI ","J1FDZI ","J1FIXI ","J1FIYI ", & + "J1FIZI ","J1FMGXI ","J1FMGYI ","J1FMGZI ","J1MAGXI ","J1MAGYI ","J1MAGZI ", & + "J1MBFXI ","J1MBFYI ","J1MBFZI ","J1MBXI ","J1MBYI ","J1MBZI ","J1STAXI ", & + "J1STAYI ","J1STAZI ","J1STVXI ","J1STVYI ","J1STVZI ","J1VXI ","J1VYI ", & + "J1VZI ","J2AXI ","J2AYI ","J2AZI ","J2DYNP ","J2FAGXI ","J2FAGYI ", & + "J2FAGZI ","J2FAMXI ","J2FAMYI ","J2FAMZI ","J2FBFXI ","J2FBFYI ","J2FBFZI ", & + "J2FBXI ","J2FBYI ","J2FBZI ","J2FDXI ","J2FDYI ","J2FDZI ","J2FIXI ", & + "J2FIYI ","J2FIZI ","J2FMGXI ","J2FMGYI ","J2FMGZI ","J2MAGXI ","J2MAGYI ", & + "J2MAGZI ","J2MBFXI ","J2MBFYI ","J2MBFZI ","J2MBXI ","J2MBYI ","J2MBZI ", & + "J2STAXI ","J2STAYI ","J2STAZI ","J2STVXI ","J2STVYI ","J2STVZI ","J2VXI ", & + "J2VYI ","J2VZI ","J3AXI ","J3AYI ","J3AZI ","J3DYNP ","J3FAGXI ", & + "J3FAGYI ","J3FAGZI ","J3FAMXI ","J3FAMYI ","J3FAMZI ","J3FBFXI ","J3FBFYI ", & + "J3FBFZI ","J3FBXI ","J3FBYI ","J3FBZI ","J3FDXI ","J3FDYI ","J3FDZI ", & + "J3FIXI ","J3FIYI ","J3FIZI ","J3FMGXI ","J3FMGYI ","J3FMGZI ","J3MAGXI ", & + "J3MAGYI ","J3MAGZI ","J3MBFXI ","J3MBFYI ","J3MBFZI ","J3MBXI ","J3MBYI ", & + "J3MBZI ","J3STAXI ","J3STAYI ","J3STAZI ","J3STVXI ","J3STVYI ","J3STVZI ", & + "J3VXI ","J3VYI ","J3VZI ","J4AXI ","J4AYI ","J4AZI ","J4DYNP ", & + "J4FAGXI ","J4FAGYI ","J4FAGZI ","J4FAMXI ","J4FAMYI ","J4FAMZI ","J4FBFXI ", & + "J4FBFYI ","J4FBFZI ","J4FBXI ","J4FBYI ","J4FBZI ","J4FDXI ","J4FDYI ", & + "J4FDZI ","J4FIXI ","J4FIYI ","J4FIZI ","J4FMGXI ","J4FMGYI ","J4FMGZI ", & + "J4MAGXI ","J4MAGYI ","J4MAGZI ","J4MBFXI ","J4MBFYI ","J4MBFZI ","J4MBXI ", & + "J4MBYI ","J4MBZI ","J4STAXI ","J4STAYI ","J4STAZI ","J4STVXI ","J4STVYI ", & + "J4STVZI ","J4VXI ","J4VYI ","J4VZI ","J5AXI ","J5AYI ","J5AZI ", & + "J5DYNP ","J5FAGXI ","J5FAGYI ","J5FAGZI ","J5FAMXI ","J5FAMYI ","J5FAMZI ", & + "J5FBFXI ","J5FBFYI ","J5FBFZI ","J5FBXI ","J5FBYI ","J5FBZI ","J5FDXI ", & + "J5FDYI ","J5FDZI ","J5FIXI ","J5FIYI ","J5FIZI ","J5FMGXI ","J5FMGYI ", & + "J5FMGZI ","J5MAGXI ","J5MAGYI ","J5MAGZI ","J5MBFXI ","J5MBFYI ","J5MBFZI ", & + "J5MBXI ","J5MBYI ","J5MBZI ","J5STAXI ","J5STAYI ","J5STAZI ","J5STVXI ", & + "J5STVYI ","J5STVZI ","J5VXI ","J5VYI ","J5VZI ","J6AXI ","J6AYI ", & + "J6AZI ","J6DYNP ","J6FAGXI ","J6FAGYI ","J6FAGZI ","J6FAMXI ","J6FAMYI ", & + "J6FAMZI ","J6FBFXI ","J6FBFYI ","J6FBFZI ","J6FBXI ","J6FBYI ","J6FBZI ", & + "J6FDXI ","J6FDYI ","J6FDZI ","J6FIXI ","J6FIYI ","J6FIZI ","J6FMGXI ", & + "J6FMGYI ","J6FMGZI ","J6MAGXI ","J6MAGYI ","J6MAGZI ","J6MBFXI ","J6MBFYI ", & + "J6MBFZI ","J6MBXI ","J6MBYI ","J6MBZI ","J6STAXI ","J6STAYI ","J6STAZI ", & + "J6STVXI ","J6STVYI ","J6STVZI ","J6VXI ","J6VYI ","J6VZI ","J7AXI ", & + "J7AYI ","J7AZI ","J7DYNP ","J7FAGXI ","J7FAGYI ","J7FAGZI ","J7FAMXI ", & + "J7FAMYI ","J7FAMZI ","J7FBFXI ","J7FBFYI ","J7FBFZI ","J7FBXI ","J7FBYI ", & + "J7FBZI ","J7FDXI ","J7FDYI ","J7FDZI ","J7FIXI ","J7FIYI ","J7FIZI ", & + "J7FMGXI ","J7FMGYI ","J7FMGZI ","J7MAGXI ","J7MAGYI ","J7MAGZI ","J7MBFXI ", & + "J7MBFYI ","J7MBFZI ","J7MBXI ","J7MBYI ","J7MBZI ","J7STAXI ","J7STAYI ", & + "J7STAZI ","J7STVXI ","J7STVYI ","J7STVZI ","J7VXI ","J7VYI ","J7VZI ", & + "J8AXI ","J8AYI ","J8AZI ","J8DYNP ","J8FAGXI ","J8FAGYI ","J8FAGZI ", & + "J8FAMXI ","J8FAMYI ","J8FAMZI ","J8FBFXI ","J8FBFYI ","J8FBFZI ","J8FBXI ", & + "J8FBYI ","J8FBZI ","J8FDXI ","J8FDYI ","J8FDZI ","J8FIXI ","J8FIYI ", & + "J8FIZI ","J8FMGXI ","J8FMGYI ","J8FMGZI ","J8MAGXI ","J8MAGYI ","J8MAGZI ", & + "J8MBFXI ","J8MBFYI ","J8MBFZI ","J8MBXI ","J8MBYI ","J8MBZI ","J8STAXI ", & + "J8STAYI ","J8STAZI ","J8STVXI ","J8STVYI ","J8STVZI ","J8VXI ","J8VYI ", & + "J8VZI ","J9AXI ","J9AYI ","J9AZI ","J9DYNP ","J9FAGXI ","J9FAGYI ", & + "J9FAGZI ","J9FAMXI ","J9FAMYI ","J9FAMZI ","J9FBFXI ","J9FBFYI ","J9FBFZI ", & + "J9FBXI ","J9FBYI ","J9FBZI ","J9FDXI ","J9FDYI ","J9FDZI ","J9FIXI ", & + "J9FIYI ","J9FIZI ","J9FMGXI ","J9FMGYI ","J9FMGZI ","J9MAGXI ","J9MAGYI ", & + "J9MAGZI ","J9MBFXI ","J9MBFYI ","J9MBFZI ","J9MBXI ","J9MBYI ","J9MBZI ", & + "J9STAXI ","J9STAYI ","J9STAZI ","J9STVXI ","J9STVYI ","J9STVZI ","J9VXI ", & + "J9VYI ","J9VZI ","M1N1AXI ","M1N1AYI ","M1N1AZI ","M1N1DYNP ","M1N1FAFXI", & + "M1N1FAFYI","M1N1FAFZI","M1N1FAGXI","M1N1FAGYI","M1N1FAGZI","M1N1FAMXI","M1N1FAMYI", & + "M1N1FAMZI","M1N1FBFXI","M1N1FBFYI","M1N1FBFZI","M1N1FBXI ","M1N1FBYI ","M1N1FBZI ", & + "M1N1FDXI ","M1N1FDYI ","M1N1FDZI ","M1N1FIXI ","M1N1FIYI ","M1N1FIZI ","M1N1FMGXI", & + "M1N1FMGYI","M1N1FMGZI","M1N1MAFXI","M1N1MAFYI","M1N1MAFZI","M1N1MAGXI","M1N1MAGYI", & + "M1N1MAGZI","M1N1MBFXI","M1N1MBFYI","M1N1MBFZI","M1N1MBXI ","M1N1MBYI ","M1N1MBZI ", & + "M1N1MMGXI","M1N1MMGYI","M1N1MMGZI","M1N1STAXI","M1N1STAYI","M1N1STAZI","M1N1STVXI", & + "M1N1STVYI","M1N1STVZI","M1N1VXI ","M1N1VYI ","M1N1VZI ","M1N2AXI ","M1N2AYI ", & + "M1N2AZI ","M1N2DYNP ","M1N2FAFXI","M1N2FAFYI","M1N2FAFZI","M1N2FAGXI","M1N2FAGYI", & + "M1N2FAGZI","M1N2FAMXI","M1N2FAMYI","M1N2FAMZI","M1N2FBFXI","M1N2FBFYI","M1N2FBFZI", & + "M1N2FBXI ","M1N2FBYI ","M1N2FBZI ","M1N2FDXI ","M1N2FDYI ","M1N2FDZI ","M1N2FIXI ", & + "M1N2FIYI ","M1N2FIZI ","M1N2FMGXI","M1N2FMGYI","M1N2FMGZI","M1N2MAFXI","M1N2MAFYI", & + "M1N2MAFZI","M1N2MAGXI","M1N2MAGYI","M1N2MAGZI","M1N2MBFXI","M1N2MBFYI","M1N2MBFZI", & + "M1N2MBXI ","M1N2MBYI ","M1N2MBZI ","M1N2MMGXI","M1N2MMGYI","M1N2MMGZI","M1N2STAXI", & + "M1N2STAYI","M1N2STAZI","M1N2STVXI","M1N2STVYI","M1N2STVZI","M1N2VXI ","M1N2VYI ", & + "M1N2VZI ","M1N3AXI ","M1N3AYI ","M1N3AZI ","M1N3DYNP ","M1N3FAFXI","M1N3FAFYI", & + "M1N3FAFZI","M1N3FAGXI","M1N3FAGYI"/) + ValidParamAry(501:1000) = (/ & + "M1N3FAGZI","M1N3FAMXI","M1N3FAMYI","M1N3FAMZI","M1N3FBFXI","M1N3FBFYI","M1N3FBFZI", & + "M1N3FBXI ","M1N3FBYI ","M1N3FBZI ","M1N3FDXI ","M1N3FDYI ","M1N3FDZI ","M1N3FIXI ", & + "M1N3FIYI ","M1N3FIZI ","M1N3FMGXI","M1N3FMGYI","M1N3FMGZI","M1N3MAFXI","M1N3MAFYI", & + "M1N3MAFZI","M1N3MAGXI","M1N3MAGYI","M1N3MAGZI","M1N3MBFXI","M1N3MBFYI","M1N3MBFZI", & + "M1N3MBXI ","M1N3MBYI ","M1N3MBZI ","M1N3MMGXI","M1N3MMGYI","M1N3MMGZI","M1N3STAXI", & + "M1N3STAYI","M1N3STAZI","M1N3STVXI","M1N3STVYI","M1N3STVZI","M1N3VXI ","M1N3VYI ", & + "M1N3VZI ","M1N4AXI ","M1N4AYI ","M1N4AZI ","M1N4DYNP ","M1N4FAFXI","M1N4FAFYI", & + "M1N4FAFZI","M1N4FAGXI","M1N4FAGYI","M1N4FAGZI","M1N4FAMXI","M1N4FAMYI","M1N4FAMZI", & + "M1N4FBFXI","M1N4FBFYI","M1N4FBFZI","M1N4FBXI ","M1N4FBYI ","M1N4FBZI ","M1N4FDXI ", & + "M1N4FDYI ","M1N4FDZI ","M1N4FIXI ","M1N4FIYI ","M1N4FIZI ","M1N4FMGXI","M1N4FMGYI", & + "M1N4FMGZI","M1N4MAFXI","M1N4MAFYI","M1N4MAFZI","M1N4MAGXI","M1N4MAGYI","M1N4MAGZI", & + "M1N4MBFXI","M1N4MBFYI","M1N4MBFZI","M1N4MBXI ","M1N4MBYI ","M1N4MBZI ","M1N4MMGXI", & + "M1N4MMGYI","M1N4MMGZI","M1N4STAXI","M1N4STAYI","M1N4STAZI","M1N4STVXI","M1N4STVYI", & + "M1N4STVZI","M1N4VXI ","M1N4VYI ","M1N4VZI ","M1N5AXI ","M1N5AYI ","M1N5AZI ", & + "M1N5DYNP ","M1N5FAFXI","M1N5FAFYI","M1N5FAFZI","M1N5FAGXI","M1N5FAGYI","M1N5FAGZI", & + "M1N5FAMXI","M1N5FAMYI","M1N5FAMZI","M1N5FBFXI","M1N5FBFYI","M1N5FBFZI","M1N5FBXI ", & + "M1N5FBYI ","M1N5FBZI ","M1N5FDXI ","M1N5FDYI ","M1N5FDZI ","M1N5FIXI ","M1N5FIYI ", & + "M1N5FIZI ","M1N5FMGXI","M1N5FMGYI","M1N5FMGZI","M1N5MAFXI","M1N5MAFYI","M1N5MAFZI", & + "M1N5MAGXI","M1N5MAGYI","M1N5MAGZI","M1N5MBFXI","M1N5MBFYI","M1N5MBFZI","M1N5MBXI ", & + "M1N5MBYI ","M1N5MBZI ","M1N5MMGXI","M1N5MMGYI","M1N5MMGZI","M1N5STAXI","M1N5STAYI", & + "M1N5STAZI","M1N5STVXI","M1N5STVYI","M1N5STVZI","M1N5VXI ","M1N5VYI ","M1N5VZI ", & + "M1N6AXI ","M1N6AYI ","M1N6AZI ","M1N6DYNP ","M1N6FAFXI","M1N6FAFYI","M1N6FAFZI", & + "M1N6FAGXI","M1N6FAGYI","M1N6FAGZI","M1N6FAMXI","M1N6FAMYI","M1N6FAMZI","M1N6FBFXI", & + "M1N6FBFYI","M1N6FBFZI","M1N6FBXI ","M1N6FBYI ","M1N6FBZI ","M1N6FDXI ","M1N6FDYI ", & + "M1N6FDZI ","M1N6FIXI ","M1N6FIYI ","M1N6FIZI ","M1N6FMGXI","M1N6FMGYI","M1N6FMGZI", & + "M1N6MAFXI","M1N6MAFYI","M1N6MAFZI","M1N6MAGXI","M1N6MAGYI","M1N6MAGZI","M1N6MBFXI", & + "M1N6MBFYI","M1N6MBFZI","M1N6MBXI ","M1N6MBYI ","M1N6MBZI ","M1N6MMGXI","M1N6MMGYI", & + "M1N6MMGZI","M1N6STAXI","M1N6STAYI","M1N6STAZI","M1N6STVXI","M1N6STVYI","M1N6STVZI", & + "M1N6VXI ","M1N6VYI ","M1N6VZI ","M1N7AXI ","M1N7AYI ","M1N7AZI ","M1N7DYNP ", & + "M1N7FAFXI","M1N7FAFYI","M1N7FAFZI","M1N7FAGXI","M1N7FAGYI","M1N7FAGZI","M1N7FAMXI", & + "M1N7FAMYI","M1N7FAMZI","M1N7FBFXI","M1N7FBFYI","M1N7FBFZI","M1N7FBXI ","M1N7FBYI ", & + "M1N7FBZI ","M1N7FDXI ","M1N7FDYI ","M1N7FDZI ","M1N7FIXI ","M1N7FIYI ","M1N7FIZI ", & + "M1N7FMGXI","M1N7FMGYI","M1N7FMGZI","M1N7MAFXI","M1N7MAFYI","M1N7MAFZI","M1N7MAGXI", & + "M1N7MAGYI","M1N7MAGZI","M1N7MBFXI","M1N7MBFYI","M1N7MBFZI","M1N7MBXI ","M1N7MBYI ", & + "M1N7MBZI ","M1N7MMGXI","M1N7MMGYI","M1N7MMGZI","M1N7STAXI","M1N7STAYI","M1N7STAZI", & + "M1N7STVXI","M1N7STVYI","M1N7STVZI","M1N7VXI ","M1N7VYI ","M1N7VZI ","M1N8AXI ", & + "M1N8AYI ","M1N8AZI ","M1N8DYNP ","M1N8FAFXI","M1N8FAFYI","M1N8FAFZI","M1N8FAGXI", & + "M1N8FAGYI","M1N8FAGZI","M1N8FAMXI","M1N8FAMYI","M1N8FAMZI","M1N8FBFXI","M1N8FBFYI", & + "M1N8FBFZI","M1N8FBXI ","M1N8FBYI ","M1N8FBZI ","M1N8FDXI ","M1N8FDYI ","M1N8FDZI ", & + "M1N8FIXI ","M1N8FIYI ","M1N8FIZI ","M1N8FMGXI","M1N8FMGYI","M1N8FMGZI","M1N8MAFXI", & + "M1N8MAFYI","M1N8MAFZI","M1N8MAGXI","M1N8MAGYI","M1N8MAGZI","M1N8MBFXI","M1N8MBFYI", & + "M1N8MBFZI","M1N8MBXI ","M1N8MBYI ","M1N8MBZI ","M1N8MMGXI","M1N8MMGYI","M1N8MMGZI", & + "M1N8STAXI","M1N8STAYI","M1N8STAZI","M1N8STVXI","M1N8STVYI","M1N8STVZI","M1N8VXI ", & + "M1N8VYI ","M1N8VZI ","M1N9AXI ","M1N9AYI ","M1N9AZI ","M1N9DYNP ","M1N9FAFXI", & + "M1N9FAFYI","M1N9FAFZI","M1N9FAGXI","M1N9FAGYI","M1N9FAGZI","M1N9FAMXI","M1N9FAMYI", & + "M1N9FAMZI","M1N9FBFXI","M1N9FBFYI","M1N9FBFZI","M1N9FBXI ","M1N9FBYI ","M1N9FBZI ", & + "M1N9FDXI ","M1N9FDYI ","M1N9FDZI ","M1N9FIXI ","M1N9FIYI ","M1N9FIZI ","M1N9FMGXI", & + "M1N9FMGYI","M1N9FMGZI","M1N9MAFXI","M1N9MAFYI","M1N9MAFZI","M1N9MAGXI","M1N9MAGYI", & + "M1N9MAGZI","M1N9MBFXI","M1N9MBFYI","M1N9MBFZI","M1N9MBXI ","M1N9MBYI ","M1N9MBZI ", & + "M1N9MMGXI","M1N9MMGYI","M1N9MMGZI","M1N9STAXI","M1N9STAYI","M1N9STAZI","M1N9STVXI", & + "M1N9STVYI","M1N9STVZI","M1N9VXI ","M1N9VYI ","M1N9VZI ","M2N1AXI ","M2N1AYI ", & + "M2N1AZI ","M2N1DYNP ","M2N1FAFXI","M2N1FAFYI","M2N1FAFZI","M2N1FAGXI","M2N1FAGYI", & + "M2N1FAGZI","M2N1FAMXI","M2N1FAMYI","M2N1FAMZI","M2N1FBFXI","M2N1FBFYI","M2N1FBFZI", & + "M2N1FBXI ","M2N1FBYI ","M2N1FBZI ","M2N1FDXI ","M2N1FDYI ","M2N1FDZI ","M2N1FIXI ", & + "M2N1FIYI ","M2N1FIZI ","M2N1FMGXI","M2N1FMGYI","M2N1FMGZI","M2N1MAFXI","M2N1MAFYI", & + "M2N1MAFZI","M2N1MAGXI","M2N1MAGYI","M2N1MAGZI","M2N1MBFXI","M2N1MBFYI","M2N1MBFZI", & + "M2N1MBXI ","M2N1MBYI ","M2N1MBZI ","M2N1MMGXI","M2N1MMGYI","M2N1MMGZI","M2N1STAXI", & + "M2N1STAYI","M2N1STAZI","M2N1STVXI","M2N1STVYI","M2N1STVZI","M2N1VXI ","M2N1VYI ", & + "M2N1VZI ","M2N2AXI ","M2N2AYI ","M2N2AZI ","M2N2DYNP ","M2N2FAFXI","M2N2FAFYI", & + "M2N2FAFZI","M2N2FAGXI","M2N2FAGYI","M2N2FAGZI","M2N2FAMXI","M2N2FAMYI","M2N2FAMZI", & + "M2N2FBFXI","M2N2FBFYI","M2N2FBFZI","M2N2FBXI ","M2N2FBYI ","M2N2FBZI ","M2N2FDXI ", & + "M2N2FDYI ","M2N2FDZI ","M2N2FIXI ","M2N2FIYI ","M2N2FIZI ","M2N2FMGXI","M2N2FMGYI", & + "M2N2FMGZI","M2N2MAFXI","M2N2MAFYI","M2N2MAFZI","M2N2MAGXI","M2N2MAGYI","M2N2MAGZI", & + "M2N2MBFXI","M2N2MBFYI","M2N2MBFZI","M2N2MBXI ","M2N2MBYI ","M2N2MBZI ","M2N2MMGXI", & + "M2N2MMGYI","M2N2MMGZI","M2N2STAXI","M2N2STAYI","M2N2STAZI","M2N2STVXI","M2N2STVYI", & + "M2N2STVZI","M2N2VXI ","M2N2VYI ","M2N2VZI ","M2N3AXI ","M2N3AYI ","M2N3AZI ", & + "M2N3DYNP ","M2N3FAFXI","M2N3FAFYI","M2N3FAFZI","M2N3FAGXI","M2N3FAGYI","M2N3FAGZI", & + "M2N3FAMXI","M2N3FAMYI","M2N3FAMZI","M2N3FBFXI","M2N3FBFYI","M2N3FBFZI","M2N3FBXI ", & + "M2N3FBYI ","M2N3FBZI ","M2N3FDXI ","M2N3FDYI ","M2N3FDZI ","M2N3FIXI ","M2N3FIYI ", & + "M2N3FIZI ","M2N3FMGXI","M2N3FMGYI","M2N3FMGZI","M2N3MAFXI","M2N3MAFYI","M2N3MAFZI", & + "M2N3MAGXI","M2N3MAGYI","M2N3MAGZI","M2N3MBFXI","M2N3MBFYI","M2N3MBFZI","M2N3MBXI ", & + "M2N3MBYI ","M2N3MBZI ","M2N3MMGXI"/) + ValidParamAry(1001:1500) = (/ & + "M2N3MMGYI","M2N3MMGZI","M2N3STAXI","M2N3STAYI","M2N3STAZI","M2N3STVXI","M2N3STVYI", & + "M2N3STVZI","M2N3VXI ","M2N3VYI ","M2N3VZI ","M2N4AXI ","M2N4AYI ","M2N4AZI ", & + "M2N4DYNP ","M2N4FAFXI","M2N4FAFYI","M2N4FAFZI","M2N4FAGXI","M2N4FAGYI","M2N4FAGZI", & + "M2N4FAMXI","M2N4FAMYI","M2N4FAMZI","M2N4FBFXI","M2N4FBFYI","M2N4FBFZI","M2N4FBXI ", & + "M2N4FBYI ","M2N4FBZI ","M2N4FDXI ","M2N4FDYI ","M2N4FDZI ","M2N4FIXI ","M2N4FIYI ", & + "M2N4FIZI ","M2N4FMGXI","M2N4FMGYI","M2N4FMGZI","M2N4MAFXI","M2N4MAFYI","M2N4MAFZI", & + "M2N4MAGXI","M2N4MAGYI","M2N4MAGZI","M2N4MBFXI","M2N4MBFYI","M2N4MBFZI","M2N4MBXI ", & + "M2N4MBYI ","M2N4MBZI ","M2N4MMGXI","M2N4MMGYI","M2N4MMGZI","M2N4STAXI","M2N4STAYI", & + "M2N4STAZI","M2N4STVXI","M2N4STVYI","M2N4STVZI","M2N4VXI ","M2N4VYI ","M2N4VZI ", & + "M2N5AXI ","M2N5AYI ","M2N5AZI ","M2N5DYNP ","M2N5FAFXI","M2N5FAFYI","M2N5FAFZI", & + "M2N5FAGXI","M2N5FAGYI","M2N5FAGZI","M2N5FAMXI","M2N5FAMYI","M2N5FAMZI","M2N5FBFXI", & + "M2N5FBFYI","M2N5FBFZI","M2N5FBXI ","M2N5FBYI ","M2N5FBZI ","M2N5FDXI ","M2N5FDYI ", & + "M2N5FDZI ","M2N5FIXI ","M2N5FIYI ","M2N5FIZI ","M2N5FMGXI","M2N5FMGYI","M2N5FMGZI", & + "M2N5MAFXI","M2N5MAFYI","M2N5MAFZI","M2N5MAGXI","M2N5MAGYI","M2N5MAGZI","M2N5MBFXI", & + "M2N5MBFYI","M2N5MBFZI","M2N5MBXI ","M2N5MBYI ","M2N5MBZI ","M2N5MMGXI","M2N5MMGYI", & + "M2N5MMGZI","M2N5STAXI","M2N5STAYI","M2N5STAZI","M2N5STVXI","M2N5STVYI","M2N5STVZI", & + "M2N5VXI ","M2N5VYI ","M2N5VZI ","M2N6AXI ","M2N6AYI ","M2N6AZI ","M2N6DYNP ", & + "M2N6FAFXI","M2N6FAFYI","M2N6FAFZI","M2N6FAGXI","M2N6FAGYI","M2N6FAGZI","M2N6FAMXI", & + "M2N6FAMYI","M2N6FAMZI","M2N6FBFXI","M2N6FBFYI","M2N6FBFZI","M2N6FBXI ","M2N6FBYI ", & + "M2N6FBZI ","M2N6FDXI ","M2N6FDYI ","M2N6FDZI ","M2N6FIXI ","M2N6FIYI ","M2N6FIZI ", & + "M2N6FMGXI","M2N6FMGYI","M2N6FMGZI","M2N6MAFXI","M2N6MAFYI","M2N6MAFZI","M2N6MAGXI", & + "M2N6MAGYI","M2N6MAGZI","M2N6MBFXI","M2N6MBFYI","M2N6MBFZI","M2N6MBXI ","M2N6MBYI ", & + "M2N6MBZI ","M2N6MMGXI","M2N6MMGYI","M2N6MMGZI","M2N6STAXI","M2N6STAYI","M2N6STAZI", & + "M2N6STVXI","M2N6STVYI","M2N6STVZI","M2N6VXI ","M2N6VYI ","M2N6VZI ","M2N7AXI ", & + "M2N7AYI ","M2N7AZI ","M2N7DYNP ","M2N7FAFXI","M2N7FAFYI","M2N7FAFZI","M2N7FAGXI", & + "M2N7FAGYI","M2N7FAGZI","M2N7FAMXI","M2N7FAMYI","M2N7FAMZI","M2N7FBFXI","M2N7FBFYI", & + "M2N7FBFZI","M2N7FBXI ","M2N7FBYI ","M2N7FBZI ","M2N7FDXI ","M2N7FDYI ","M2N7FDZI ", & + "M2N7FIXI ","M2N7FIYI ","M2N7FIZI ","M2N7FMGXI","M2N7FMGYI","M2N7FMGZI","M2N7MAFXI", & + "M2N7MAFYI","M2N7MAFZI","M2N7MAGXI","M2N7MAGYI","M2N7MAGZI","M2N7MBFXI","M2N7MBFYI", & + "M2N7MBFZI","M2N7MBXI ","M2N7MBYI ","M2N7MBZI ","M2N7MMGXI","M2N7MMGYI","M2N7MMGZI", & + "M2N7STAXI","M2N7STAYI","M2N7STAZI","M2N7STVXI","M2N7STVYI","M2N7STVZI","M2N7VXI ", & + "M2N7VYI ","M2N7VZI ","M2N8AXI ","M2N8AYI ","M2N8AZI ","M2N8DYNP ","M2N8FAFXI", & + "M2N8FAFYI","M2N8FAFZI","M2N8FAGXI","M2N8FAGYI","M2N8FAGZI","M2N8FAMXI","M2N8FAMYI", & + "M2N8FAMZI","M2N8FBFXI","M2N8FBFYI","M2N8FBFZI","M2N8FBXI ","M2N8FBYI ","M2N8FBZI ", & + "M2N8FDXI ","M2N8FDYI ","M2N8FDZI ","M2N8FIXI ","M2N8FIYI ","M2N8FIZI ","M2N8FMGXI", & + "M2N8FMGYI","M2N8FMGZI","M2N8MAFXI","M2N8MAFYI","M2N8MAFZI","M2N8MAGXI","M2N8MAGYI", & + "M2N8MAGZI","M2N8MBFXI","M2N8MBFYI","M2N8MBFZI","M2N8MBXI ","M2N8MBYI ","M2N8MBZI ", & + "M2N8MMGXI","M2N8MMGYI","M2N8MMGZI","M2N8STAXI","M2N8STAYI","M2N8STAZI","M2N8STVXI", & + "M2N8STVYI","M2N8STVZI","M2N8VXI ","M2N8VYI ","M2N8VZI ","M2N9AXI ","M2N9AYI ", & + "M2N9AZI ","M2N9DYNP ","M2N9FAFXI","M2N9FAFYI","M2N9FAFZI","M2N9FAGXI","M2N9FAGYI", & + "M2N9FAGZI","M2N9FAMXI","M2N9FAMYI","M2N9FAMZI","M2N9FBFXI","M2N9FBFYI","M2N9FBFZI", & + "M2N9FBXI ","M2N9FBYI ","M2N9FBZI ","M2N9FDXI ","M2N9FDYI ","M2N9FDZI ","M2N9FIXI ", & + "M2N9FIYI ","M2N9FIZI ","M2N9FMGXI","M2N9FMGYI","M2N9FMGZI","M2N9MAFXI","M2N9MAFYI", & + "M2N9MAFZI","M2N9MAGXI","M2N9MAGYI","M2N9MAGZI","M2N9MBFXI","M2N9MBFYI","M2N9MBFZI", & + "M2N9MBXI ","M2N9MBYI ","M2N9MBZI ","M2N9MMGXI","M2N9MMGYI","M2N9MMGZI","M2N9STAXI", & + "M2N9STAYI","M2N9STAZI","M2N9STVXI","M2N9STVYI","M2N9STVZI","M2N9VXI ","M2N9VYI ", & + "M2N9VZI ","M3N1AXI ","M3N1AYI ","M3N1AZI ","M3N1DYNP ","M3N1FAFXI","M3N1FAFYI", & + "M3N1FAFZI","M3N1FAGXI","M3N1FAGYI","M3N1FAGZI","M3N1FAMXI","M3N1FAMYI","M3N1FAMZI", & + "M3N1FBFXI","M3N1FBFYI","M3N1FBFZI","M3N1FBXI ","M3N1FBYI ","M3N1FBZI ","M3N1FDXI ", & + "M3N1FDYI ","M3N1FDZI ","M3N1FIXI ","M3N1FIYI ","M3N1FIZI ","M3N1FMGXI","M3N1FMGYI", & + "M3N1FMGZI","M3N1MAFXI","M3N1MAFYI","M3N1MAFZI","M3N1MAGXI","M3N1MAGYI","M3N1MAGZI", & + "M3N1MBFXI","M3N1MBFYI","M3N1MBFZI","M3N1MBXI ","M3N1MBYI ","M3N1MBZI ","M3N1MMGXI", & + "M3N1MMGYI","M3N1MMGZI","M3N1STAXI","M3N1STAYI","M3N1STAZI","M3N1STVXI","M3N1STVYI", & + "M3N1STVZI","M3N1VXI ","M3N1VYI ","M3N1VZI ","M3N2AXI ","M3N2AYI ","M3N2AZI ", & + "M3N2DYNP ","M3N2FAFXI","M3N2FAFYI","M3N2FAFZI","M3N2FAGXI","M3N2FAGYI","M3N2FAGZI", & + "M3N2FAMXI","M3N2FAMYI","M3N2FAMZI","M3N2FBFXI","M3N2FBFYI","M3N2FBFZI","M3N2FBXI ", & + "M3N2FBYI ","M3N2FBZI ","M3N2FDXI ","M3N2FDYI ","M3N2FDZI ","M3N2FIXI ","M3N2FIYI ", & + "M3N2FIZI ","M3N2FMGXI","M3N2FMGYI","M3N2FMGZI","M3N2MAFXI","M3N2MAFYI","M3N2MAFZI", & + "M3N2MAGXI","M3N2MAGYI","M3N2MAGZI","M3N2MBFXI","M3N2MBFYI","M3N2MBFZI","M3N2MBXI ", & + "M3N2MBYI ","M3N2MBZI ","M3N2MMGXI","M3N2MMGYI","M3N2MMGZI","M3N2STAXI","M3N2STAYI", & + "M3N2STAZI","M3N2STVXI","M3N2STVYI","M3N2STVZI","M3N2VXI ","M3N2VYI ","M3N2VZI ", & + "M3N3AXI ","M3N3AYI ","M3N3AZI ","M3N3DYNP ","M3N3FAFXI","M3N3FAFYI","M3N3FAFZI", & + "M3N3FAGXI","M3N3FAGYI","M3N3FAGZI","M3N3FAMXI","M3N3FAMYI","M3N3FAMZI","M3N3FBFXI", & + "M3N3FBFYI","M3N3FBFZI","M3N3FBXI ","M3N3FBYI ","M3N3FBZI ","M3N3FDXI ","M3N3FDYI ", & + "M3N3FDZI ","M3N3FIXI ","M3N3FIYI ","M3N3FIZI ","M3N3FMGXI","M3N3FMGYI","M3N3FMGZI", & + "M3N3MAFXI","M3N3MAFYI","M3N3MAFZI","M3N3MAGXI","M3N3MAGYI","M3N3MAGZI","M3N3MBFXI", & + "M3N3MBFYI","M3N3MBFZI","M3N3MBXI ","M3N3MBYI ","M3N3MBZI ","M3N3MMGXI","M3N3MMGYI", & + "M3N3MMGZI","M3N3STAXI","M3N3STAYI","M3N3STAZI","M3N3STVXI","M3N3STVYI","M3N3STVZI", & + "M3N3VXI ","M3N3VYI ","M3N3VZI ","M3N4AXI ","M3N4AYI ","M3N4AZI ","M3N4DYNP ", & + "M3N4FAFXI","M3N4FAFYI","M3N4FAFZI","M3N4FAGXI","M3N4FAGYI","M3N4FAGZI","M3N4FAMXI", & + "M3N4FAMYI","M3N4FAMZI","M3N4FBFXI","M3N4FBFYI","M3N4FBFZI","M3N4FBXI ","M3N4FBYI ", & + "M3N4FBZI ","M3N4FDXI ","M3N4FDYI "/) + ValidParamAry(1501:2000) = (/ & + "M3N4FDZI ","M3N4FIXI ","M3N4FIYI ","M3N4FIZI ","M3N4FMGXI","M3N4FMGYI","M3N4FMGZI", & + "M3N4MAFXI","M3N4MAFYI","M3N4MAFZI","M3N4MAGXI","M3N4MAGYI","M3N4MAGZI","M3N4MBFXI", & + "M3N4MBFYI","M3N4MBFZI","M3N4MBXI ","M3N4MBYI ","M3N4MBZI ","M3N4MMGXI","M3N4MMGYI", & + "M3N4MMGZI","M3N4STAXI","M3N4STAYI","M3N4STAZI","M3N4STVXI","M3N4STVYI","M3N4STVZI", & + "M3N4VXI ","M3N4VYI ","M3N4VZI ","M3N5AXI ","M3N5AYI ","M3N5AZI ","M3N5DYNP ", & + "M3N5FAFXI","M3N5FAFYI","M3N5FAFZI","M3N5FAGXI","M3N5FAGYI","M3N5FAGZI","M3N5FAMXI", & + "M3N5FAMYI","M3N5FAMZI","M3N5FBFXI","M3N5FBFYI","M3N5FBFZI","M3N5FBXI ","M3N5FBYI ", & + "M3N5FBZI ","M3N5FDXI ","M3N5FDYI ","M3N5FDZI ","M3N5FIXI ","M3N5FIYI ","M3N5FIZI ", & + "M3N5FMGXI","M3N5FMGYI","M3N5FMGZI","M3N5MAFXI","M3N5MAFYI","M3N5MAFZI","M3N5MAGXI", & + "M3N5MAGYI","M3N5MAGZI","M3N5MBFXI","M3N5MBFYI","M3N5MBFZI","M3N5MBXI ","M3N5MBYI ", & + "M3N5MBZI ","M3N5MMGXI","M3N5MMGYI","M3N5MMGZI","M3N5STAXI","M3N5STAYI","M3N5STAZI", & + "M3N5STVXI","M3N5STVYI","M3N5STVZI","M3N5VXI ","M3N5VYI ","M3N5VZI ","M3N6AXI ", & + "M3N6AYI ","M3N6AZI ","M3N6DYNP ","M3N6FAFXI","M3N6FAFYI","M3N6FAFZI","M3N6FAGXI", & + "M3N6FAGYI","M3N6FAGZI","M3N6FAMXI","M3N6FAMYI","M3N6FAMZI","M3N6FBFXI","M3N6FBFYI", & + "M3N6FBFZI","M3N6FBXI ","M3N6FBYI ","M3N6FBZI ","M3N6FDXI ","M3N6FDYI ","M3N6FDZI ", & + "M3N6FIXI ","M3N6FIYI ","M3N6FIZI ","M3N6FMGXI","M3N6FMGYI","M3N6FMGZI","M3N6MAFXI", & + "M3N6MAFYI","M3N6MAFZI","M3N6MAGXI","M3N6MAGYI","M3N6MAGZI","M3N6MBFXI","M3N6MBFYI", & + "M3N6MBFZI","M3N6MBXI ","M3N6MBYI ","M3N6MBZI ","M3N6MMGXI","M3N6MMGYI","M3N6MMGZI", & + "M3N6STAXI","M3N6STAYI","M3N6STAZI","M3N6STVXI","M3N6STVYI","M3N6STVZI","M3N6VXI ", & + "M3N6VYI ","M3N6VZI ","M3N7AXI ","M3N7AYI ","M3N7AZI ","M3N7DYNP ","M3N7FAFXI", & + "M3N7FAFYI","M3N7FAFZI","M3N7FAGXI","M3N7FAGYI","M3N7FAGZI","M3N7FAMXI","M3N7FAMYI", & + "M3N7FAMZI","M3N7FBFXI","M3N7FBFYI","M3N7FBFZI","M3N7FBXI ","M3N7FBYI ","M3N7FBZI ", & + "M3N7FDXI ","M3N7FDYI ","M3N7FDZI ","M3N7FIXI ","M3N7FIYI ","M3N7FIZI ","M3N7FMGXI", & + "M3N7FMGYI","M3N7FMGZI","M3N7MAFXI","M3N7MAFYI","M3N7MAFZI","M3N7MAGXI","M3N7MAGYI", & + "M3N7MAGZI","M3N7MBFXI","M3N7MBFYI","M3N7MBFZI","M3N7MBXI ","M3N7MBYI ","M3N7MBZI ", & + "M3N7MMGXI","M3N7MMGYI","M3N7MMGZI","M3N7STAXI","M3N7STAYI","M3N7STAZI","M3N7STVXI", & + "M3N7STVYI","M3N7STVZI","M3N7VXI ","M3N7VYI ","M3N7VZI ","M3N8AXI ","M3N8AYI ", & + "M3N8AZI ","M3N8DYNP ","M3N8FAFXI","M3N8FAFYI","M3N8FAFZI","M3N8FAGXI","M3N8FAGYI", & + "M3N8FAGZI","M3N8FAMXI","M3N8FAMYI","M3N8FAMZI","M3N8FBFXI","M3N8FBFYI","M3N8FBFZI", & + "M3N8FBXI ","M3N8FBYI ","M3N8FBZI ","M3N8FDXI ","M3N8FDYI ","M3N8FDZI ","M3N8FIXI ", & + "M3N8FIYI ","M3N8FIZI ","M3N8FMGXI","M3N8FMGYI","M3N8FMGZI","M3N8MAFXI","M3N8MAFYI", & + "M3N8MAFZI","M3N8MAGXI","M3N8MAGYI","M3N8MAGZI","M3N8MBFXI","M3N8MBFYI","M3N8MBFZI", & + "M3N8MBXI ","M3N8MBYI ","M3N8MBZI ","M3N8MMGXI","M3N8MMGYI","M3N8MMGZI","M3N8STAXI", & + "M3N8STAYI","M3N8STAZI","M3N8STVXI","M3N8STVYI","M3N8STVZI","M3N8VXI ","M3N8VYI ", & + "M3N8VZI ","M3N9AXI ","M3N9AYI ","M3N9AZI ","M3N9DYNP ","M3N9FAFXI","M3N9FAFYI", & + "M3N9FAFZI","M3N9FAGXI","M3N9FAGYI","M3N9FAGZI","M3N9FAMXI","M3N9FAMYI","M3N9FAMZI", & + "M3N9FBFXI","M3N9FBFYI","M3N9FBFZI","M3N9FBXI ","M3N9FBYI ","M3N9FBZI ","M3N9FDXI ", & + "M3N9FDYI ","M3N9FDZI ","M3N9FIXI ","M3N9FIYI ","M3N9FIZI ","M3N9FMGXI","M3N9FMGYI", & + "M3N9FMGZI","M3N9MAFXI","M3N9MAFYI","M3N9MAFZI","M3N9MAGXI","M3N9MAGYI","M3N9MAGZI", & + "M3N9MBFXI","M3N9MBFYI","M3N9MBFZI","M3N9MBXI ","M3N9MBYI ","M3N9MBZI ","M3N9MMGXI", & + "M3N9MMGYI","M3N9MMGZI","M3N9STAXI","M3N9STAYI","M3N9STAZI","M3N9STVXI","M3N9STVYI", & + "M3N9STVZI","M3N9VXI ","M3N9VYI ","M3N9VZI ","M4N1AXI ","M4N1AYI ","M4N1AZI ", & + "M4N1DYNP ","M4N1FAFXI","M4N1FAFYI","M4N1FAFZI","M4N1FAGXI","M4N1FAGYI","M4N1FAGZI", & + "M4N1FAMXI","M4N1FAMYI","M4N1FAMZI","M4N1FBFXI","M4N1FBFYI","M4N1FBFZI","M4N1FBXI ", & + "M4N1FBYI ","M4N1FBZI ","M4N1FDXI ","M4N1FDYI ","M4N1FDZI ","M4N1FIXI ","M4N1FIYI ", & + "M4N1FIZI ","M4N1FMGXI","M4N1FMGYI","M4N1FMGZI","M4N1MAFXI","M4N1MAFYI","M4N1MAFZI", & + "M4N1MAGXI","M4N1MAGYI","M4N1MAGZI","M4N1MBFXI","M4N1MBFYI","M4N1MBFZI","M4N1MBXI ", & + "M4N1MBYI ","M4N1MBZI ","M4N1MMGXI","M4N1MMGYI","M4N1MMGZI","M4N1STAXI","M4N1STAYI", & + "M4N1STAZI","M4N1STVXI","M4N1STVYI","M4N1STVZI","M4N1VXI ","M4N1VYI ","M4N1VZI ", & + "M4N2AXI ","M4N2AYI ","M4N2AZI ","M4N2DYNP ","M4N2FAFXI","M4N2FAFYI","M4N2FAFZI", & + "M4N2FAGXI","M4N2FAGYI","M4N2FAGZI","M4N2FAMXI","M4N2FAMYI","M4N2FAMZI","M4N2FBFXI", & + "M4N2FBFYI","M4N2FBFZI","M4N2FBXI ","M4N2FBYI ","M4N2FBZI ","M4N2FDXI ","M4N2FDYI ", & + "M4N2FDZI ","M4N2FIXI ","M4N2FIYI ","M4N2FIZI ","M4N2FMGXI","M4N2FMGYI","M4N2FMGZI", & + "M4N2MAFXI","M4N2MAFYI","M4N2MAFZI","M4N2MAGXI","M4N2MAGYI","M4N2MAGZI","M4N2MBFXI", & + "M4N2MBFYI","M4N2MBFZI","M4N2MBXI ","M4N2MBYI ","M4N2MBZI ","M4N2MMGXI","M4N2MMGYI", & + "M4N2MMGZI","M4N2STAXI","M4N2STAYI","M4N2STAZI","M4N2STVXI","M4N2STVYI","M4N2STVZI", & + "M4N2VXI ","M4N2VYI ","M4N2VZI ","M4N3AXI ","M4N3AYI ","M4N3AZI ","M4N3DYNP ", & + "M4N3FAFXI","M4N3FAFYI","M4N3FAFZI","M4N3FAGXI","M4N3FAGYI","M4N3FAGZI","M4N3FAMXI", & + "M4N3FAMYI","M4N3FAMZI","M4N3FBFXI","M4N3FBFYI","M4N3FBFZI","M4N3FBXI ","M4N3FBYI ", & + "M4N3FBZI ","M4N3FDXI ","M4N3FDYI ","M4N3FDZI ","M4N3FIXI ","M4N3FIYI ","M4N3FIZI ", & + "M4N3FMGXI","M4N3FMGYI","M4N3FMGZI","M4N3MAFXI","M4N3MAFYI","M4N3MAFZI","M4N3MAGXI", & + "M4N3MAGYI","M4N3MAGZI","M4N3MBFXI","M4N3MBFYI","M4N3MBFZI","M4N3MBXI ","M4N3MBYI ", & + "M4N3MBZI ","M4N3MMGXI","M4N3MMGYI","M4N3MMGZI","M4N3STAXI","M4N3STAYI","M4N3STAZI", & + "M4N3STVXI","M4N3STVYI","M4N3STVZI","M4N3VXI ","M4N3VYI ","M4N3VZI ","M4N4AXI ", & + "M4N4AYI ","M4N4AZI ","M4N4DYNP ","M4N4FAFXI","M4N4FAFYI","M4N4FAFZI","M4N4FAGXI", & + "M4N4FAGYI","M4N4FAGZI","M4N4FAMXI","M4N4FAMYI","M4N4FAMZI","M4N4FBFXI","M4N4FBFYI", & + "M4N4FBFZI","M4N4FBXI ","M4N4FBYI ","M4N4FBZI ","M4N4FDXI ","M4N4FDYI ","M4N4FDZI ", & + "M4N4FIXI ","M4N4FIYI ","M4N4FIZI ","M4N4FMGXI","M4N4FMGYI","M4N4FMGZI","M4N4MAFXI", & + "M4N4MAFYI","M4N4MAFZI","M4N4MAGXI","M4N4MAGYI","M4N4MAGZI","M4N4MBFXI","M4N4MBFYI", & + "M4N4MBFZI","M4N4MBXI ","M4N4MBYI ","M4N4MBZI ","M4N4MMGXI","M4N4MMGYI","M4N4MMGZI", & + "M4N4STAXI","M4N4STAYI","M4N4STAZI","M4N4STVXI","M4N4STVYI","M4N4STVZI","M4N4VXI ", & + "M4N4VYI ","M4N4VZI ","M4N5AXI "/) + ValidParamAry(2001:2500) = (/ & + "M4N5AYI ","M4N5AZI ","M4N5DYNP ","M4N5FAFXI","M4N5FAFYI","M4N5FAFZI","M4N5FAGXI", & + "M4N5FAGYI","M4N5FAGZI","M4N5FAMXI","M4N5FAMYI","M4N5FAMZI","M4N5FBFXI","M4N5FBFYI", & + "M4N5FBFZI","M4N5FBXI ","M4N5FBYI ","M4N5FBZI ","M4N5FDXI ","M4N5FDYI ","M4N5FDZI ", & + "M4N5FIXI ","M4N5FIYI ","M4N5FIZI ","M4N5FMGXI","M4N5FMGYI","M4N5FMGZI","M4N5MAFXI", & + "M4N5MAFYI","M4N5MAFZI","M4N5MAGXI","M4N5MAGYI","M4N5MAGZI","M4N5MBFXI","M4N5MBFYI", & + "M4N5MBFZI","M4N5MBXI ","M4N5MBYI ","M4N5MBZI ","M4N5MMGXI","M4N5MMGYI","M4N5MMGZI", & + "M4N5STAXI","M4N5STAYI","M4N5STAZI","M4N5STVXI","M4N5STVYI","M4N5STVZI","M4N5VXI ", & + "M4N5VYI ","M4N5VZI ","M4N6AXI ","M4N6AYI ","M4N6AZI ","M4N6DYNP ","M4N6FAFXI", & + "M4N6FAFYI","M4N6FAFZI","M4N6FAGXI","M4N6FAGYI","M4N6FAGZI","M4N6FAMXI","M4N6FAMYI", & + "M4N6FAMZI","M4N6FBFXI","M4N6FBFYI","M4N6FBFZI","M4N6FBXI ","M4N6FBYI ","M4N6FBZI ", & + "M4N6FDXI ","M4N6FDYI ","M4N6FDZI ","M4N6FIXI ","M4N6FIYI ","M4N6FIZI ","M4N6FMGXI", & + "M4N6FMGYI","M4N6FMGZI","M4N6MAFXI","M4N6MAFYI","M4N6MAFZI","M4N6MAGXI","M4N6MAGYI", & + "M4N6MAGZI","M4N6MBFXI","M4N6MBFYI","M4N6MBFZI","M4N6MBXI ","M4N6MBYI ","M4N6MBZI ", & + "M4N6MMGXI","M4N6MMGYI","M4N6MMGZI","M4N6STAXI","M4N6STAYI","M4N6STAZI","M4N6STVXI", & + "M4N6STVYI","M4N6STVZI","M4N6VXI ","M4N6VYI ","M4N6VZI ","M4N7AXI ","M4N7AYI ", & + "M4N7AZI ","M4N7DYNP ","M4N7FAFXI","M4N7FAFYI","M4N7FAFZI","M4N7FAGXI","M4N7FAGYI", & + "M4N7FAGZI","M4N7FAMXI","M4N7FAMYI","M4N7FAMZI","M4N7FBFXI","M4N7FBFYI","M4N7FBFZI", & + "M4N7FBXI ","M4N7FBYI ","M4N7FBZI ","M4N7FDXI ","M4N7FDYI ","M4N7FDZI ","M4N7FIXI ", & + "M4N7FIYI ","M4N7FIZI ","M4N7FMGXI","M4N7FMGYI","M4N7FMGZI","M4N7MAFXI","M4N7MAFYI", & + "M4N7MAFZI","M4N7MAGXI","M4N7MAGYI","M4N7MAGZI","M4N7MBFXI","M4N7MBFYI","M4N7MBFZI", & + "M4N7MBXI ","M4N7MBYI ","M4N7MBZI ","M4N7MMGXI","M4N7MMGYI","M4N7MMGZI","M4N7STAXI", & + "M4N7STAYI","M4N7STAZI","M4N7STVXI","M4N7STVYI","M4N7STVZI","M4N7VXI ","M4N7VYI ", & + "M4N7VZI ","M4N8AXI ","M4N8AYI ","M4N8AZI ","M4N8DYNP ","M4N8FAFXI","M4N8FAFYI", & + "M4N8FAFZI","M4N8FAGXI","M4N8FAGYI","M4N8FAGZI","M4N8FAMXI","M4N8FAMYI","M4N8FAMZI", & + "M4N8FBFXI","M4N8FBFYI","M4N8FBFZI","M4N8FBXI ","M4N8FBYI ","M4N8FBZI ","M4N8FDXI ", & + "M4N8FDYI ","M4N8FDZI ","M4N8FIXI ","M4N8FIYI ","M4N8FIZI ","M4N8FMGXI","M4N8FMGYI", & + "M4N8FMGZI","M4N8MAFXI","M4N8MAFYI","M4N8MAFZI","M4N8MAGXI","M4N8MAGYI","M4N8MAGZI", & + "M4N8MBFXI","M4N8MBFYI","M4N8MBFZI","M4N8MBXI ","M4N8MBYI ","M4N8MBZI ","M4N8MMGXI", & + "M4N8MMGYI","M4N8MMGZI","M4N8STAXI","M4N8STAYI","M4N8STAZI","M4N8STVXI","M4N8STVYI", & + "M4N8STVZI","M4N8VXI ","M4N8VYI ","M4N8VZI ","M4N9AXI ","M4N9AYI ","M4N9AZI ", & + "M4N9DYNP ","M4N9FAFXI","M4N9FAFYI","M4N9FAFZI","M4N9FAGXI","M4N9FAGYI","M4N9FAGZI", & + "M4N9FAMXI","M4N9FAMYI","M4N9FAMZI","M4N9FBFXI","M4N9FBFYI","M4N9FBFZI","M4N9FBXI ", & + "M4N9FBYI ","M4N9FBZI ","M4N9FDXI ","M4N9FDYI ","M4N9FDZI ","M4N9FIXI ","M4N9FIYI ", & + "M4N9FIZI ","M4N9FMGXI","M4N9FMGYI","M4N9FMGZI","M4N9MAFXI","M4N9MAFYI","M4N9MAFZI", & + "M4N9MAGXI","M4N9MAGYI","M4N9MAGZI","M4N9MBFXI","M4N9MBFYI","M4N9MBFZI","M4N9MBXI ", & + "M4N9MBYI ","M4N9MBZI ","M4N9MMGXI","M4N9MMGYI","M4N9MMGZI","M4N9STAXI","M4N9STAYI", & + "M4N9STAZI","M4N9STVXI","M4N9STVYI","M4N9STVZI","M4N9VXI ","M4N9VYI ","M4N9VZI ", & + "M5N1AXI ","M5N1AYI ","M5N1AZI ","M5N1DYNP ","M5N1FAFXI","M5N1FAFYI","M5N1FAFZI", & + "M5N1FAGXI","M5N1FAGYI","M5N1FAGZI","M5N1FAMXI","M5N1FAMYI","M5N1FAMZI","M5N1FBFXI", & + "M5N1FBFYI","M5N1FBFZI","M5N1FBXI ","M5N1FBYI ","M5N1FBZI ","M5N1FDXI ","M5N1FDYI ", & + "M5N1FDZI ","M5N1FIXI ","M5N1FIYI ","M5N1FIZI ","M5N1FMGXI","M5N1FMGYI","M5N1FMGZI", & + "M5N1MAFXI","M5N1MAFYI","M5N1MAFZI","M5N1MAGXI","M5N1MAGYI","M5N1MAGZI","M5N1MBFXI", & + "M5N1MBFYI","M5N1MBFZI","M5N1MBXI ","M5N1MBYI ","M5N1MBZI ","M5N1MMGXI","M5N1MMGYI", & + "M5N1MMGZI","M5N1STAXI","M5N1STAYI","M5N1STAZI","M5N1STVXI","M5N1STVYI","M5N1STVZI", & + "M5N1VXI ","M5N1VYI ","M5N1VZI ","M5N2AXI ","M5N2AYI ","M5N2AZI ","M5N2DYNP ", & + "M5N2FAFXI","M5N2FAFYI","M5N2FAFZI","M5N2FAGXI","M5N2FAGYI","M5N2FAGZI","M5N2FAMXI", & + "M5N2FAMYI","M5N2FAMZI","M5N2FBFXI","M5N2FBFYI","M5N2FBFZI","M5N2FBXI ","M5N2FBYI ", & + "M5N2FBZI ","M5N2FDXI ","M5N2FDYI ","M5N2FDZI ","M5N2FIXI ","M5N2FIYI ","M5N2FIZI ", & + "M5N2FMGXI","M5N2FMGYI","M5N2FMGZI","M5N2MAFXI","M5N2MAFYI","M5N2MAFZI","M5N2MAGXI", & + "M5N2MAGYI","M5N2MAGZI","M5N2MBFXI","M5N2MBFYI","M5N2MBFZI","M5N2MBXI ","M5N2MBYI ", & + "M5N2MBZI ","M5N2MMGXI","M5N2MMGYI","M5N2MMGZI","M5N2STAXI","M5N2STAYI","M5N2STAZI", & + "M5N2STVXI","M5N2STVYI","M5N2STVZI","M5N2VXI ","M5N2VYI ","M5N2VZI ","M5N3AXI ", & + "M5N3AYI ","M5N3AZI ","M5N3DYNP ","M5N3FAFXI","M5N3FAFYI","M5N3FAFZI","M5N3FAGXI", & + "M5N3FAGYI","M5N3FAGZI","M5N3FAMXI","M5N3FAMYI","M5N3FAMZI","M5N3FBFXI","M5N3FBFYI", & + "M5N3FBFZI","M5N3FBXI ","M5N3FBYI ","M5N3FBZI ","M5N3FDXI ","M5N3FDYI ","M5N3FDZI ", & + "M5N3FIXI ","M5N3FIYI ","M5N3FIZI ","M5N3FMGXI","M5N3FMGYI","M5N3FMGZI","M5N3MAFXI", & + "M5N3MAFYI","M5N3MAFZI","M5N3MAGXI","M5N3MAGYI","M5N3MAGZI","M5N3MBFXI","M5N3MBFYI", & + "M5N3MBFZI","M5N3MBXI ","M5N3MBYI ","M5N3MBZI ","M5N3MMGXI","M5N3MMGYI","M5N3MMGZI", & + "M5N3STAXI","M5N3STAYI","M5N3STAZI","M5N3STVXI","M5N3STVYI","M5N3STVZI","M5N3VXI ", & + "M5N3VYI ","M5N3VZI ","M5N4AXI ","M5N4AYI ","M5N4AZI ","M5N4DYNP ","M5N4FAFXI", & + "M5N4FAFYI","M5N4FAFZI","M5N4FAGXI","M5N4FAGYI","M5N4FAGZI","M5N4FAMXI","M5N4FAMYI", & + "M5N4FAMZI","M5N4FBFXI","M5N4FBFYI","M5N4FBFZI","M5N4FBXI ","M5N4FBYI ","M5N4FBZI ", & + "M5N4FDXI ","M5N4FDYI ","M5N4FDZI ","M5N4FIXI ","M5N4FIYI ","M5N4FIZI ","M5N4FMGXI", & + "M5N4FMGYI","M5N4FMGZI","M5N4MAFXI","M5N4MAFYI","M5N4MAFZI","M5N4MAGXI","M5N4MAGYI", & + "M5N4MAGZI","M5N4MBFXI","M5N4MBFYI","M5N4MBFZI","M5N4MBXI ","M5N4MBYI ","M5N4MBZI ", & + "M5N4MMGXI","M5N4MMGYI","M5N4MMGZI","M5N4STAXI","M5N4STAYI","M5N4STAZI","M5N4STVXI", & + "M5N4STVYI","M5N4STVZI","M5N4VXI ","M5N4VYI ","M5N4VZI ","M5N5AXI ","M5N5AYI ", & + "M5N5AZI ","M5N5DYNP ","M5N5FAFXI","M5N5FAFYI","M5N5FAFZI","M5N5FAGXI","M5N5FAGYI", & + "M5N5FAGZI","M5N5FAMXI","M5N5FAMYI","M5N5FAMZI","M5N5FBFXI","M5N5FBFYI","M5N5FBFZI", & + "M5N5FBXI ","M5N5FBYI ","M5N5FBZI ","M5N5FDXI ","M5N5FDYI ","M5N5FDZI ","M5N5FIXI ", & + "M5N5FIYI ","M5N5FIZI ","M5N5FMGXI","M5N5FMGYI","M5N5FMGZI","M5N5MAFXI","M5N5MAFYI", & + "M5N5MAFZI","M5N5MAGXI","M5N5MAGYI"/) + ValidParamAry(2501:3000) = (/ & + "M5N5MAGZI","M5N5MBFXI","M5N5MBFYI","M5N5MBFZI","M5N5MBXI ","M5N5MBYI ","M5N5MBZI ", & + "M5N5MMGXI","M5N5MMGYI","M5N5MMGZI","M5N5STAXI","M5N5STAYI","M5N5STAZI","M5N5STVXI", & + "M5N5STVYI","M5N5STVZI","M5N5VXI ","M5N5VYI ","M5N5VZI ","M5N6AXI ","M5N6AYI ", & + "M5N6AZI ","M5N6DYNP ","M5N6FAFXI","M5N6FAFYI","M5N6FAFZI","M5N6FAGXI","M5N6FAGYI", & + "M5N6FAGZI","M5N6FAMXI","M5N6FAMYI","M5N6FAMZI","M5N6FBFXI","M5N6FBFYI","M5N6FBFZI", & + "M5N6FBXI ","M5N6FBYI ","M5N6FBZI ","M5N6FDXI ","M5N6FDYI ","M5N6FDZI ","M5N6FIXI ", & + "M5N6FIYI ","M5N6FIZI ","M5N6FMGXI","M5N6FMGYI","M5N6FMGZI","M5N6MAFXI","M5N6MAFYI", & + "M5N6MAFZI","M5N6MAGXI","M5N6MAGYI","M5N6MAGZI","M5N6MBFXI","M5N6MBFYI","M5N6MBFZI", & + "M5N6MBXI ","M5N6MBYI ","M5N6MBZI ","M5N6MMGXI","M5N6MMGYI","M5N6MMGZI","M5N6STAXI", & + "M5N6STAYI","M5N6STAZI","M5N6STVXI","M5N6STVYI","M5N6STVZI","M5N6VXI ","M5N6VYI ", & + "M5N6VZI ","M5N7AXI ","M5N7AYI ","M5N7AZI ","M5N7DYNP ","M5N7FAFXI","M5N7FAFYI", & + "M5N7FAFZI","M5N7FAGXI","M5N7FAGYI","M5N7FAGZI","M5N7FAMXI","M5N7FAMYI","M5N7FAMZI", & + "M5N7FBFXI","M5N7FBFYI","M5N7FBFZI","M5N7FBXI ","M5N7FBYI ","M5N7FBZI ","M5N7FDXI ", & + "M5N7FDYI ","M5N7FDZI ","M5N7FIXI ","M5N7FIYI ","M5N7FIZI ","M5N7FMGXI","M5N7FMGYI", & + "M5N7FMGZI","M5N7MAFXI","M5N7MAFYI","M5N7MAFZI","M5N7MAGXI","M5N7MAGYI","M5N7MAGZI", & + "M5N7MBFXI","M5N7MBFYI","M5N7MBFZI","M5N7MBXI ","M5N7MBYI ","M5N7MBZI ","M5N7MMGXI", & + "M5N7MMGYI","M5N7MMGZI","M5N7STAXI","M5N7STAYI","M5N7STAZI","M5N7STVXI","M5N7STVYI", & + "M5N7STVZI","M5N7VXI ","M5N7VYI ","M5N7VZI ","M5N8AXI ","M5N8AYI ","M5N8AZI ", & + "M5N8DYNP ","M5N8FAFXI","M5N8FAFYI","M5N8FAFZI","M5N8FAGXI","M5N8FAGYI","M5N8FAGZI", & + "M5N8FAMXI","M5N8FAMYI","M5N8FAMZI","M5N8FBFXI","M5N8FBFYI","M5N8FBFZI","M5N8FBXI ", & + "M5N8FBYI ","M5N8FBZI ","M5N8FDXI ","M5N8FDYI ","M5N8FDZI ","M5N8FIXI ","M5N8FIYI ", & + "M5N8FIZI ","M5N8FMGXI","M5N8FMGYI","M5N8FMGZI","M5N8MAFXI","M5N8MAFYI","M5N8MAFZI", & + "M5N8MAGXI","M5N8MAGYI","M5N8MAGZI","M5N8MBFXI","M5N8MBFYI","M5N8MBFZI","M5N8MBXI ", & + "M5N8MBYI ","M5N8MBZI ","M5N8MMGXI","M5N8MMGYI","M5N8MMGZI","M5N8STAXI","M5N8STAYI", & + "M5N8STAZI","M5N8STVXI","M5N8STVYI","M5N8STVZI","M5N8VXI ","M5N8VYI ","M5N8VZI ", & + "M5N9AXI ","M5N9AYI ","M5N9AZI ","M5N9DYNP ","M5N9FAFXI","M5N9FAFYI","M5N9FAFZI", & + "M5N9FAGXI","M5N9FAGYI","M5N9FAGZI","M5N9FAMXI","M5N9FAMYI","M5N9FAMZI","M5N9FBFXI", & + "M5N9FBFYI","M5N9FBFZI","M5N9FBXI ","M5N9FBYI ","M5N9FBZI ","M5N9FDXI ","M5N9FDYI ", & + "M5N9FDZI ","M5N9FIXI ","M5N9FIYI ","M5N9FIZI ","M5N9FMGXI","M5N9FMGYI","M5N9FMGZI", & + "M5N9MAFXI","M5N9MAFYI","M5N9MAFZI","M5N9MAGXI","M5N9MAGYI","M5N9MAGZI","M5N9MBFXI", & + "M5N9MBFYI","M5N9MBFZI","M5N9MBXI ","M5N9MBYI ","M5N9MBZI ","M5N9MMGXI","M5N9MMGYI", & + "M5N9MMGZI","M5N9STAXI","M5N9STAYI","M5N9STAZI","M5N9STVXI","M5N9STVYI","M5N9STVZI", & + "M5N9VXI ","M5N9VYI ","M5N9VZI ","M6N1AXI ","M6N1AYI ","M6N1AZI ","M6N1DYNP ", & + "M6N1FAFXI","M6N1FAFYI","M6N1FAFZI","M6N1FAGXI","M6N1FAGYI","M6N1FAGZI","M6N1FAMXI", & + "M6N1FAMYI","M6N1FAMZI","M6N1FBFXI","M6N1FBFYI","M6N1FBFZI","M6N1FBXI ","M6N1FBYI ", & + "M6N1FBZI ","M6N1FDXI ","M6N1FDYI ","M6N1FDZI ","M6N1FIXI ","M6N1FIYI ","M6N1FIZI ", & + "M6N1FMGXI","M6N1FMGYI","M6N1FMGZI","M6N1MAFXI","M6N1MAFYI","M6N1MAFZI","M6N1MAGXI", & + "M6N1MAGYI","M6N1MAGZI","M6N1MBFXI","M6N1MBFYI","M6N1MBFZI","M6N1MBXI ","M6N1MBYI ", & + "M6N1MBZI ","M6N1MMGXI","M6N1MMGYI","M6N1MMGZI","M6N1STAXI","M6N1STAYI","M6N1STAZI", & + "M6N1STVXI","M6N1STVYI","M6N1STVZI","M6N1VXI ","M6N1VYI ","M6N1VZI ","M6N2AXI ", & + "M6N2AYI ","M6N2AZI ","M6N2DYNP ","M6N2FAFXI","M6N2FAFYI","M6N2FAFZI","M6N2FAGXI", & + "M6N2FAGYI","M6N2FAGZI","M6N2FAMXI","M6N2FAMYI","M6N2FAMZI","M6N2FBFXI","M6N2FBFYI", & + "M6N2FBFZI","M6N2FBXI ","M6N2FBYI ","M6N2FBZI ","M6N2FDXI ","M6N2FDYI ","M6N2FDZI ", & + "M6N2FIXI ","M6N2FIYI ","M6N2FIZI ","M6N2FMGXI","M6N2FMGYI","M6N2FMGZI","M6N2MAFXI", & + "M6N2MAFYI","M6N2MAFZI","M6N2MAGXI","M6N2MAGYI","M6N2MAGZI","M6N2MBFXI","M6N2MBFYI", & + "M6N2MBFZI","M6N2MBXI ","M6N2MBYI ","M6N2MBZI ","M6N2MMGXI","M6N2MMGYI","M6N2MMGZI", & + "M6N2STAXI","M6N2STAYI","M6N2STAZI","M6N2STVXI","M6N2STVYI","M6N2STVZI","M6N2VXI ", & + "M6N2VYI ","M6N2VZI ","M6N3AXI ","M6N3AYI ","M6N3AZI ","M6N3DYNP ","M6N3FAFXI", & + "M6N3FAFYI","M6N3FAFZI","M6N3FAGXI","M6N3FAGYI","M6N3FAGZI","M6N3FAMXI","M6N3FAMYI", & + "M6N3FAMZI","M6N3FBFXI","M6N3FBFYI","M6N3FBFZI","M6N3FBXI ","M6N3FBYI ","M6N3FBZI ", & + "M6N3FDXI ","M6N3FDYI ","M6N3FDZI ","M6N3FIXI ","M6N3FIYI ","M6N3FIZI ","M6N3FMGXI", & + "M6N3FMGYI","M6N3FMGZI","M6N3MAFXI","M6N3MAFYI","M6N3MAFZI","M6N3MAGXI","M6N3MAGYI", & + "M6N3MAGZI","M6N3MBFXI","M6N3MBFYI","M6N3MBFZI","M6N3MBXI ","M6N3MBYI ","M6N3MBZI ", & + "M6N3MMGXI","M6N3MMGYI","M6N3MMGZI","M6N3STAXI","M6N3STAYI","M6N3STAZI","M6N3STVXI", & + "M6N3STVYI","M6N3STVZI","M6N3VXI ","M6N3VYI ","M6N3VZI ","M6N4AXI ","M6N4AYI ", & + "M6N4AZI ","M6N4DYNP ","M6N4FAFXI","M6N4FAFYI","M6N4FAFZI","M6N4FAGXI","M6N4FAGYI", & + "M6N4FAGZI","M6N4FAMXI","M6N4FAMYI","M6N4FAMZI","M6N4FBFXI","M6N4FBFYI","M6N4FBFZI", & + "M6N4FBXI ","M6N4FBYI ","M6N4FBZI ","M6N4FDXI ","M6N4FDYI ","M6N4FDZI ","M6N4FIXI ", & + "M6N4FIYI ","M6N4FIZI ","M6N4FMGXI","M6N4FMGYI","M6N4FMGZI","M6N4MAFXI","M6N4MAFYI", & + "M6N4MAFZI","M6N4MAGXI","M6N4MAGYI","M6N4MAGZI","M6N4MBFXI","M6N4MBFYI","M6N4MBFZI", & + "M6N4MBXI ","M6N4MBYI ","M6N4MBZI ","M6N4MMGXI","M6N4MMGYI","M6N4MMGZI","M6N4STAXI", & + "M6N4STAYI","M6N4STAZI","M6N4STVXI","M6N4STVYI","M6N4STVZI","M6N4VXI ","M6N4VYI ", & + "M6N4VZI ","M6N5AXI ","M6N5AYI ","M6N5AZI ","M6N5DYNP ","M6N5FAFXI","M6N5FAFYI", & + "M6N5FAFZI","M6N5FAGXI","M6N5FAGYI","M6N5FAGZI","M6N5FAMXI","M6N5FAMYI","M6N5FAMZI", & + "M6N5FBFXI","M6N5FBFYI","M6N5FBFZI","M6N5FBXI ","M6N5FBYI ","M6N5FBZI ","M6N5FDXI ", & + "M6N5FDYI ","M6N5FDZI ","M6N5FIXI ","M6N5FIYI ","M6N5FIZI ","M6N5FMGXI","M6N5FMGYI", & + "M6N5FMGZI","M6N5MAFXI","M6N5MAFYI","M6N5MAFZI","M6N5MAGXI","M6N5MAGYI","M6N5MAGZI", & + "M6N5MBFXI","M6N5MBFYI","M6N5MBFZI","M6N5MBXI ","M6N5MBYI ","M6N5MBZI ","M6N5MMGXI", & + "M6N5MMGYI","M6N5MMGZI","M6N5STAXI","M6N5STAYI","M6N5STAZI","M6N5STVXI","M6N5STVYI", & + "M6N5STVZI","M6N5VXI ","M6N5VYI ","M6N5VZI ","M6N6AXI ","M6N6AYI ","M6N6AZI ", & + "M6N6DYNP ","M6N6FAFXI","M6N6FAFYI","M6N6FAFZI","M6N6FAGXI","M6N6FAGYI","M6N6FAGZI", & + "M6N6FAMXI","M6N6FAMYI","M6N6FAMZI"/) + ValidParamAry(3001:3500) = (/ & + "M6N6FBFXI","M6N6FBFYI","M6N6FBFZI","M6N6FBXI ","M6N6FBYI ","M6N6FBZI ","M6N6FDXI ", & + "M6N6FDYI ","M6N6FDZI ","M6N6FIXI ","M6N6FIYI ","M6N6FIZI ","M6N6FMGXI","M6N6FMGYI", & + "M6N6FMGZI","M6N6MAFXI","M6N6MAFYI","M6N6MAFZI","M6N6MAGXI","M6N6MAGYI","M6N6MAGZI", & + "M6N6MBFXI","M6N6MBFYI","M6N6MBFZI","M6N6MBXI ","M6N6MBYI ","M6N6MBZI ","M6N6MMGXI", & + "M6N6MMGYI","M6N6MMGZI","M6N6STAXI","M6N6STAYI","M6N6STAZI","M6N6STVXI","M6N6STVYI", & + "M6N6STVZI","M6N6VXI ","M6N6VYI ","M6N6VZI ","M6N7AXI ","M6N7AYI ","M6N7AZI ", & + "M6N7DYNP ","M6N7FAFXI","M6N7FAFYI","M6N7FAFZI","M6N7FAGXI","M6N7FAGYI","M6N7FAGZI", & + "M6N7FAMXI","M6N7FAMYI","M6N7FAMZI","M6N7FBFXI","M6N7FBFYI","M6N7FBFZI","M6N7FBXI ", & + "M6N7FBYI ","M6N7FBZI ","M6N7FDXI ","M6N7FDYI ","M6N7FDZI ","M6N7FIXI ","M6N7FIYI ", & + "M6N7FIZI ","M6N7FMGXI","M6N7FMGYI","M6N7FMGZI","M6N7MAFXI","M6N7MAFYI","M6N7MAFZI", & + "M6N7MAGXI","M6N7MAGYI","M6N7MAGZI","M6N7MBFXI","M6N7MBFYI","M6N7MBFZI","M6N7MBXI ", & + "M6N7MBYI ","M6N7MBZI ","M6N7MMGXI","M6N7MMGYI","M6N7MMGZI","M6N7STAXI","M6N7STAYI", & + "M6N7STAZI","M6N7STVXI","M6N7STVYI","M6N7STVZI","M6N7VXI ","M6N7VYI ","M6N7VZI ", & + "M6N8AXI ","M6N8AYI ","M6N8AZI ","M6N8DYNP ","M6N8FAFXI","M6N8FAFYI","M6N8FAFZI", & + "M6N8FAGXI","M6N8FAGYI","M6N8FAGZI","M6N8FAMXI","M6N8FAMYI","M6N8FAMZI","M6N8FBFXI", & + "M6N8FBFYI","M6N8FBFZI","M6N8FBXI ","M6N8FBYI ","M6N8FBZI ","M6N8FDXI ","M6N8FDYI ", & + "M6N8FDZI ","M6N8FIXI ","M6N8FIYI ","M6N8FIZI ","M6N8FMGXI","M6N8FMGYI","M6N8FMGZI", & + "M6N8MAFXI","M6N8MAFYI","M6N8MAFZI","M6N8MAGXI","M6N8MAGYI","M6N8MAGZI","M6N8MBFXI", & + "M6N8MBFYI","M6N8MBFZI","M6N8MBXI ","M6N8MBYI ","M6N8MBZI ","M6N8MMGXI","M6N8MMGYI", & + "M6N8MMGZI","M6N8STAXI","M6N8STAYI","M6N8STAZI","M6N8STVXI","M6N8STVYI","M6N8STVZI", & + "M6N8VXI ","M6N8VYI ","M6N8VZI ","M6N9AXI ","M6N9AYI ","M6N9AZI ","M6N9DYNP ", & + "M6N9FAFXI","M6N9FAFYI","M6N9FAFZI","M6N9FAGXI","M6N9FAGYI","M6N9FAGZI","M6N9FAMXI", & + "M6N9FAMYI","M6N9FAMZI","M6N9FBFXI","M6N9FBFYI","M6N9FBFZI","M6N9FBXI ","M6N9FBYI ", & + "M6N9FBZI ","M6N9FDXI ","M6N9FDYI ","M6N9FDZI ","M6N9FIXI ","M6N9FIYI ","M6N9FIZI ", & + "M6N9FMGXI","M6N9FMGYI","M6N9FMGZI","M6N9MAFXI","M6N9MAFYI","M6N9MAFZI","M6N9MAGXI", & + "M6N9MAGYI","M6N9MAGZI","M6N9MBFXI","M6N9MBFYI","M6N9MBFZI","M6N9MBXI ","M6N9MBYI ", & + "M6N9MBZI ","M6N9MMGXI","M6N9MMGYI","M6N9MMGZI","M6N9STAXI","M6N9STAYI","M6N9STAZI", & + "M6N9STVXI","M6N9STVYI","M6N9STVZI","M6N9VXI ","M6N9VYI ","M6N9VZI ","M7N1AXI ", & + "M7N1AYI ","M7N1AZI ","M7N1DYNP ","M7N1FAFXI","M7N1FAFYI","M7N1FAFZI","M7N1FAGXI", & + "M7N1FAGYI","M7N1FAGZI","M7N1FAMXI","M7N1FAMYI","M7N1FAMZI","M7N1FBFXI","M7N1FBFYI", & + "M7N1FBFZI","M7N1FBXI ","M7N1FBYI ","M7N1FBZI ","M7N1FDXI ","M7N1FDYI ","M7N1FDZI ", & + "M7N1FIXI ","M7N1FIYI ","M7N1FIZI ","M7N1FMGXI","M7N1FMGYI","M7N1FMGZI","M7N1MAFXI", & + "M7N1MAFYI","M7N1MAFZI","M7N1MAGXI","M7N1MAGYI","M7N1MAGZI","M7N1MBFXI","M7N1MBFYI", & + "M7N1MBFZI","M7N1MBXI ","M7N1MBYI ","M7N1MBZI ","M7N1MMGXI","M7N1MMGYI","M7N1MMGZI", & + "M7N1STAXI","M7N1STAYI","M7N1STAZI","M7N1STVXI","M7N1STVYI","M7N1STVZI","M7N1VXI ", & + "M7N1VYI ","M7N1VZI ","M7N2AXI ","M7N2AYI ","M7N2AZI ","M7N2DYNP ","M7N2FAFXI", & + "M7N2FAFYI","M7N2FAFZI","M7N2FAGXI","M7N2FAGYI","M7N2FAGZI","M7N2FAMXI","M7N2FAMYI", & + "M7N2FAMZI","M7N2FBFXI","M7N2FBFYI","M7N2FBFZI","M7N2FBXI ","M7N2FBYI ","M7N2FBZI ", & + "M7N2FDXI ","M7N2FDYI ","M7N2FDZI ","M7N2FIXI ","M7N2FIYI ","M7N2FIZI ","M7N2FMGXI", & + "M7N2FMGYI","M7N2FMGZI","M7N2MAFXI","M7N2MAFYI","M7N2MAFZI","M7N2MAGXI","M7N2MAGYI", & + "M7N2MAGZI","M7N2MBFXI","M7N2MBFYI","M7N2MBFZI","M7N2MBXI ","M7N2MBYI ","M7N2MBZI ", & + "M7N2MMGXI","M7N2MMGYI","M7N2MMGZI","M7N2STAXI","M7N2STAYI","M7N2STAZI","M7N2STVXI", & + "M7N2STVYI","M7N2STVZI","M7N2VXI ","M7N2VYI ","M7N2VZI ","M7N3AXI ","M7N3AYI ", & + "M7N3AZI ","M7N3DYNP ","M7N3FAFXI","M7N3FAFYI","M7N3FAFZI","M7N3FAGXI","M7N3FAGYI", & + "M7N3FAGZI","M7N3FAMXI","M7N3FAMYI","M7N3FAMZI","M7N3FBFXI","M7N3FBFYI","M7N3FBFZI", & + "M7N3FBXI ","M7N3FBYI ","M7N3FBZI ","M7N3FDXI ","M7N3FDYI ","M7N3FDZI ","M7N3FIXI ", & + "M7N3FIYI ","M7N3FIZI ","M7N3FMGXI","M7N3FMGYI","M7N3FMGZI","M7N3MAFXI","M7N3MAFYI", & + "M7N3MAFZI","M7N3MAGXI","M7N3MAGYI","M7N3MAGZI","M7N3MBFXI","M7N3MBFYI","M7N3MBFZI", & + "M7N3MBXI ","M7N3MBYI ","M7N3MBZI ","M7N3MMGXI","M7N3MMGYI","M7N3MMGZI","M7N3STAXI", & + "M7N3STAYI","M7N3STAZI","M7N3STVXI","M7N3STVYI","M7N3STVZI","M7N3VXI ","M7N3VYI ", & + "M7N3VZI ","M7N4AXI ","M7N4AYI ","M7N4AZI ","M7N4DYNP ","M7N4FAFXI","M7N4FAFYI", & + "M7N4FAFZI","M7N4FAGXI","M7N4FAGYI","M7N4FAGZI","M7N4FAMXI","M7N4FAMYI","M7N4FAMZI", & + "M7N4FBFXI","M7N4FBFYI","M7N4FBFZI","M7N4FBXI ","M7N4FBYI ","M7N4FBZI ","M7N4FDXI ", & + "M7N4FDYI ","M7N4FDZI ","M7N4FIXI ","M7N4FIYI ","M7N4FIZI ","M7N4FMGXI","M7N4FMGYI", & + "M7N4FMGZI","M7N4MAFXI","M7N4MAFYI","M7N4MAFZI","M7N4MAGXI","M7N4MAGYI","M7N4MAGZI", & + "M7N4MBFXI","M7N4MBFYI","M7N4MBFZI","M7N4MBXI ","M7N4MBYI ","M7N4MBZI ","M7N4MMGXI", & + "M7N4MMGYI","M7N4MMGZI","M7N4STAXI","M7N4STAYI","M7N4STAZI","M7N4STVXI","M7N4STVYI", & + "M7N4STVZI","M7N4VXI ","M7N4VYI ","M7N4VZI ","M7N5AXI ","M7N5AYI ","M7N5AZI ", & + "M7N5DYNP ","M7N5FAFXI","M7N5FAFYI","M7N5FAFZI","M7N5FAGXI","M7N5FAGYI","M7N5FAGZI", & + "M7N5FAMXI","M7N5FAMYI","M7N5FAMZI","M7N5FBFXI","M7N5FBFYI","M7N5FBFZI","M7N5FBXI ", & + "M7N5FBYI ","M7N5FBZI ","M7N5FDXI ","M7N5FDYI ","M7N5FDZI ","M7N5FIXI ","M7N5FIYI ", & + "M7N5FIZI ","M7N5FMGXI","M7N5FMGYI","M7N5FMGZI","M7N5MAFXI","M7N5MAFYI","M7N5MAFZI", & + "M7N5MAGXI","M7N5MAGYI","M7N5MAGZI","M7N5MBFXI","M7N5MBFYI","M7N5MBFZI","M7N5MBXI ", & + "M7N5MBYI ","M7N5MBZI ","M7N5MMGXI","M7N5MMGYI","M7N5MMGZI","M7N5STAXI","M7N5STAYI", & + "M7N5STAZI","M7N5STVXI","M7N5STVYI","M7N5STVZI","M7N5VXI ","M7N5VYI ","M7N5VZI ", & + "M7N6AXI ","M7N6AYI ","M7N6AZI ","M7N6DYNP ","M7N6FAFXI","M7N6FAFYI","M7N6FAFZI", & + "M7N6FAGXI","M7N6FAGYI","M7N6FAGZI","M7N6FAMXI","M7N6FAMYI","M7N6FAMZI","M7N6FBFXI", & + "M7N6FBFYI","M7N6FBFZI","M7N6FBXI ","M7N6FBYI ","M7N6FBZI ","M7N6FDXI ","M7N6FDYI ", & + "M7N6FDZI ","M7N6FIXI ","M7N6FIYI ","M7N6FIZI ","M7N6FMGXI","M7N6FMGYI","M7N6FMGZI", & + "M7N6MAFXI","M7N6MAFYI","M7N6MAFZI","M7N6MAGXI","M7N6MAGYI","M7N6MAGZI","M7N6MBFXI", & + "M7N6MBFYI","M7N6MBFZI","M7N6MBXI ","M7N6MBYI ","M7N6MBZI ","M7N6MMGXI","M7N6MMGYI", & + "M7N6MMGZI","M7N6STAXI","M7N6STAYI"/) + ValidParamAry(3501:4000) = (/ & + "M7N6STAZI","M7N6STVXI","M7N6STVYI","M7N6STVZI","M7N6VXI ","M7N6VYI ","M7N6VZI ", & + "M7N7AXI ","M7N7AYI ","M7N7AZI ","M7N7DYNP ","M7N7FAFXI","M7N7FAFYI","M7N7FAFZI", & + "M7N7FAGXI","M7N7FAGYI","M7N7FAGZI","M7N7FAMXI","M7N7FAMYI","M7N7FAMZI","M7N7FBFXI", & + "M7N7FBFYI","M7N7FBFZI","M7N7FBXI ","M7N7FBYI ","M7N7FBZI ","M7N7FDXI ","M7N7FDYI ", & + "M7N7FDZI ","M7N7FIXI ","M7N7FIYI ","M7N7FIZI ","M7N7FMGXI","M7N7FMGYI","M7N7FMGZI", & + "M7N7MAFXI","M7N7MAFYI","M7N7MAFZI","M7N7MAGXI","M7N7MAGYI","M7N7MAGZI","M7N7MBFXI", & + "M7N7MBFYI","M7N7MBFZI","M7N7MBXI ","M7N7MBYI ","M7N7MBZI ","M7N7MMGXI","M7N7MMGYI", & + "M7N7MMGZI","M7N7STAXI","M7N7STAYI","M7N7STAZI","M7N7STVXI","M7N7STVYI","M7N7STVZI", & + "M7N7VXI ","M7N7VYI ","M7N7VZI ","M7N8AXI ","M7N8AYI ","M7N8AZI ","M7N8DYNP ", & + "M7N8FAFXI","M7N8FAFYI","M7N8FAFZI","M7N8FAGXI","M7N8FAGYI","M7N8FAGZI","M7N8FAMXI", & + "M7N8FAMYI","M7N8FAMZI","M7N8FBFXI","M7N8FBFYI","M7N8FBFZI","M7N8FBXI ","M7N8FBYI ", & + "M7N8FBZI ","M7N8FDXI ","M7N8FDYI ","M7N8FDZI ","M7N8FIXI ","M7N8FIYI ","M7N8FIZI ", & + "M7N8FMGXI","M7N8FMGYI","M7N8FMGZI","M7N8MAFXI","M7N8MAFYI","M7N8MAFZI","M7N8MAGXI", & + "M7N8MAGYI","M7N8MAGZI","M7N8MBFXI","M7N8MBFYI","M7N8MBFZI","M7N8MBXI ","M7N8MBYI ", & + "M7N8MBZI ","M7N8MMGXI","M7N8MMGYI","M7N8MMGZI","M7N8STAXI","M7N8STAYI","M7N8STAZI", & + "M7N8STVXI","M7N8STVYI","M7N8STVZI","M7N8VXI ","M7N8VYI ","M7N8VZI ","M7N9AXI ", & + "M7N9AYI ","M7N9AZI ","M7N9DYNP ","M7N9FAFXI","M7N9FAFYI","M7N9FAFZI","M7N9FAGXI", & + "M7N9FAGYI","M7N9FAGZI","M7N9FAMXI","M7N9FAMYI","M7N9FAMZI","M7N9FBFXI","M7N9FBFYI", & + "M7N9FBFZI","M7N9FBXI ","M7N9FBYI ","M7N9FBZI ","M7N9FDXI ","M7N9FDYI ","M7N9FDZI ", & + "M7N9FIXI ","M7N9FIYI ","M7N9FIZI ","M7N9FMGXI","M7N9FMGYI","M7N9FMGZI","M7N9MAFXI", & + "M7N9MAFYI","M7N9MAFZI","M7N9MAGXI","M7N9MAGYI","M7N9MAGZI","M7N9MBFXI","M7N9MBFYI", & + "M7N9MBFZI","M7N9MBXI ","M7N9MBYI ","M7N9MBZI ","M7N9MMGXI","M7N9MMGYI","M7N9MMGZI", & + "M7N9STAXI","M7N9STAYI","M7N9STAZI","M7N9STVXI","M7N9STVYI","M7N9STVZI","M7N9VXI ", & + "M7N9VYI ","M7N9VZI ","M8N1AXI ","M8N1AYI ","M8N1AZI ","M8N1DYNP ","M8N1FAFXI", & + "M8N1FAFYI","M8N1FAFZI","M8N1FAGXI","M8N1FAGYI","M8N1FAGZI","M8N1FAMXI","M8N1FAMYI", & + "M8N1FAMZI","M8N1FBFXI","M8N1FBFYI","M8N1FBFZI","M8N1FBXI ","M8N1FBYI ","M8N1FBZI ", & + "M8N1FDXI ","M8N1FDYI ","M8N1FDZI ","M8N1FIXI ","M8N1FIYI ","M8N1FIZI ","M8N1FMGXI", & + "M8N1FMGYI","M8N1FMGZI","M8N1MAFXI","M8N1MAFYI","M8N1MAFZI","M8N1MAGXI","M8N1MAGYI", & + "M8N1MAGZI","M8N1MBFXI","M8N1MBFYI","M8N1MBFZI","M8N1MBXI ","M8N1MBYI ","M8N1MBZI ", & + "M8N1MMGXI","M8N1MMGYI","M8N1MMGZI","M8N1STAXI","M8N1STAYI","M8N1STAZI","M8N1STVXI", & + "M8N1STVYI","M8N1STVZI","M8N1VXI ","M8N1VYI ","M8N1VZI ","M8N2AXI ","M8N2AYI ", & + "M8N2AZI ","M8N2DYNP ","M8N2FAFXI","M8N2FAFYI","M8N2FAFZI","M8N2FAGXI","M8N2FAGYI", & + "M8N2FAGZI","M8N2FAMXI","M8N2FAMYI","M8N2FAMZI","M8N2FBFXI","M8N2FBFYI","M8N2FBFZI", & + "M8N2FBXI ","M8N2FBYI ","M8N2FBZI ","M8N2FDXI ","M8N2FDYI ","M8N2FDZI ","M8N2FIXI ", & + "M8N2FIYI ","M8N2FIZI ","M8N2FMGXI","M8N2FMGYI","M8N2FMGZI","M8N2MAFXI","M8N2MAFYI", & + "M8N2MAFZI","M8N2MAGXI","M8N2MAGYI","M8N2MAGZI","M8N2MBFXI","M8N2MBFYI","M8N2MBFZI", & + "M8N2MBXI ","M8N2MBYI ","M8N2MBZI ","M8N2MMGXI","M8N2MMGYI","M8N2MMGZI","M8N2STAXI", & + "M8N2STAYI","M8N2STAZI","M8N2STVXI","M8N2STVYI","M8N2STVZI","M8N2VXI ","M8N2VYI ", & + "M8N2VZI ","M8N3AXI ","M8N3AYI ","M8N3AZI ","M8N3DYNP ","M8N3FAFXI","M8N3FAFYI", & + "M8N3FAFZI","M8N3FAGXI","M8N3FAGYI","M8N3FAGZI","M8N3FAMXI","M8N3FAMYI","M8N3FAMZI", & + "M8N3FBFXI","M8N3FBFYI","M8N3FBFZI","M8N3FBXI ","M8N3FBYI ","M8N3FBZI ","M8N3FDXI ", & + "M8N3FDYI ","M8N3FDZI ","M8N3FIXI ","M8N3FIYI ","M8N3FIZI ","M8N3FMGXI","M8N3FMGYI", & + "M8N3FMGZI","M8N3MAFXI","M8N3MAFYI","M8N3MAFZI","M8N3MAGXI","M8N3MAGYI","M8N3MAGZI", & + "M8N3MBFXI","M8N3MBFYI","M8N3MBFZI","M8N3MBXI ","M8N3MBYI ","M8N3MBZI ","M8N3MMGXI", & + "M8N3MMGYI","M8N3MMGZI","M8N3STAXI","M8N3STAYI","M8N3STAZI","M8N3STVXI","M8N3STVYI", & + "M8N3STVZI","M8N3VXI ","M8N3VYI ","M8N3VZI ","M8N4AXI ","M8N4AYI ","M8N4AZI ", & + "M8N4DYNP ","M8N4FAFXI","M8N4FAFYI","M8N4FAFZI","M8N4FAGXI","M8N4FAGYI","M8N4FAGZI", & + "M8N4FAMXI","M8N4FAMYI","M8N4FAMZI","M8N4FBFXI","M8N4FBFYI","M8N4FBFZI","M8N4FBXI ", & + "M8N4FBYI ","M8N4FBZI ","M8N4FDXI ","M8N4FDYI ","M8N4FDZI ","M8N4FIXI ","M8N4FIYI ", & + "M8N4FIZI ","M8N4FMGXI","M8N4FMGYI","M8N4FMGZI","M8N4MAFXI","M8N4MAFYI","M8N4MAFZI", & + "M8N4MAGXI","M8N4MAGYI","M8N4MAGZI","M8N4MBFXI","M8N4MBFYI","M8N4MBFZI","M8N4MBXI ", & + "M8N4MBYI ","M8N4MBZI ","M8N4MMGXI","M8N4MMGYI","M8N4MMGZI","M8N4STAXI","M8N4STAYI", & + "M8N4STAZI","M8N4STVXI","M8N4STVYI","M8N4STVZI","M8N4VXI ","M8N4VYI ","M8N4VZI ", & + "M8N5AXI ","M8N5AYI ","M8N5AZI ","M8N5DYNP ","M8N5FAFXI","M8N5FAFYI","M8N5FAFZI", & + "M8N5FAGXI","M8N5FAGYI","M8N5FAGZI","M8N5FAMXI","M8N5FAMYI","M8N5FAMZI","M8N5FBFXI", & + "M8N5FBFYI","M8N5FBFZI","M8N5FBXI ","M8N5FBYI ","M8N5FBZI ","M8N5FDXI ","M8N5FDYI ", & + "M8N5FDZI ","M8N5FIXI ","M8N5FIYI ","M8N5FIZI ","M8N5FMGXI","M8N5FMGYI","M8N5FMGZI", & + "M8N5MAFXI","M8N5MAFYI","M8N5MAFZI","M8N5MAGXI","M8N5MAGYI","M8N5MAGZI","M8N5MBFXI", & + "M8N5MBFYI","M8N5MBFZI","M8N5MBXI ","M8N5MBYI ","M8N5MBZI ","M8N5MMGXI","M8N5MMGYI", & + "M8N5MMGZI","M8N5STAXI","M8N5STAYI","M8N5STAZI","M8N5STVXI","M8N5STVYI","M8N5STVZI", & + "M8N5VXI ","M8N5VYI ","M8N5VZI ","M8N6AXI ","M8N6AYI ","M8N6AZI ","M8N6DYNP ", & + "M8N6FAFXI","M8N6FAFYI","M8N6FAFZI","M8N6FAGXI","M8N6FAGYI","M8N6FAGZI","M8N6FAMXI", & + "M8N6FAMYI","M8N6FAMZI","M8N6FBFXI","M8N6FBFYI","M8N6FBFZI","M8N6FBXI ","M8N6FBYI ", & + "M8N6FBZI ","M8N6FDXI ","M8N6FDYI ","M8N6FDZI ","M8N6FIXI ","M8N6FIYI ","M8N6FIZI ", & + "M8N6FMGXI","M8N6FMGYI","M8N6FMGZI","M8N6MAFXI","M8N6MAFYI","M8N6MAFZI","M8N6MAGXI", & + "M8N6MAGYI","M8N6MAGZI","M8N6MBFXI","M8N6MBFYI","M8N6MBFZI","M8N6MBXI ","M8N6MBYI ", & + "M8N6MBZI ","M8N6MMGXI","M8N6MMGYI","M8N6MMGZI","M8N6STAXI","M8N6STAYI","M8N6STAZI", & + "M8N6STVXI","M8N6STVYI","M8N6STVZI","M8N6VXI ","M8N6VYI ","M8N6VZI ","M8N7AXI ", & + "M8N7AYI ","M8N7AZI ","M8N7DYNP ","M8N7FAFXI","M8N7FAFYI","M8N7FAFZI","M8N7FAGXI", & + "M8N7FAGYI","M8N7FAGZI","M8N7FAMXI","M8N7FAMYI","M8N7FAMZI","M8N7FBFXI","M8N7FBFYI", & + "M8N7FBFZI","M8N7FBXI ","M8N7FBYI ","M8N7FBZI ","M8N7FDXI ","M8N7FDYI ","M8N7FDZI ", & + "M8N7FIXI ","M8N7FIYI ","M8N7FIZI "/) + ValidParamAry(4001:4500) = (/ & + "M8N7FMGXI","M8N7FMGYI","M8N7FMGZI","M8N7MAFXI","M8N7MAFYI","M8N7MAFZI","M8N7MAGXI", & + "M8N7MAGYI","M8N7MAGZI","M8N7MBFXI","M8N7MBFYI","M8N7MBFZI","M8N7MBXI ","M8N7MBYI ", & + "M8N7MBZI ","M8N7MMGXI","M8N7MMGYI","M8N7MMGZI","M8N7STAXI","M8N7STAYI","M8N7STAZI", & + "M8N7STVXI","M8N7STVYI","M8N7STVZI","M8N7VXI ","M8N7VYI ","M8N7VZI ","M8N8AXI ", & + "M8N8AYI ","M8N8AZI ","M8N8DYNP ","M8N8FAFXI","M8N8FAFYI","M8N8FAFZI","M8N8FAGXI", & + "M8N8FAGYI","M8N8FAGZI","M8N8FAMXI","M8N8FAMYI","M8N8FAMZI","M8N8FBFXI","M8N8FBFYI", & + "M8N8FBFZI","M8N8FBXI ","M8N8FBYI ","M8N8FBZI ","M8N8FDXI ","M8N8FDYI ","M8N8FDZI ", & + "M8N8FIXI ","M8N8FIYI ","M8N8FIZI ","M8N8FMGXI","M8N8FMGYI","M8N8FMGZI","M8N8MAFXI", & + "M8N8MAFYI","M8N8MAFZI","M8N8MAGXI","M8N8MAGYI","M8N8MAGZI","M8N8MBFXI","M8N8MBFYI", & + "M8N8MBFZI","M8N8MBXI ","M8N8MBYI ","M8N8MBZI ","M8N8MMGXI","M8N8MMGYI","M8N8MMGZI", & + "M8N8STAXI","M8N8STAYI","M8N8STAZI","M8N8STVXI","M8N8STVYI","M8N8STVZI","M8N8VXI ", & + "M8N8VYI ","M8N8VZI ","M8N9AXI ","M8N9AYI ","M8N9AZI ","M8N9DYNP ","M8N9FAFXI", & + "M8N9FAFYI","M8N9FAFZI","M8N9FAGXI","M8N9FAGYI","M8N9FAGZI","M8N9FAMXI","M8N9FAMYI", & + "M8N9FAMZI","M8N9FBFXI","M8N9FBFYI","M8N9FBFZI","M8N9FBXI ","M8N9FBYI ","M8N9FBZI ", & + "M8N9FDXI ","M8N9FDYI ","M8N9FDZI ","M8N9FIXI ","M8N9FIYI ","M8N9FIZI ","M8N9FMGXI", & + "M8N9FMGYI","M8N9FMGZI","M8N9MAFXI","M8N9MAFYI","M8N9MAFZI","M8N9MAGXI","M8N9MAGYI", & + "M8N9MAGZI","M8N9MBFXI","M8N9MBFYI","M8N9MBFZI","M8N9MBXI ","M8N9MBYI ","M8N9MBZI ", & + "M8N9MMGXI","M8N9MMGYI","M8N9MMGZI","M8N9STAXI","M8N9STAYI","M8N9STAZI","M8N9STVXI", & + "M8N9STVYI","M8N9STVZI","M8N9VXI ","M8N9VYI ","M8N9VZI ","M9N1AXI ","M9N1AYI ", & + "M9N1AZI ","M9N1DYNP ","M9N1FAFXI","M9N1FAFYI","M9N1FAFZI","M9N1FAGXI","M9N1FAGYI", & + "M9N1FAGZI","M9N1FAMXI","M9N1FAMYI","M9N1FAMZI","M9N1FBFXI","M9N1FBFYI","M9N1FBFZI", & + "M9N1FBXI ","M9N1FBYI ","M9N1FBZI ","M9N1FDXI ","M9N1FDYI ","M9N1FDZI ","M9N1FIXI ", & + "M9N1FIYI ","M9N1FIZI ","M9N1FMGXI","M9N1FMGYI","M9N1FMGZI","M9N1MAFXI","M9N1MAFYI", & + "M9N1MAFZI","M9N1MAGXI","M9N1MAGYI","M9N1MAGZI","M9N1MBFXI","M9N1MBFYI","M9N1MBFZI", & + "M9N1MBXI ","M9N1MBYI ","M9N1MBZI ","M9N1MMGXI","M9N1MMGYI","M9N1MMGZI","M9N1STAXI", & + "M9N1STAYI","M9N1STAZI","M9N1STVXI","M9N1STVYI","M9N1STVZI","M9N1VXI ","M9N1VYI ", & + "M9N1VZI ","M9N2AXI ","M9N2AYI ","M9N2AZI ","M9N2DYNP ","M9N2FAFXI","M9N2FAFYI", & + "M9N2FAFZI","M9N2FAGXI","M9N2FAGYI","M9N2FAGZI","M9N2FAMXI","M9N2FAMYI","M9N2FAMZI", & + "M9N2FBFXI","M9N2FBFYI","M9N2FBFZI","M9N2FBXI ","M9N2FBYI ","M9N2FBZI ","M9N2FDXI ", & + "M9N2FDYI ","M9N2FDZI ","M9N2FIXI ","M9N2FIYI ","M9N2FIZI ","M9N2FMGXI","M9N2FMGYI", & + "M9N2FMGZI","M9N2MAFXI","M9N2MAFYI","M9N2MAFZI","M9N2MAGXI","M9N2MAGYI","M9N2MAGZI", & + "M9N2MBFXI","M9N2MBFYI","M9N2MBFZI","M9N2MBXI ","M9N2MBYI ","M9N2MBZI ","M9N2MMGXI", & + "M9N2MMGYI","M9N2MMGZI","M9N2STAXI","M9N2STAYI","M9N2STAZI","M9N2STVXI","M9N2STVYI", & + "M9N2STVZI","M9N2VXI ","M9N2VYI ","M9N2VZI ","M9N3AXI ","M9N3AYI ","M9N3AZI ", & + "M9N3DYNP ","M9N3FAFXI","M9N3FAFYI","M9N3FAFZI","M9N3FAGXI","M9N3FAGYI","M9N3FAGZI", & + "M9N3FAMXI","M9N3FAMYI","M9N3FAMZI","M9N3FBFXI","M9N3FBFYI","M9N3FBFZI","M9N3FBXI ", & + "M9N3FBYI ","M9N3FBZI ","M9N3FDXI ","M9N3FDYI ","M9N3FDZI ","M9N3FIXI ","M9N3FIYI ", & + "M9N3FIZI ","M9N3FMGXI","M9N3FMGYI","M9N3FMGZI","M9N3MAFXI","M9N3MAFYI","M9N3MAFZI", & + "M9N3MAGXI","M9N3MAGYI","M9N3MAGZI","M9N3MBFXI","M9N3MBFYI","M9N3MBFZI","M9N3MBXI ", & + "M9N3MBYI ","M9N3MBZI ","M9N3MMGXI","M9N3MMGYI","M9N3MMGZI","M9N3STAXI","M9N3STAYI", & + "M9N3STAZI","M9N3STVXI","M9N3STVYI","M9N3STVZI","M9N3VXI ","M9N3VYI ","M9N3VZI ", & + "M9N4AXI ","M9N4AYI ","M9N4AZI ","M9N4DYNP ","M9N4FAFXI","M9N4FAFYI","M9N4FAFZI", & + "M9N4FAGXI","M9N4FAGYI","M9N4FAGZI","M9N4FAMXI","M9N4FAMYI","M9N4FAMZI","M9N4FBFXI", & + "M9N4FBFYI","M9N4FBFZI","M9N4FBXI ","M9N4FBYI ","M9N4FBZI ","M9N4FDXI ","M9N4FDYI ", & + "M9N4FDZI ","M9N4FIXI ","M9N4FIYI ","M9N4FIZI ","M9N4FMGXI","M9N4FMGYI","M9N4FMGZI", & + "M9N4MAFXI","M9N4MAFYI","M9N4MAFZI","M9N4MAGXI","M9N4MAGYI","M9N4MAGZI","M9N4MBFXI", & + "M9N4MBFYI","M9N4MBFZI","M9N4MBXI ","M9N4MBYI ","M9N4MBZI ","M9N4MMGXI","M9N4MMGYI", & + "M9N4MMGZI","M9N4STAXI","M9N4STAYI","M9N4STAZI","M9N4STVXI","M9N4STVYI","M9N4STVZI", & + "M9N4VXI ","M9N4VYI ","M9N4VZI ","M9N5AXI ","M9N5AYI ","M9N5AZI ","M9N5DYNP ", & + "M9N5FAFXI","M9N5FAFYI","M9N5FAFZI","M9N5FAGXI","M9N5FAGYI","M9N5FAGZI","M9N5FAMXI", & + "M9N5FAMYI","M9N5FAMZI","M9N5FBFXI","M9N5FBFYI","M9N5FBFZI","M9N5FBXI ","M9N5FBYI ", & + "M9N5FBZI ","M9N5FDXI ","M9N5FDYI ","M9N5FDZI ","M9N5FIXI ","M9N5FIYI ","M9N5FIZI ", & + "M9N5FMGXI","M9N5FMGYI","M9N5FMGZI","M9N5MAFXI","M9N5MAFYI","M9N5MAFZI","M9N5MAGXI", & + "M9N5MAGYI","M9N5MAGZI","M9N5MBFXI","M9N5MBFYI","M9N5MBFZI","M9N5MBXI ","M9N5MBYI ", & + "M9N5MBZI ","M9N5MMGXI","M9N5MMGYI","M9N5MMGZI","M9N5STAXI","M9N5STAYI","M9N5STAZI", & + "M9N5STVXI","M9N5STVYI","M9N5STVZI","M9N5VXI ","M9N5VYI ","M9N5VZI ","M9N6AXI ", & + "M9N6AYI ","M9N6AZI ","M9N6DYNP ","M9N6FAFXI","M9N6FAFYI","M9N6FAFZI","M9N6FAGXI", & + "M9N6FAGYI","M9N6FAGZI","M9N6FAMXI","M9N6FAMYI","M9N6FAMZI","M9N6FBFXI","M9N6FBFYI", & + "M9N6FBFZI","M9N6FBXI ","M9N6FBYI ","M9N6FBZI ","M9N6FDXI ","M9N6FDYI ","M9N6FDZI ", & + "M9N6FIXI ","M9N6FIYI ","M9N6FIZI ","M9N6FMGXI","M9N6FMGYI","M9N6FMGZI","M9N6MAFXI", & + "M9N6MAFYI","M9N6MAFZI","M9N6MAGXI","M9N6MAGYI","M9N6MAGZI","M9N6MBFXI","M9N6MBFYI", & + "M9N6MBFZI","M9N6MBXI ","M9N6MBYI ","M9N6MBZI ","M9N6MMGXI","M9N6MMGYI","M9N6MMGZI", & + "M9N6STAXI","M9N6STAYI","M9N6STAZI","M9N6STVXI","M9N6STVYI","M9N6STVZI","M9N6VXI ", & + "M9N6VYI ","M9N6VZI ","M9N7AXI ","M9N7AYI ","M9N7AZI ","M9N7DYNP ","M9N7FAFXI", & + "M9N7FAFYI","M9N7FAFZI","M9N7FAGXI","M9N7FAGYI","M9N7FAGZI","M9N7FAMXI","M9N7FAMYI", & + "M9N7FAMZI","M9N7FBFXI","M9N7FBFYI","M9N7FBFZI","M9N7FBXI ","M9N7FBYI ","M9N7FBZI ", & + "M9N7FDXI ","M9N7FDYI ","M9N7FDZI ","M9N7FIXI ","M9N7FIYI ","M9N7FIZI ","M9N7FMGXI", & + "M9N7FMGYI","M9N7FMGZI","M9N7MAFXI","M9N7MAFYI","M9N7MAFZI","M9N7MAGXI","M9N7MAGYI", & + "M9N7MAGZI","M9N7MBFXI","M9N7MBFYI","M9N7MBFZI","M9N7MBXI ","M9N7MBYI ","M9N7MBZI ", & + "M9N7MMGXI","M9N7MMGYI","M9N7MMGZI","M9N7STAXI","M9N7STAYI","M9N7STAZI","M9N7STVXI", & + "M9N7STVYI","M9N7STVZI","M9N7VXI ","M9N7VYI ","M9N7VZI ","M9N8AXI ","M9N8AYI ", & + "M9N8AZI ","M9N8DYNP ","M9N8FAFXI"/) + ValidParamAry(4501:4599) = (/ & + "M9N8FAFYI","M9N8FAFZI","M9N8FAGXI","M9N8FAGYI","M9N8FAGZI","M9N8FAMXI","M9N8FAMYI", & + "M9N8FAMZI","M9N8FBFXI","M9N8FBFYI","M9N8FBFZI","M9N8FBXI ","M9N8FBYI ","M9N8FBZI ", & + "M9N8FDXI ","M9N8FDYI ","M9N8FDZI ","M9N8FIXI ","M9N8FIYI ","M9N8FIZI ","M9N8FMGXI", & + "M9N8FMGYI","M9N8FMGZI","M9N8MAFXI","M9N8MAFYI","M9N8MAFZI","M9N8MAGXI","M9N8MAGYI", & + "M9N8MAGZI","M9N8MBFXI","M9N8MBFYI","M9N8MBFZI","M9N8MBXI ","M9N8MBYI ","M9N8MBZI ", & + "M9N8MMGXI","M9N8MMGYI","M9N8MMGZI","M9N8STAXI","M9N8STAYI","M9N8STAZI","M9N8STVXI", & + "M9N8STVYI","M9N8STVZI","M9N8VXI ","M9N8VYI ","M9N8VZI ","M9N9AXI ","M9N9AYI ", & + "M9N9AZI ","M9N9DYNP ","M9N9FAFXI","M9N9FAFYI","M9N9FAFZI","M9N9FAGXI","M9N9FAGYI", & + "M9N9FAGZI","M9N9FAMXI","M9N9FAMYI","M9N9FAMZI","M9N9FBFXI","M9N9FBFYI","M9N9FBFZI", & + "M9N9FBXI ","M9N9FBYI ","M9N9FBZI ","M9N9FDXI ","M9N9FDYI ","M9N9FDZI ","M9N9FIXI ", & + "M9N9FIYI ","M9N9FIZI ","M9N9FMGXI","M9N9FMGYI","M9N9FMGZI","M9N9MAFXI","M9N9MAFYI", & + "M9N9MAFZI","M9N9MAGXI","M9N9MAGYI","M9N9MAGZI","M9N9MBFXI","M9N9MBFYI","M9N9MBFZI", & + "M9N9MBXI ","M9N9MBYI ","M9N9MBZI ","M9N9MMGXI","M9N9MMGYI","M9N9MMGZI","M9N9STAXI", & + "M9N9STAYI","M9N9STAZI","M9N9STVXI","M9N9STVYI","M9N9STVZI","M9N9VXI ","M9N9VYI ", & + "M9N9VZI "/) + ParamIndxAry(1:500) = (/ & + J1Axi , J1Ayi , J1Azi , J1DynP , J1FAGxi , J1FAGyi , J1FAGzi , & + J1FAMxi , J1FAMyi , J1FAMzi , J1FBFxi , J1FBFyi , J1FBFzi , J1FBxi , & + J1FByi , J1FBzi , J1FDxi , J1FDyi , J1FDzi , J1FIxi , J1FIyi , & + J1FIzi , J1FMGxi , J1FMGyi , J1FMGzi , J1MAGxi , J1MAGyi , J1MAGzi , & + J1MBFxi , J1MBFyi , J1MBFzi , J1MBxi , J1MByi , J1MBzi , J1STAxi , & + J1STAyi , J1STAzi , J1STVxi , J1STVyi , J1STVzi , J1Vxi , J1Vyi , & + J1Vzi , J2Axi , J2Ayi , J2Azi , J2DynP , J2FAGxi , J2FAGyi , & + J2FAGzi , J2FAMxi , J2FAMyi , J2FAMzi , J2FBFxi , J2FBFyi , J2FBFzi , & + J2FBxi , J2FByi , J2FBzi , J2FDxi , J2FDyi , J2FDzi , J2FIxi , & + J2FIyi , J2FIzi , J2FMGxi , J2FMGyi , J2FMGzi , J2MAGxi , J2MAGyi , & + J2MAGzi , J2MBFxi , J2MBFyi , J2MBFzi , J2MBxi , J2MByi , J2MBzi , & + J2STAxi , J2STAyi , J2STAzi , J2STVxi , J2STVyi , J2STVzi , J2Vxi , & + J2Vyi , J2Vzi , J3Axi , J3Ayi , J3Azi , J3DynP , J3FAGxi , & + J3FAGyi , J3FAGzi , J3FAMxi , J3FAMyi , J3FAMzi , J3FBFxi , J3FBFyi , & + J3FBFzi , J3FBxi , J3FByi , J3FBzi , J3FDxi , J3FDyi , J3FDzi , & + J3FIxi , J3FIyi , J3FIzi , J3FMGxi , J3FMGyi , J3FMGzi , J3MAGxi , & + J3MAGyi , J3MAGzi , J3MBFxi , J3MBFyi , J3MBFzi , J3MBxi , J3MByi , & + J3MBzi , J3STAxi , J3STAyi , J3STAzi , J3STVxi , J3STVyi , J3STVzi , & + J3Vxi , J3Vyi , J3Vzi , J4Axi , J4Ayi , J4Azi , J4DynP , & + J4FAGxi , J4FAGyi , J4FAGzi , J4FAMxi , J4FAMyi , J4FAMzi , J4FBFxi , & + J4FBFyi , J4FBFzi , J4FBxi , J4FByi , J4FBzi , J4FDxi , J4FDyi , & + J4FDzi , J4FIxi , J4FIyi , J4FIzi , J4FMGxi , J4FMGyi , J4FMGzi , & + J4MAGxi , J4MAGyi , J4MAGzi , J4MBFxi , J4MBFyi , J4MBFzi , J4MBxi , & + J4MByi , J4MBzi , J4STAxi , J4STAyi , J4STAzi , J4STVxi , J4STVyi , & + J4STVzi , J4Vxi , J4Vyi , J4Vzi , J5Axi , J5Ayi , J5Azi , & + J5DynP , J5FAGxi , J5FAGyi , J5FAGzi , J5FAMxi , J5FAMyi , J5FAMzi , & + J5FBFxi , J5FBFyi , J5FBFzi , J5FBxi , J5FByi , J5FBzi , J5FDxi , & + J5FDyi , J5FDzi , J5FIxi , J5FIyi , J5FIzi , J5FMGxi , J5FMGyi , & + J5FMGzi , J5MAGxi , J5MAGyi , J5MAGzi , J5MBFxi , J5MBFyi , J5MBFzi , & + J5MBxi , J5MByi , J5MBzi , J5STAxi , J5STAyi , J5STAzi , J5STVxi , & + J5STVyi , J5STVzi , J5Vxi , J5Vyi , J5Vzi , J6Axi , J6Ayi , & + J6Azi , J6DynP , J6FAGxi , J6FAGyi , J6FAGzi , J6FAMxi , J6FAMyi , & + J6FAMzi , J6FBFxi , J6FBFyi , J6FBFzi , J6FBxi , J6FByi , J6FBzi , & + J6FDxi , J6FDyi , J6FDzi , J6FIxi , J6FIyi , J6FIzi , J6FMGxi , & + J6FMGyi , J6FMGzi , J6MAGxi , J6MAGyi , J6MAGzi , J6MBFxi , J6MBFyi , & + J6MBFzi , J6MBxi , J6MByi , J6MBzi , J6STAxi , J6STAyi , J6STAzi , & + J6STVxi , J6STVyi , J6STVzi , J6Vxi , J6Vyi , J6Vzi , J7Axi , & + J7Ayi , J7Azi , J7DynP , J7FAGxi , J7FAGyi , J7FAGzi , J7FAMxi , & + J7FAMyi , J7FAMzi , J7FBFxi , J7FBFyi , J7FBFzi , J7FBxi , J7FByi , & + J7FBzi , J7FDxi , J7FDyi , J7FDzi , J7FIxi , J7FIyi , J7FIzi , & + J7FMGxi , J7FMGyi , J7FMGzi , J7MAGxi , J7MAGyi , J7MAGzi , J7MBFxi , & + J7MBFyi , J7MBFzi , J7MBxi , J7MByi , J7MBzi , J7STAxi , J7STAyi , & + J7STAzi , J7STVxi , J7STVyi , J7STVzi , J7Vxi , J7Vyi , J7Vzi , & + J8Axi , J8Ayi , J8Azi , J8DynP , J8FAGxi , J8FAGyi , J8FAGzi , & + J8FAMxi , J8FAMyi , J8FAMzi , J8FBFxi , J8FBFyi , J8FBFzi , J8FBxi , & + J8FByi , J8FBzi , J8FDxi , J8FDyi , J8FDzi , J8FIxi , J8FIyi , & + J8FIzi , J8FMGxi , J8FMGyi , J8FMGzi , J8MAGxi , J8MAGyi , J8MAGzi , & + J8MBFxi , J8MBFyi , J8MBFzi , J8MBxi , J8MByi , J8MBzi , J8STAxi , & + J8STAyi , J8STAzi , J8STVxi , J8STVyi , J8STVzi , J8Vxi , J8Vyi , & + J8Vzi , J9Axi , J9Ayi , J9Azi , J9DynP , J9FAGxi , J9FAGyi , & + J9FAGzi , J9FAMxi , J9FAMyi , J9FAMzi , J9FBFxi , J9FBFyi , J9FBFzi , & + J9FBxi , J9FByi , J9FBzi , J9FDxi , J9FDyi , J9FDzi , J9FIxi , & + J9FIyi , J9FIzi , J9FMGxi , J9FMGyi , J9FMGzi , J9MAGxi , J9MAGyi , & + J9MAGzi , J9MBFxi , J9MBFyi , J9MBFzi , J9MBxi , J9MByi , J9MBzi , & + J9STAxi , J9STAyi , J9STAzi , J9STVxi , J9STVyi , J9STVzi , J9Vxi , & + J9Vyi , J9Vzi , M1N1Axi , M1N1Ayi , M1N1Azi , M1N1DynP , M1N1FAFxi , & + M1N1FAFyi , M1N1FAFzi , M1N1FAGxi , M1N1FAGyi , M1N1FAGzi , M1N1FAMxi , M1N1FAMyi , & + M1N1FAMzi , M1N1FBFxi , M1N1FBFyi , M1N1FBFzi , M1N1FBxi , M1N1FByi , M1N1FBzi , & + M1N1FDxi , M1N1FDyi , M1N1FDzi , M1N1FIxi , M1N1FIyi , M1N1FIzi , M1N1FMGxi , & + M1N1FMGyi , M1N1FMGzi , M1N1MAFxi , M1N1MAFyi , M1N1MAFzi , M1N1MAGxi , M1N1MAGyi , & + M1N1MAGzi , M1N1MBFxi , M1N1MBFyi , M1N1MBFzi , M1N1MBxi , M1N1MByi , M1N1MBzi , & + M1N1MMGxi , M1N1MMGyi , M1N1MMGzi , M1N1STAxi , M1N1STAyi , M1N1STAzi , M1N1STVxi , & + M1N1STVyi , M1N1STVzi , M1N1Vxi , M1N1Vyi , M1N1Vzi , M1N2Axi , M1N2Ayi , & + M1N2Azi , M1N2DynP , M1N2FAFxi , M1N2FAFyi , M1N2FAFzi , M1N2FAGxi , M1N2FAGyi , & + M1N2FAGzi , M1N2FAMxi , M1N2FAMyi , M1N2FAMzi , M1N2FBFxi , M1N2FBFyi , M1N2FBFzi , & + M1N2FBxi , M1N2FByi , M1N2FBzi , M1N2FDxi , M1N2FDyi , M1N2FDzi , M1N2FIxi , & + M1N2FIyi , M1N2FIzi , M1N2FMGxi , M1N2FMGyi , M1N2FMGzi , M1N2MAFxi , M1N2MAFyi , & + M1N2MAFzi , M1N2MAGxi , M1N2MAGyi , M1N2MAGzi , M1N2MBFxi , M1N2MBFyi , M1N2MBFzi , & + M1N2MBxi , M1N2MByi , M1N2MBzi , M1N2MMGxi , M1N2MMGyi , M1N2MMGzi , M1N2STAxi , & + M1N2STAyi , M1N2STAzi , M1N2STVxi , M1N2STVyi , M1N2STVzi , M1N2Vxi , M1N2Vyi , & + M1N2Vzi , M1N3Axi , M1N3Ayi , M1N3Azi , M1N3DynP , M1N3FAFxi , M1N3FAFyi , & + M1N3FAFzi , M1N3FAGxi , M1N3FAGyi /) + ParamIndxAry(501:1000) = (/ & + M1N3FAGzi , M1N3FAMxi , M1N3FAMyi , M1N3FAMzi , M1N3FBFxi , M1N3FBFyi , M1N3FBFzi , & + M1N3FBxi , M1N3FByi , M1N3FBzi , M1N3FDxi , M1N3FDyi , M1N3FDzi , M1N3FIxi , & + M1N3FIyi , M1N3FIzi , M1N3FMGxi , M1N3FMGyi , M1N3FMGzi , M1N3MAFxi , M1N3MAFyi , & + M1N3MAFzi , M1N3MAGxi , M1N3MAGyi , M1N3MAGzi , M1N3MBFxi , M1N3MBFyi , M1N3MBFzi , & + M1N3MBxi , M1N3MByi , M1N3MBzi , M1N3MMGxi , M1N3MMGyi , M1N3MMGzi , M1N3STAxi , & + M1N3STAyi , M1N3STAzi , M1N3STVxi , M1N3STVyi , M1N3STVzi , M1N3Vxi , M1N3Vyi , & + M1N3Vzi , M1N4Axi , M1N4Ayi , M1N4Azi , M1N4DynP , M1N4FAFxi , M1N4FAFyi , & + M1N4FAFzi , M1N4FAGxi , M1N4FAGyi , M1N4FAGzi , M1N4FAMxi , M1N4FAMyi , M1N4FAMzi , & + M1N4FBFxi , M1N4FBFyi , M1N4FBFzi , M1N4FBxi , M1N4FByi , M1N4FBzi , M1N4FDxi , & + M1N4FDyi , M1N4FDzi , M1N4FIxi , M1N4FIyi , M1N4FIzi , M1N4FMGxi , M1N4FMGyi , & + M1N4FMGzi , M1N4MAFxi , M1N4MAFyi , M1N4MAFzi , M1N4MAGxi , M1N4MAGyi , M1N4MAGzi , & + M1N4MBFxi , M1N4MBFyi , M1N4MBFzi , M1N4MBxi , M1N4MByi , M1N4MBzi , M1N4MMGxi , & + M1N4MMGyi , M1N4MMGzi , M1N4STAxi , M1N4STAyi , M1N4STAzi , M1N4STVxi , M1N4STVyi , & + M1N4STVzi , M1N4Vxi , M1N4Vyi , M1N4Vzi , M1N5Axi , M1N5Ayi , M1N5Azi , & + M1N5DynP , M1N5FAFxi , M1N5FAFyi , M1N5FAFzi , M1N5FAGxi , M1N5FAGyi , M1N5FAGzi , & + M1N5FAMxi , M1N5FAMyi , M1N5FAMzi , M1N5FBFxi , M1N5FBFyi , M1N5FBFzi , M1N5FBxi , & + M1N5FByi , M1N5FBzi , M1N5FDxi , M1N5FDyi , M1N5FDzi , M1N5FIxi , M1N5FIyi , & + M1N5FIzi , M1N5FMGxi , M1N5FMGyi , M1N5FMGzi , M1N5MAFxi , M1N5MAFyi , M1N5MAFzi , & + M1N5MAGxi , M1N5MAGyi , M1N5MAGzi , M1N5MBFxi , M1N5MBFyi , M1N5MBFzi , M1N5MBxi , & + M1N5MByi , M1N5MBzi , M1N5MMGxi , M1N5MMGyi , M1N5MMGzi , M1N5STAxi , M1N5STAyi , & + M1N5STAzi , M1N5STVxi , M1N5STVyi , M1N5STVzi , M1N5Vxi , M1N5Vyi , M1N5Vzi , & + M1N6Axi , M1N6Ayi , M1N6Azi , M1N6DynP , M1N6FAFxi , M1N6FAFyi , M1N6FAFzi , & + M1N6FAGxi , M1N6FAGyi , M1N6FAGzi , M1N6FAMxi , M1N6FAMyi , M1N6FAMzi , M1N6FBFxi , & + M1N6FBFyi , M1N6FBFzi , M1N6FBxi , M1N6FByi , M1N6FBzi , M1N6FDxi , M1N6FDyi , & + M1N6FDzi , M1N6FIxi , M1N6FIyi , M1N6FIzi , M1N6FMGxi , M1N6FMGyi , M1N6FMGzi , & + M1N6MAFxi , M1N6MAFyi , M1N6MAFzi , M1N6MAGxi , M1N6MAGyi , M1N6MAGzi , M1N6MBFxi , & + M1N6MBFyi , M1N6MBFzi , M1N6MBxi , M1N6MByi , M1N6MBzi , M1N6MMGxi , M1N6MMGyi , & + M1N6MMGzi , M1N6STAxi , M1N6STAyi , M1N6STAzi , M1N6STVxi , M1N6STVyi , M1N6STVzi , & + M1N6Vxi , M1N6Vyi , M1N6Vzi , M1N7Axi , M1N7Ayi , M1N7Azi , M1N7DynP , & + M1N7FAFxi , M1N7FAFyi , M1N7FAFzi , M1N7FAGxi , M1N7FAGyi , M1N7FAGzi , M1N7FAMxi , & + M1N7FAMyi , M1N7FAMzi , M1N7FBFxi , M1N7FBFyi , M1N7FBFzi , M1N7FBxi , M1N7FByi , & + M1N7FBzi , M1N7FDxi , M1N7FDyi , M1N7FDzi , M1N7FIxi , M1N7FIyi , M1N7FIzi , & + M1N7FMGxi , M1N7FMGyi , M1N7FMGzi , M1N7MAFxi , M1N7MAFyi , M1N7MAFzi , M1N7MAGxi , & + M1N7MAGyi , M1N7MAGzi , M1N7MBFxi , M1N7MBFyi , M1N7MBFzi , M1N7MBxi , M1N7MByi , & + M1N7MBzi , M1N7MMGxi , M1N7MMGyi , M1N7MMGzi , M1N7STAxi , M1N7STAyi , M1N7STAzi , & + M1N7STVxi , M1N7STVyi , M1N7STVzi , M1N7Vxi , M1N7Vyi , M1N7Vzi , M1N8Axi , & + M1N8Ayi , M1N8Azi , M1N8DynP , M1N8FAFxi , M1N8FAFyi , M1N8FAFzi , M1N8FAGxi , & + M1N8FAGyi , M1N8FAGzi , M1N8FAMxi , M1N8FAMyi , M1N8FAMzi , M1N8FBFxi , M1N8FBFyi , & + M1N8FBFzi , M1N8FBxi , M1N8FByi , M1N8FBzi , M1N8FDxi , M1N8FDyi , M1N8FDzi , & + M1N8FIxi , M1N8FIyi , M1N8FIzi , M1N8FMGxi , M1N8FMGyi , M1N8FMGzi , M1N8MAFxi , & + M1N8MAFyi , M1N8MAFzi , M1N8MAGxi , M1N8MAGyi , M1N8MAGzi , M1N8MBFxi , M1N8MBFyi , & + M1N8MBFzi , M1N8MBxi , M1N8MByi , M1N8MBzi , M1N8MMGxi , M1N8MMGyi , M1N8MMGzi , & + M1N8STAxi , M1N8STAyi , M1N8STAzi , M1N8STVxi , M1N8STVyi , M1N8STVzi , M1N8Vxi , & + M1N8Vyi , M1N8Vzi , M1N9Axi , M1N9Ayi , M1N9Azi , M1N9DynP , M1N9FAFxi , & + M1N9FAFyi , M1N9FAFzi , M1N9FAGxi , M1N9FAGyi , M1N9FAGzi , M1N9FAMxi , M1N9FAMyi , & + M1N9FAMzi , M1N9FBFxi , M1N9FBFyi , M1N9FBFzi , M1N9FBxi , M1N9FByi , M1N9FBzi , & + M1N9FDxi , M1N9FDyi , M1N9FDzi , M1N9FIxi , M1N9FIyi , M1N9FIzi , M1N9FMGxi , & + M1N9FMGyi , M1N9FMGzi , M1N9MAFxi , M1N9MAFyi , M1N9MAFzi , M1N9MAGxi , M1N9MAGyi , & + M1N9MAGzi , M1N9MBFxi , M1N9MBFyi , M1N9MBFzi , M1N9MBxi , M1N9MByi , M1N9MBzi , & + M1N9MMGxi , M1N9MMGyi , M1N9MMGzi , M1N9STAxi , M1N9STAyi , M1N9STAzi , M1N9STVxi , & + M1N9STVyi , M1N9STVzi , M1N9Vxi , M1N9Vyi , M1N9Vzi , M2N1Axi , M2N1Ayi , & + M2N1Azi , M2N1DynP , M2N1FAFxi , M2N1FAFyi , M2N1FAFzi , M2N1FAGxi , M2N1FAGyi , & + M2N1FAGzi , M2N1FAMxi , M2N1FAMyi , M2N1FAMzi , M2N1FBFxi , M2N1FBFyi , M2N1FBFzi , & + M2N1FBxi , M2N1FByi , M2N1FBzi , M2N1FDxi , M2N1FDyi , M2N1FDzi , M2N1FIxi , & + M2N1FIyi , M2N1FIzi , M2N1FMGxi , M2N1FMGyi , M2N1FMGzi , M2N1MAFxi , M2N1MAFyi , & + M2N1MAFzi , M2N1MAGxi , M2N1MAGyi , M2N1MAGzi , M2N1MBFxi , M2N1MBFyi , M2N1MBFzi , & + M2N1MBxi , M2N1MByi , M2N1MBzi , M2N1MMGxi , M2N1MMGyi , M2N1MMGzi , M2N1STAxi , & + M2N1STAyi , M2N1STAzi , M2N1STVxi , M2N1STVyi , M2N1STVzi , M2N1Vxi , M2N1Vyi , & + M2N1Vzi , M2N2Axi , M2N2Ayi , M2N2Azi , M2N2DynP , M2N2FAFxi , M2N2FAFyi , & + M2N2FAFzi , M2N2FAGxi , M2N2FAGyi , M2N2FAGzi , M2N2FAMxi , M2N2FAMyi , M2N2FAMzi , & + M2N2FBFxi , M2N2FBFyi , M2N2FBFzi , M2N2FBxi , M2N2FByi , M2N2FBzi , M2N2FDxi , & + M2N2FDyi , M2N2FDzi , M2N2FIxi , M2N2FIyi , M2N2FIzi , M2N2FMGxi , M2N2FMGyi , & + M2N2FMGzi , M2N2MAFxi , M2N2MAFyi , M2N2MAFzi , M2N2MAGxi , M2N2MAGyi , M2N2MAGzi , & + M2N2MBFxi , M2N2MBFyi , M2N2MBFzi , M2N2MBxi , M2N2MByi , M2N2MBzi , M2N2MMGxi , & + M2N2MMGyi , M2N2MMGzi , M2N2STAxi , M2N2STAyi , M2N2STAzi , M2N2STVxi , M2N2STVyi , & + M2N2STVzi , M2N2Vxi , M2N2Vyi , M2N2Vzi , M2N3Axi , M2N3Ayi , M2N3Azi , & + M2N3DynP , M2N3FAFxi , M2N3FAFyi , M2N3FAFzi , M2N3FAGxi , M2N3FAGyi , M2N3FAGzi , & + M2N3FAMxi , M2N3FAMyi , M2N3FAMzi , M2N3FBFxi , M2N3FBFyi , M2N3FBFzi , M2N3FBxi , & + M2N3FByi , M2N3FBzi , M2N3FDxi , M2N3FDyi , M2N3FDzi , M2N3FIxi , M2N3FIyi , & + M2N3FIzi , M2N3FMGxi , M2N3FMGyi , M2N3FMGzi , M2N3MAFxi , M2N3MAFyi , M2N3MAFzi , & + M2N3MAGxi , M2N3MAGyi , M2N3MAGzi , M2N3MBFxi , M2N3MBFyi , M2N3MBFzi , M2N3MBxi , & + M2N3MByi , M2N3MBzi , M2N3MMGxi /) + ParamIndxAry(1001:1500) = (/ & + M2N3MMGyi , M2N3MMGzi , M2N3STAxi , M2N3STAyi , M2N3STAzi , M2N3STVxi , M2N3STVyi , & + M2N3STVzi , M2N3Vxi , M2N3Vyi , M2N3Vzi , M2N4Axi , M2N4Ayi , M2N4Azi , & + M2N4DynP , M2N4FAFxi , M2N4FAFyi , M2N4FAFzi , M2N4FAGxi , M2N4FAGyi , M2N4FAGzi , & + M2N4FAMxi , M2N4FAMyi , M2N4FAMzi , M2N4FBFxi , M2N4FBFyi , M2N4FBFzi , M2N4FBxi , & + M2N4FByi , M2N4FBzi , M2N4FDxi , M2N4FDyi , M2N4FDzi , M2N4FIxi , M2N4FIyi , & + M2N4FIzi , M2N4FMGxi , M2N4FMGyi , M2N4FMGzi , M2N4MAFxi , M2N4MAFyi , M2N4MAFzi , & + M2N4MAGxi , M2N4MAGyi , M2N4MAGzi , M2N4MBFxi , M2N4MBFyi , M2N4MBFzi , M2N4MBxi , & + M2N4MByi , M2N4MBzi , M2N4MMGxi , M2N4MMGyi , M2N4MMGzi , M2N4STAxi , M2N4STAyi , & + M2N4STAzi , M2N4STVxi , M2N4STVyi , M2N4STVzi , M2N4Vxi , M2N4Vyi , M2N4Vzi , & + M2N5Axi , M2N5Ayi , M2N5Azi , M2N5DynP , M2N5FAFxi , M2N5FAFyi , M2N5FAFzi , & + M2N5FAGxi , M2N5FAGyi , M2N5FAGzi , M2N5FAMxi , M2N5FAMyi , M2N5FAMzi , M2N5FBFxi , & + M2N5FBFyi , M2N5FBFzi , M2N5FBxi , M2N5FByi , M2N5FBzi , M2N5FDxi , M2N5FDyi , & + M2N5FDzi , M2N5FIxi , M2N5FIyi , M2N5FIzi , M2N5FMGxi , M2N5FMGyi , M2N5FMGzi , & + M2N5MAFxi , M2N5MAFyi , M2N5MAFzi , M2N5MAGxi , M2N5MAGyi , M2N5MAGzi , M2N5MBFxi , & + M2N5MBFyi , M2N5MBFzi , M2N5MBxi , M2N5MByi , M2N5MBzi , M2N5MMGxi , M2N5MMGyi , & + M2N5MMGzi , M2N5STAxi , M2N5STAyi , M2N5STAzi , M2N5STVxi , M2N5STVyi , M2N5STVzi , & + M2N5Vxi , M2N5Vyi , M2N5Vzi , M2N6Axi , M2N6Ayi , M2N6Azi , M2N6DynP , & + M2N6FAFxi , M2N6FAFyi , M2N6FAFzi , M2N6FAGxi , M2N6FAGyi , M2N6FAGzi , M2N6FAMxi , & + M2N6FAMyi , M2N6FAMzi , M2N6FBFxi , M2N6FBFyi , M2N6FBFzi , M2N6FBxi , M2N6FByi , & + M2N6FBzi , M2N6FDxi , M2N6FDyi , M2N6FDzi , M2N6FIxi , M2N6FIyi , M2N6FIzi , & + M2N6FMGxi , M2N6FMGyi , M2N6FMGzi , M2N6MAFxi , M2N6MAFyi , M2N6MAFzi , M2N6MAGxi , & + M2N6MAGyi , M2N6MAGzi , M2N6MBFxi , M2N6MBFyi , M2N6MBFzi , M2N6MBxi , M2N6MByi , & + M2N6MBzi , M2N6MMGxi , M2N6MMGyi , M2N6MMGzi , M2N6STAxi , M2N6STAyi , M2N6STAzi , & + M2N6STVxi , M2N6STVyi , M2N6STVzi , M2N6Vxi , M2N6Vyi , M2N6Vzi , M2N7Axi , & + M2N7Ayi , M2N7Azi , M2N7DynP , M2N7FAFxi , M2N7FAFyi , M2N7FAFzi , M2N7FAGxi , & + M2N7FAGyi , M2N7FAGzi , M2N7FAMxi , M2N7FAMyi , M2N7FAMzi , M2N7FBFxi , M2N7FBFyi , & + M2N7FBFzi , M2N7FBxi , M2N7FByi , M2N7FBzi , M2N7FDxi , M2N7FDyi , M2N7FDzi , & + M2N7FIxi , M2N7FIyi , M2N7FIzi , M2N7FMGxi , M2N7FMGyi , M2N7FMGzi , M2N7MAFxi , & + M2N7MAFyi , M2N7MAFzi , M2N7MAGxi , M2N7MAGyi , M2N7MAGzi , M2N7MBFxi , M2N7MBFyi , & + M2N7MBFzi , M2N7MBxi , M2N7MByi , M2N7MBzi , M2N7MMGxi , M2N7MMGyi , M2N7MMGzi , & + M2N7STAxi , M2N7STAyi , M2N7STAzi , M2N7STVxi , M2N7STVyi , M2N7STVzi , M2N7Vxi , & + M2N7Vyi , M2N7Vzi , M2N8Axi , M2N8Ayi , M2N8Azi , M2N8DynP , M2N8FAFxi , & + M2N8FAFyi , M2N8FAFzi , M2N8FAGxi , M2N8FAGyi , M2N8FAGzi , M2N8FAMxi , M2N8FAMyi , & + M2N8FAMzi , M2N8FBFxi , M2N8FBFyi , M2N8FBFzi , M2N8FBxi , M2N8FByi , M2N8FBzi , & + M2N8FDxi , M2N8FDyi , M2N8FDzi , M2N8FIxi , M2N8FIyi , M2N8FIzi , M2N8FMGxi , & + M2N8FMGyi , M2N8FMGzi , M2N8MAFxi , M2N8MAFyi , M2N8MAFzi , M2N8MAGxi , M2N8MAGyi , & + M2N8MAGzi , M2N8MBFxi , M2N8MBFyi , M2N8MBFzi , M2N8MBxi , M2N8MByi , M2N8MBzi , & + M2N8MMGxi , M2N8MMGyi , M2N8MMGzi , M2N8STAxi , M2N8STAyi , M2N8STAzi , M2N8STVxi , & + M2N8STVyi , M2N8STVzi , M2N8Vxi , M2N8Vyi , M2N8Vzi , M2N9Axi , M2N9Ayi , & + M2N9Azi , M2N9DynP , M2N9FAFxi , M2N9FAFyi , M2N9FAFzi , M2N9FAGxi , M2N9FAGyi , & + M2N9FAGzi , M2N9FAMxi , M2N9FAMyi , M2N9FAMzi , M2N9FBFxi , M2N9FBFyi , M2N9FBFzi , & + M2N9FBxi , M2N9FByi , M2N9FBzi , M2N9FDxi , M2N9FDyi , M2N9FDzi , M2N9FIxi , & + M2N9FIyi , M2N9FIzi , M2N9FMGxi , M2N9FMGyi , M2N9FMGzi , M2N9MAFxi , M2N9MAFyi , & + M2N9MAFzi , M2N9MAGxi , M2N9MAGyi , M2N9MAGzi , M2N9MBFxi , M2N9MBFyi , M2N9MBFzi , & + M2N9MBxi , M2N9MByi , M2N9MBzi , M2N9MMGxi , M2N9MMGyi , M2N9MMGzi , M2N9STAxi , & + M2N9STAyi , M2N9STAzi , M2N9STVxi , M2N9STVyi , M2N9STVzi , M2N9Vxi , M2N9Vyi , & + M2N9Vzi , M3N1Axi , M3N1Ayi , M3N1Azi , M3N1DynP , M3N1FAFxi , M3N1FAFyi , & + M3N1FAFzi , M3N1FAGxi , M3N1FAGyi , M3N1FAGzi , M3N1FAMxi , M3N1FAMyi , M3N1FAMzi , & + M3N1FBFxi , M3N1FBFyi , M3N1FBFzi , M3N1FBxi , M3N1FByi , M3N1FBzi , M3N1FDxi , & + M3N1FDyi , M3N1FDzi , M3N1FIxi , M3N1FIyi , M3N1FIzi , M3N1FMGxi , M3N1FMGyi , & + M3N1FMGzi , M3N1MAFxi , M3N1MAFyi , M3N1MAFzi , M3N1MAGxi , M3N1MAGyi , M3N1MAGzi , & + M3N1MBFxi , M3N1MBFyi , M3N1MBFzi , M3N1MBxi , M3N1MByi , M3N1MBzi , M3N1MMGxi , & + M3N1MMGyi , M3N1MMGzi , M3N1STAxi , M3N1STAyi , M3N1STAzi , M3N1STVxi , M3N1STVyi , & + M3N1STVzi , M3N1Vxi , M3N1Vyi , M3N1Vzi , M3N2Axi , M3N2Ayi , M3N2Azi , & + M3N2DynP , M3N2FAFxi , M3N2FAFyi , M3N2FAFzi , M3N2FAGxi , M3N2FAGyi , M3N2FAGzi , & + M3N2FAMxi , M3N2FAMyi , M3N2FAMzi , M3N2FBFxi , M3N2FBFyi , M3N2FBFzi , M3N2FBxi , & + M3N2FByi , M3N2FBzi , M3N2FDxi , M3N2FDyi , M3N2FDzi , M3N2FIxi , M3N2FIyi , & + M3N2FIzi , M3N2FMGxi , M3N2FMGyi , M3N2FMGzi , M3N2MAFxi , M3N2MAFyi , M3N2MAFzi , & + M3N2MAGxi , M3N2MAGyi , M3N2MAGzi , M3N2MBFxi , M3N2MBFyi , M3N2MBFzi , M3N2MBxi , & + M3N2MByi , M3N2MBzi , M3N2MMGxi , M3N2MMGyi , M3N2MMGzi , M3N2STAxi , M3N2STAyi , & + M3N2STAzi , M3N2STVxi , M3N2STVyi , M3N2STVzi , M3N2Vxi , M3N2Vyi , M3N2Vzi , & + M3N3Axi , M3N3Ayi , M3N3Azi , M3N3DynP , M3N3FAFxi , M3N3FAFyi , M3N3FAFzi , & + M3N3FAGxi , M3N3FAGyi , M3N3FAGzi , M3N3FAMxi , M3N3FAMyi , M3N3FAMzi , M3N3FBFxi , & + M3N3FBFyi , M3N3FBFzi , M3N3FBxi , M3N3FByi , M3N3FBzi , M3N3FDxi , M3N3FDyi , & + M3N3FDzi , M3N3FIxi , M3N3FIyi , M3N3FIzi , M3N3FMGxi , M3N3FMGyi , M3N3FMGzi , & + M3N3MAFxi , M3N3MAFyi , M3N3MAFzi , M3N3MAGxi , M3N3MAGyi , M3N3MAGzi , M3N3MBFxi , & + M3N3MBFyi , M3N3MBFzi , M3N3MBxi , M3N3MByi , M3N3MBzi , M3N3MMGxi , M3N3MMGyi , & + M3N3MMGzi , M3N3STAxi , M3N3STAyi , M3N3STAzi , M3N3STVxi , M3N3STVyi , M3N3STVzi , & + M3N3Vxi , M3N3Vyi , M3N3Vzi , M3N4Axi , M3N4Ayi , M3N4Azi , M3N4DynP , & + M3N4FAFxi , M3N4FAFyi , M3N4FAFzi , M3N4FAGxi , M3N4FAGyi , M3N4FAGzi , M3N4FAMxi , & + M3N4FAMyi , M3N4FAMzi , M3N4FBFxi , M3N4FBFyi , M3N4FBFzi , M3N4FBxi , M3N4FByi , & + M3N4FBzi , M3N4FDxi , M3N4FDyi /) + ParamIndxAry(1501:2000) = (/ & + M3N4FDzi , M3N4FIxi , M3N4FIyi , M3N4FIzi , M3N4FMGxi , M3N4FMGyi , M3N4FMGzi , & + M3N4MAFxi , M3N4MAFyi , M3N4MAFzi , M3N4MAGxi , M3N4MAGyi , M3N4MAGzi , M3N4MBFxi , & + M3N4MBFyi , M3N4MBFzi , M3N4MBxi , M3N4MByi , M3N4MBzi , M3N4MMGxi , M3N4MMGyi , & + M3N4MMGzi , M3N4STAxi , M3N4STAyi , M3N4STAzi , M3N4STVxi , M3N4STVyi , M3N4STVzi , & + M3N4Vxi , M3N4Vyi , M3N4Vzi , M3N5Axi , M3N5Ayi , M3N5Azi , M3N5DynP , & + M3N5FAFxi , M3N5FAFyi , M3N5FAFzi , M3N5FAGxi , M3N5FAGyi , M3N5FAGzi , M3N5FAMxi , & + M3N5FAMyi , M3N5FAMzi , M3N5FBFxi , M3N5FBFyi , M3N5FBFzi , M3N5FBxi , M3N5FByi , & + M3N5FBzi , M3N5FDxi , M3N5FDyi , M3N5FDzi , M3N5FIxi , M3N5FIyi , M3N5FIzi , & + M3N5FMGxi , M3N5FMGyi , M3N5FMGzi , M3N5MAFxi , M3N5MAFyi , M3N5MAFzi , M3N5MAGxi , & + M3N5MAGyi , M3N5MAGzi , M3N5MBFxi , M3N5MBFyi , M3N5MBFzi , M3N5MBxi , M3N5MByi , & + M3N5MBzi , M3N5MMGxi , M3N5MMGyi , M3N5MMGzi , M3N5STAxi , M3N5STAyi , M3N5STAzi , & + M3N5STVxi , M3N5STVyi , M3N5STVzi , M3N5Vxi , M3N5Vyi , M3N5Vzi , M3N6Axi , & + M3N6Ayi , M3N6Azi , M3N6DynP , M3N6FAFxi , M3N6FAFyi , M3N6FAFzi , M3N6FAGxi , & + M3N6FAGyi , M3N6FAGzi , M3N6FAMxi , M3N6FAMyi , M3N6FAMzi , M3N6FBFxi , M3N6FBFyi , & + M3N6FBFzi , M3N6FBxi , M3N6FByi , M3N6FBzi , M3N6FDxi , M3N6FDyi , M3N6FDzi , & + M3N6FIxi , M3N6FIyi , M3N6FIzi , M3N6FMGxi , M3N6FMGyi , M3N6FMGzi , M3N6MAFxi , & + M3N6MAFyi , M3N6MAFzi , M3N6MAGxi , M3N6MAGyi , M3N6MAGzi , M3N6MBFxi , M3N6MBFyi , & + M3N6MBFzi , M3N6MBxi , M3N6MByi , M3N6MBzi , M3N6MMGxi , M3N6MMGyi , M3N6MMGzi , & + M3N6STAxi , M3N6STAyi , M3N6STAzi , M3N6STVxi , M3N6STVyi , M3N6STVzi , M3N6Vxi , & + M3N6Vyi , M3N6Vzi , M3N7Axi , M3N7Ayi , M3N7Azi , M3N7DynP , M3N7FAFxi , & + M3N7FAFyi , M3N7FAFzi , M3N7FAGxi , M3N7FAGyi , M3N7FAGzi , M3N7FAMxi , M3N7FAMyi , & + M3N7FAMzi , M3N7FBFxi , M3N7FBFyi , M3N7FBFzi , M3N7FBxi , M3N7FByi , M3N7FBzi , & + M3N7FDxi , M3N7FDyi , M3N7FDzi , M3N7FIxi , M3N7FIyi , M3N7FIzi , M3N7FMGxi , & + M3N7FMGyi , M3N7FMGzi , M3N7MAFxi , M3N7MAFyi , M3N7MAFzi , M3N7MAGxi , M3N7MAGyi , & + M3N7MAGzi , M3N7MBFxi , M3N7MBFyi , M3N7MBFzi , M3N7MBxi , M3N7MByi , M3N7MBzi , & + M3N7MMGxi , M3N7MMGyi , M3N7MMGzi , M3N7STAxi , M3N7STAyi , M3N7STAzi , M3N7STVxi , & + M3N7STVyi , M3N7STVzi , M3N7Vxi , M3N7Vyi , M3N7Vzi , M3N8Axi , M3N8Ayi , & + M3N8Azi , M3N8DynP , M3N8FAFxi , M3N8FAFyi , M3N8FAFzi , M3N8FAGxi , M3N8FAGyi , & + M3N8FAGzi , M3N8FAMxi , M3N8FAMyi , M3N8FAMzi , M3N8FBFxi , M3N8FBFyi , M3N8FBFzi , & + M3N8FBxi , M3N8FByi , M3N8FBzi , M3N8FDxi , M3N8FDyi , M3N8FDzi , M3N8FIxi , & + M3N8FIyi , M3N8FIzi , M3N8FMGxi , M3N8FMGyi , M3N8FMGzi , M3N8MAFxi , M3N8MAFyi , & + M3N8MAFzi , M3N8MAGxi , M3N8MAGyi , M3N8MAGzi , M3N8MBFxi , M3N8MBFyi , M3N8MBFzi , & + M3N8MBxi , M3N8MByi , M3N8MBzi , M3N8MMGxi , M3N8MMGyi , M3N8MMGzi , M3N8STAxi , & + M3N8STAyi , M3N8STAzi , M3N8STVxi , M3N8STVyi , M3N8STVzi , M3N8Vxi , M3N8Vyi , & + M3N8Vzi , M3N9Axi , M3N9Ayi , M3N9Azi , M3N9DynP , M3N9FAFxi , M3N9FAFyi , & + M3N9FAFzi , M3N9FAGxi , M3N9FAGyi , M3N9FAGzi , M3N9FAMxi , M3N9FAMyi , M3N9FAMzi , & + M3N9FBFxi , M3N9FBFyi , M3N9FBFzi , M3N9FBxi , M3N9FByi , M3N9FBzi , M3N9FDxi , & + M3N9FDyi , M3N9FDzi , M3N9FIxi , M3N9FIyi , M3N9FIzi , M3N9FMGxi , M3N9FMGyi , & + M3N9FMGzi , M3N9MAFxi , M3N9MAFyi , M3N9MAFzi , M3N9MAGxi , M3N9MAGyi , M3N9MAGzi , & + M3N9MBFxi , M3N9MBFyi , M3N9MBFzi , M3N9MBxi , M3N9MByi , M3N9MBzi , M3N9MMGxi , & + M3N9MMGyi , M3N9MMGzi , M3N9STAxi , M3N9STAyi , M3N9STAzi , M3N9STVxi , M3N9STVyi , & + M3N9STVzi , M3N9Vxi , M3N9Vyi , M3N9Vzi , M4N1Axi , M4N1Ayi , M4N1Azi , & + M4N1DynP , M4N1FAFxi , M4N1FAFyi , M4N1FAFzi , M4N1FAGxi , M4N1FAGyi , M4N1FAGzi , & + M4N1FAMxi , M4N1FAMyi , M4N1FAMzi , M4N1FBFxi , M4N1FBFyi , M4N1FBFzi , M4N1FBxi , & + M4N1FByi , M4N1FBzi , M4N1FDxi , M4N1FDyi , M4N1FDzi , M4N1FIxi , M4N1FIyi , & + M4N1FIzi , M4N1FMGxi , M4N1FMGyi , M4N1FMGzi , M4N1MAFxi , M4N1MAFyi , M4N1MAFzi , & + M4N1MAGxi , M4N1MAGyi , M4N1MAGzi , M4N1MBFxi , M4N1MBFyi , M4N1MBFzi , M4N1MBxi , & + M4N1MByi , M4N1MBzi , M4N1MMGxi , M4N1MMGyi , M4N1MMGzi , M4N1STAxi , M4N1STAyi , & + M4N1STAzi , M4N1STVxi , M4N1STVyi , M4N1STVzi , M4N1Vxi , M4N1Vyi , M4N1Vzi , & + M4N2Axi , M4N2Ayi , M4N2Azi , M4N2DynP , M4N2FAFxi , M4N2FAFyi , M4N2FAFzi , & + M4N2FAGxi , M4N2FAGyi , M4N2FAGzi , M4N2FAMxi , M4N2FAMyi , M4N2FAMzi , M4N2FBFxi , & + M4N2FBFyi , M4N2FBFzi , M4N2FBxi , M4N2FByi , M4N2FBzi , M4N2FDxi , M4N2FDyi , & + M4N2FDzi , M4N2FIxi , M4N2FIyi , M4N2FIzi , M4N2FMGxi , M4N2FMGyi , M4N2FMGzi , & + M4N2MAFxi , M4N2MAFyi , M4N2MAFzi , M4N2MAGxi , M4N2MAGyi , M4N2MAGzi , M4N2MBFxi , & + M4N2MBFyi , M4N2MBFzi , M4N2MBxi , M4N2MByi , M4N2MBzi , M4N2MMGxi , M4N2MMGyi , & + M4N2MMGzi , M4N2STAxi , M4N2STAyi , M4N2STAzi , M4N2STVxi , M4N2STVyi , M4N2STVzi , & + M4N2Vxi , M4N2Vyi , M4N2Vzi , M4N3Axi , M4N3Ayi , M4N3Azi , M4N3DynP , & + M4N3FAFxi , M4N3FAFyi , M4N3FAFzi , M4N3FAGxi , M4N3FAGyi , M4N3FAGzi , M4N3FAMxi , & + M4N3FAMyi , M4N3FAMzi , M4N3FBFxi , M4N3FBFyi , M4N3FBFzi , M4N3FBxi , M4N3FByi , & + M4N3FBzi , M4N3FDxi , M4N3FDyi , M4N3FDzi , M4N3FIxi , M4N3FIyi , M4N3FIzi , & + M4N3FMGxi , M4N3FMGyi , M4N3FMGzi , M4N3MAFxi , M4N3MAFyi , M4N3MAFzi , M4N3MAGxi , & + M4N3MAGyi , M4N3MAGzi , M4N3MBFxi , M4N3MBFyi , M4N3MBFzi , M4N3MBxi , M4N3MByi , & + M4N3MBzi , M4N3MMGxi , M4N3MMGyi , M4N3MMGzi , M4N3STAxi , M4N3STAyi , M4N3STAzi , & + M4N3STVxi , M4N3STVyi , M4N3STVzi , M4N3Vxi , M4N3Vyi , M4N3Vzi , M4N4Axi , & + M4N4Ayi , M4N4Azi , M4N4DynP , M4N4FAFxi , M4N4FAFyi , M4N4FAFzi , M4N4FAGxi , & + M4N4FAGyi , M4N4FAGzi , M4N4FAMxi , M4N4FAMyi , M4N4FAMzi , M4N4FBFxi , M4N4FBFyi , & + M4N4FBFzi , M4N4FBxi , M4N4FByi , M4N4FBzi , M4N4FDxi , M4N4FDyi , M4N4FDzi , & + M4N4FIxi , M4N4FIyi , M4N4FIzi , M4N4FMGxi , M4N4FMGyi , M4N4FMGzi , M4N4MAFxi , & + M4N4MAFyi , M4N4MAFzi , M4N4MAGxi , M4N4MAGyi , M4N4MAGzi , M4N4MBFxi , M4N4MBFyi , & + M4N4MBFzi , M4N4MBxi , M4N4MByi , M4N4MBzi , M4N4MMGxi , M4N4MMGyi , M4N4MMGzi , & + M4N4STAxi , M4N4STAyi , M4N4STAzi , M4N4STVxi , M4N4STVyi , M4N4STVzi , M4N4Vxi , & + M4N4Vyi , M4N4Vzi , M4N5Axi /) + ParamIndxAry(2001:2500) = (/ & + M4N5Ayi , M4N5Azi , M4N5DynP , M4N5FAFxi , M4N5FAFyi , M4N5FAFzi , M4N5FAGxi , & + M4N5FAGyi , M4N5FAGzi , M4N5FAMxi , M4N5FAMyi , M4N5FAMzi , M4N5FBFxi , M4N5FBFyi , & + M4N5FBFzi , M4N5FBxi , M4N5FByi , M4N5FBzi , M4N5FDxi , M4N5FDyi , M4N5FDzi , & + M4N5FIxi , M4N5FIyi , M4N5FIzi , M4N5FMGxi , M4N5FMGyi , M4N5FMGzi , M4N5MAFxi , & + M4N5MAFyi , M4N5MAFzi , M4N5MAGxi , M4N5MAGyi , M4N5MAGzi , M4N5MBFxi , M4N5MBFyi , & + M4N5MBFzi , M4N5MBxi , M4N5MByi , M4N5MBzi , M4N5MMGxi , M4N5MMGyi , M4N5MMGzi , & + M4N5STAxi , M4N5STAyi , M4N5STAzi , M4N5STVxi , M4N5STVyi , M4N5STVzi , M4N5Vxi , & + M4N5Vyi , M4N5Vzi , M4N6Axi , M4N6Ayi , M4N6Azi , M4N6DynP , M4N6FAFxi , & + M4N6FAFyi , M4N6FAFzi , M4N6FAGxi , M4N6FAGyi , M4N6FAGzi , M4N6FAMxi , M4N6FAMyi , & + M4N6FAMzi , M4N6FBFxi , M4N6FBFyi , M4N6FBFzi , M4N6FBxi , M4N6FByi , M4N6FBzi , & + M4N6FDxi , M4N6FDyi , M4N6FDzi , M4N6FIxi , M4N6FIyi , M4N6FIzi , M4N6FMGxi , & + M4N6FMGyi , M4N6FMGzi , M4N6MAFxi , M4N6MAFyi , M4N6MAFzi , M4N6MAGxi , M4N6MAGyi , & + M4N6MAGzi , M4N6MBFxi , M4N6MBFyi , M4N6MBFzi , M4N6MBxi , M4N6MByi , M4N6MBzi , & + M4N6MMGxi , M4N6MMGyi , M4N6MMGzi , M4N6STAxi , M4N6STAyi , M4N6STAzi , M4N6STVxi , & + M4N6STVyi , M4N6STVzi , M4N6Vxi , M4N6Vyi , M4N6Vzi , M4N7Axi , M4N7Ayi , & + M4N7Azi , M4N7DynP , M4N7FAFxi , M4N7FAFyi , M4N7FAFzi , M4N7FAGxi , M4N7FAGyi , & + M4N7FAGzi , M4N7FAMxi , M4N7FAMyi , M4N7FAMzi , M4N7FBFxi , M4N7FBFyi , M4N7FBFzi , & + M4N7FBxi , M4N7FByi , M4N7FBzi , M4N7FDxi , M4N7FDyi , M4N7FDzi , M4N7FIxi , & + M4N7FIyi , M4N7FIzi , M4N7FMGxi , M4N7FMGyi , M4N7FMGzi , M4N7MAFxi , M4N7MAFyi , & + M4N7MAFzi , M4N7MAGxi , M4N7MAGyi , M4N7MAGzi , M4N7MBFxi , M4N7MBFyi , M4N7MBFzi , & + M4N7MBxi , M4N7MByi , M4N7MBzi , M4N7MMGxi , M4N7MMGyi , M4N7MMGzi , M4N7STAxi , & + M4N7STAyi , M4N7STAzi , M4N7STVxi , M4N7STVyi , M4N7STVzi , M4N7Vxi , M4N7Vyi , & + M4N7Vzi , M4N8Axi , M4N8Ayi , M4N8Azi , M4N8DynP , M4N8FAFxi , M4N8FAFyi , & + M4N8FAFzi , M4N8FAGxi , M4N8FAGyi , M4N8FAGzi , M4N8FAMxi , M4N8FAMyi , M4N8FAMzi , & + M4N8FBFxi , M4N8FBFyi , M4N8FBFzi , M4N8FBxi , M4N8FByi , M4N8FBzi , M4N8FDxi , & + M4N8FDyi , M4N8FDzi , M4N8FIxi , M4N8FIyi , M4N8FIzi , M4N8FMGxi , M4N8FMGyi , & + M4N8FMGzi , M4N8MAFxi , M4N8MAFyi , M4N8MAFzi , M4N8MAGxi , M4N8MAGyi , M4N8MAGzi , & + M4N8MBFxi , M4N8MBFyi , M4N8MBFzi , M4N8MBxi , M4N8MByi , M4N8MBzi , M4N8MMGxi , & + M4N8MMGyi , M4N8MMGzi , M4N8STAxi , M4N8STAyi , M4N8STAzi , M4N8STVxi , M4N8STVyi , & + M4N8STVzi , M4N8Vxi , M4N8Vyi , M4N8Vzi , M4N9Axi , M4N9Ayi , M4N9Azi , & + M4N9DynP , M4N9FAFxi , M4N9FAFyi , M4N9FAFzi , M4N9FAGxi , M4N9FAGyi , M4N9FAGzi , & + M4N9FAMxi , M4N9FAMyi , M4N9FAMzi , M4N9FBFxi , M4N9FBFyi , M4N9FBFzi , M4N9FBxi , & + M4N9FByi , M4N9FBzi , M4N9FDxi , M4N9FDyi , M4N9FDzi , M4N9FIxi , M4N9FIyi , & + M4N9FIzi , M4N9FMGxi , M4N9FMGyi , M4N9FMGzi , M4N9MAFxi , M4N9MAFyi , M4N9MAFzi , & + M4N9MAGxi , M4N9MAGyi , M4N9MAGzi , M4N9MBFxi , M4N9MBFyi , M4N9MBFzi , M4N9MBxi , & + M4N9MByi , M4N9MBzi , M4N9MMGxi , M4N9MMGyi , M4N9MMGzi , M4N9STAxi , M4N9STAyi , & + M4N9STAzi , M4N9STVxi , M4N9STVyi , M4N9STVzi , M4N9Vxi , M4N9Vyi , M4N9Vzi , & + M5N1Axi , M5N1Ayi , M5N1Azi , M5N1DynP , M5N1FAFxi , M5N1FAFyi , M5N1FAFzi , & + M5N1FAGxi , M5N1FAGyi , M5N1FAGzi , M5N1FAMxi , M5N1FAMyi , M5N1FAMzi , M5N1FBFxi , & + M5N1FBFyi , M5N1FBFzi , M5N1FBxi , M5N1FByi , M5N1FBzi , M5N1FDxi , M5N1FDyi , & + M5N1FDzi , M5N1FIxi , M5N1FIyi , M5N1FIzi , M5N1FMGxi , M5N1FMGyi , M5N1FMGzi , & + M5N1MAFxi , M5N1MAFyi , M5N1MAFzi , M5N1MAGxi , M5N1MAGyi , M5N1MAGzi , M5N1MBFxi , & + M5N1MBFyi , M5N1MBFzi , M5N1MBxi , M5N1MByi , M5N1MBzi , M5N1MMGxi , M5N1MMGyi , & + M5N1MMGzi , M5N1STAxi , M5N1STAyi , M5N1STAzi , M5N1STVxi , M5N1STVyi , M5N1STVzi , & + M5N1Vxi , M5N1Vyi , M5N1Vzi , M5N2Axi , M5N2Ayi , M5N2Azi , M5N2DynP , & + M5N2FAFxi , M5N2FAFyi , M5N2FAFzi , M5N2FAGxi , M5N2FAGyi , M5N2FAGzi , M5N2FAMxi , & + M5N2FAMyi , M5N2FAMzi , M5N2FBFxi , M5N2FBFyi , M5N2FBFzi , M5N2FBxi , M5N2FByi , & + M5N2FBzi , M5N2FDxi , M5N2FDyi , M5N2FDzi , M5N2FIxi , M5N2FIyi , M5N2FIzi , & + M5N2FMGxi , M5N2FMGyi , M5N2FMGzi , M5N2MAFxi , M5N2MAFyi , M5N2MAFzi , M5N2MAGxi , & + M5N2MAGyi , M5N2MAGzi , M5N2MBFxi , M5N2MBFyi , M5N2MBFzi , M5N2MBxi , M5N2MByi , & + M5N2MBzi , M5N2MMGxi , M5N2MMGyi , M5N2MMGzi , M5N2STAxi , M5N2STAyi , M5N2STAzi , & + M5N2STVxi , M5N2STVyi , M5N2STVzi , M5N2Vxi , M5N2Vyi , M5N2Vzi , M5N3Axi , & + M5N3Ayi , M5N3Azi , M5N3DynP , M5N3FAFxi , M5N3FAFyi , M5N3FAFzi , M5N3FAGxi , & + M5N3FAGyi , M5N3FAGzi , M5N3FAMxi , M5N3FAMyi , M5N3FAMzi , M5N3FBFxi , M5N3FBFyi , & + M5N3FBFzi , M5N3FBxi , M5N3FByi , M5N3FBzi , M5N3FDxi , M5N3FDyi , M5N3FDzi , & + M5N3FIxi , M5N3FIyi , M5N3FIzi , M5N3FMGxi , M5N3FMGyi , M5N3FMGzi , M5N3MAFxi , & + M5N3MAFyi , M5N3MAFzi , M5N3MAGxi , M5N3MAGyi , M5N3MAGzi , M5N3MBFxi , M5N3MBFyi , & + M5N3MBFzi , M5N3MBxi , M5N3MByi , M5N3MBzi , M5N3MMGxi , M5N3MMGyi , M5N3MMGzi , & + M5N3STAxi , M5N3STAyi , M5N3STAzi , M5N3STVxi , M5N3STVyi , M5N3STVzi , M5N3Vxi , & + M5N3Vyi , M5N3Vzi , M5N4Axi , M5N4Ayi , M5N4Azi , M5N4DynP , M5N4FAFxi , & + M5N4FAFyi , M5N4FAFzi , M5N4FAGxi , M5N4FAGyi , M5N4FAGzi , M5N4FAMxi , M5N4FAMyi , & + M5N4FAMzi , M5N4FBFxi , M5N4FBFyi , M5N4FBFzi , M5N4FBxi , M5N4FByi , M5N4FBzi , & + M5N4FDxi , M5N4FDyi , M5N4FDzi , M5N4FIxi , M5N4FIyi , M5N4FIzi , M5N4FMGxi , & + M5N4FMGyi , M5N4FMGzi , M5N4MAFxi , M5N4MAFyi , M5N4MAFzi , M5N4MAGxi , M5N4MAGyi , & + M5N4MAGzi , M5N4MBFxi , M5N4MBFyi , M5N4MBFzi , M5N4MBxi , M5N4MByi , M5N4MBzi , & + M5N4MMGxi , M5N4MMGyi , M5N4MMGzi , M5N4STAxi , M5N4STAyi , M5N4STAzi , M5N4STVxi , & + M5N4STVyi , M5N4STVzi , M5N4Vxi , M5N4Vyi , M5N4Vzi , M5N5Axi , M5N5Ayi , & + M5N5Azi , M5N5DynP , M5N5FAFxi , M5N5FAFyi , M5N5FAFzi , M5N5FAGxi , M5N5FAGyi , & + M5N5FAGzi , M5N5FAMxi , M5N5FAMyi , M5N5FAMzi , M5N5FBFxi , M5N5FBFyi , M5N5FBFzi , & + M5N5FBxi , M5N5FByi , M5N5FBzi , M5N5FDxi , M5N5FDyi , M5N5FDzi , M5N5FIxi , & + M5N5FIyi , M5N5FIzi , M5N5FMGxi , M5N5FMGyi , M5N5FMGzi , M5N5MAFxi , M5N5MAFyi , & + M5N5MAFzi , M5N5MAGxi , M5N5MAGyi /) + ParamIndxAry(2501:3000) = (/ & + M5N5MAGzi , M5N5MBFxi , M5N5MBFyi , M5N5MBFzi , M5N5MBxi , M5N5MByi , M5N5MBzi , & + M5N5MMGxi , M5N5MMGyi , M5N5MMGzi , M5N5STAxi , M5N5STAyi , M5N5STAzi , M5N5STVxi , & + M5N5STVyi , M5N5STVzi , M5N5Vxi , M5N5Vyi , M5N5Vzi , M5N6Axi , M5N6Ayi , & + M5N6Azi , M5N6DynP , M5N6FAFxi , M5N6FAFyi , M5N6FAFzi , M5N6FAGxi , M5N6FAGyi , & + M5N6FAGzi , M5N6FAMxi , M5N6FAMyi , M5N6FAMzi , M5N6FBFxi , M5N6FBFyi , M5N6FBFzi , & + M5N6FBxi , M5N6FByi , M5N6FBzi , M5N6FDxi , M5N6FDyi , M5N6FDzi , M5N6FIxi , & + M5N6FIyi , M5N6FIzi , M5N6FMGxi , M5N6FMGyi , M5N6FMGzi , M5N6MAFxi , M5N6MAFyi , & + M5N6MAFzi , M5N6MAGxi , M5N6MAGyi , M5N6MAGzi , M5N6MBFxi , M5N6MBFyi , M5N6MBFzi , & + M5N6MBxi , M5N6MByi , M5N6MBzi , M5N6MMGxi , M5N6MMGyi , M5N6MMGzi , M5N6STAxi , & + M5N6STAyi , M5N6STAzi , M5N6STVxi , M5N6STVyi , M5N6STVzi , M5N6Vxi , M5N6Vyi , & + M5N6Vzi , M5N7Axi , M5N7Ayi , M5N7Azi , M5N7DynP , M5N7FAFxi , M5N7FAFyi , & + M5N7FAFzi , M5N7FAGxi , M5N7FAGyi , M5N7FAGzi , M5N7FAMxi , M5N7FAMyi , M5N7FAMzi , & + M5N7FBFxi , M5N7FBFyi , M5N7FBFzi , M5N7FBxi , M5N7FByi , M5N7FBzi , M5N7FDxi , & + M5N7FDyi , M5N7FDzi , M5N7FIxi , M5N7FIyi , M5N7FIzi , M5N7FMGxi , M5N7FMGyi , & + M5N7FMGzi , M5N7MAFxi , M5N7MAFyi , M5N7MAFzi , M5N7MAGxi , M5N7MAGyi , M5N7MAGzi , & + M5N7MBFxi , M5N7MBFyi , M5N7MBFzi , M5N7MBxi , M5N7MByi , M5N7MBzi , M5N7MMGxi , & + M5N7MMGyi , M5N7MMGzi , M5N7STAxi , M5N7STAyi , M5N7STAzi , M5N7STVxi , M5N7STVyi , & + M5N7STVzi , M5N7Vxi , M5N7Vyi , M5N7Vzi , M5N8Axi , M5N8Ayi , M5N8Azi , & + M5N8DynP , M5N8FAFxi , M5N8FAFyi , M5N8FAFzi , M5N8FAGxi , M5N8FAGyi , M5N8FAGzi , & + M5N8FAMxi , M5N8FAMyi , M5N8FAMzi , M5N8FBFxi , M5N8FBFyi , M5N8FBFzi , M5N8FBxi , & + M5N8FByi , M5N8FBzi , M5N8FDxi , M5N8FDyi , M5N8FDzi , M5N8FIxi , M5N8FIyi , & + M5N8FIzi , M5N8FMGxi , M5N8FMGyi , M5N8FMGzi , M5N8MAFxi , M5N8MAFyi , M5N8MAFzi , & + M5N8MAGxi , M5N8MAGyi , M5N8MAGzi , M5N8MBFxi , M5N8MBFyi , M5N8MBFzi , M5N8MBxi , & + M5N8MByi , M5N8MBzi , M5N8MMGxi , M5N8MMGyi , M5N8MMGzi , M5N8STAxi , M5N8STAyi , & + M5N8STAzi , M5N8STVxi , M5N8STVyi , M5N8STVzi , M5N8Vxi , M5N8Vyi , M5N8Vzi , & + M5N9Axi , M5N9Ayi , M5N9Azi , M5N9DynP , M5N9FAFxi , M5N9FAFyi , M5N9FAFzi , & + M5N9FAGxi , M5N9FAGyi , M5N9FAGzi , M5N9FAMxi , M5N9FAMyi , M5N9FAMzi , M5N9FBFxi , & + M5N9FBFyi , M5N9FBFzi , M5N9FBxi , M5N9FByi , M5N9FBzi , M5N9FDxi , M5N9FDyi , & + M5N9FDzi , M5N9FIxi , M5N9FIyi , M5N9FIzi , M5N9FMGxi , M5N9FMGyi , M5N9FMGzi , & + M5N9MAFxi , M5N9MAFyi , M5N9MAFzi , M5N9MAGxi , M5N9MAGyi , M5N9MAGzi , M5N9MBFxi , & + M5N9MBFyi , M5N9MBFzi , M5N9MBxi , M5N9MByi , M5N9MBzi , M5N9MMGxi , M5N9MMGyi , & + M5N9MMGzi , M5N9STAxi , M5N9STAyi , M5N9STAzi , M5N9STVxi , M5N9STVyi , M5N9STVzi , & + M5N9Vxi , M5N9Vyi , M5N9Vzi , M6N1Axi , M6N1Ayi , M6N1Azi , M6N1DynP , & + M6N1FAFxi , M6N1FAFyi , M6N1FAFzi , M6N1FAGxi , M6N1FAGyi , M6N1FAGzi , M6N1FAMxi , & + M6N1FAMyi , M6N1FAMzi , M6N1FBFxi , M6N1FBFyi , M6N1FBFzi , M6N1FBxi , M6N1FByi , & + M6N1FBzi , M6N1FDxi , M6N1FDyi , M6N1FDzi , M6N1FIxi , M6N1FIyi , M6N1FIzi , & + M6N1FMGxi , M6N1FMGyi , M6N1FMGzi , M6N1MAFxi , M6N1MAFyi , M6N1MAFzi , M6N1MAGxi , & + M6N1MAGyi , M6N1MAGzi , M6N1MBFxi , M6N1MBFyi , M6N1MBFzi , M6N1MBxi , M6N1MByi , & + M6N1MBzi , M6N1MMGxi , M6N1MMGyi , M6N1MMGzi , M6N1STAxi , M6N1STAyi , M6N1STAzi , & + M6N1STVxi , M6N1STVyi , M6N1STVzi , M6N1Vxi , M6N1Vyi , M6N1Vzi , M6N2Axi , & + M6N2Ayi , M6N2Azi , M6N2DynP , M6N2FAFxi , M6N2FAFyi , M6N2FAFzi , M6N2FAGxi , & + M6N2FAGyi , M6N2FAGzi , M6N2FAMxi , M6N2FAMyi , M6N2FAMzi , M6N2FBFxi , M6N2FBFyi , & + M6N2FBFzi , M6N2FBxi , M6N2FByi , M6N2FBzi , M6N2FDxi , M6N2FDyi , M6N2FDzi , & + M6N2FIxi , M6N2FIyi , M6N2FIzi , M6N2FMGxi , M6N2FMGyi , M6N2FMGzi , M6N2MAFxi , & + M6N2MAFyi , M6N2MAFzi , M6N2MAGxi , M6N2MAGyi , M6N2MAGzi , M6N2MBFxi , M6N2MBFyi , & + M6N2MBFzi , M6N2MBxi , M6N2MByi , M6N2MBzi , M6N2MMGxi , M6N2MMGyi , M6N2MMGzi , & + M6N2STAxi , M6N2STAyi , M6N2STAzi , M6N2STVxi , M6N2STVyi , M6N2STVzi , M6N2Vxi , & + M6N2Vyi , M6N2Vzi , M6N3Axi , M6N3Ayi , M6N3Azi , M6N3DynP , M6N3FAFxi , & + M6N3FAFyi , M6N3FAFzi , M6N3FAGxi , M6N3FAGyi , M6N3FAGzi , M6N3FAMxi , M6N3FAMyi , & + M6N3FAMzi , M6N3FBFxi , M6N3FBFyi , M6N3FBFzi , M6N3FBxi , M6N3FByi , M6N3FBzi , & + M6N3FDxi , M6N3FDyi , M6N3FDzi , M6N3FIxi , M6N3FIyi , M6N3FIzi , M6N3FMGxi , & + M6N3FMGyi , M6N3FMGzi , M6N3MAFxi , M6N3MAFyi , M6N3MAFzi , M6N3MAGxi , M6N3MAGyi , & + M6N3MAGzi , M6N3MBFxi , M6N3MBFyi , M6N3MBFzi , M6N3MBxi , M6N3MByi , M6N3MBzi , & + M6N3MMGxi , M6N3MMGyi , M6N3MMGzi , M6N3STAxi , M6N3STAyi , M6N3STAzi , M6N3STVxi , & + M6N3STVyi , M6N3STVzi , M6N3Vxi , M6N3Vyi , M6N3Vzi , M6N4Axi , M6N4Ayi , & + M6N4Azi , M6N4DynP , M6N4FAFxi , M6N4FAFyi , M6N4FAFzi , M6N4FAGxi , M6N4FAGyi , & + M6N4FAGzi , M6N4FAMxi , M6N4FAMyi , M6N4FAMzi , M6N4FBFxi , M6N4FBFyi , M6N4FBFzi , & + M6N4FBxi , M6N4FByi , M6N4FBzi , M6N4FDxi , M6N4FDyi , M6N4FDzi , M6N4FIxi , & + M6N4FIyi , M6N4FIzi , M6N4FMGxi , M6N4FMGyi , M6N4FMGzi , M6N4MAFxi , M6N4MAFyi , & + M6N4MAFzi , M6N4MAGxi , M6N4MAGyi , M6N4MAGzi , M6N4MBFxi , M6N4MBFyi , M6N4MBFzi , & + M6N4MBxi , M6N4MByi , M6N4MBzi , M6N4MMGxi , M6N4MMGyi , M6N4MMGzi , M6N4STAxi , & + M6N4STAyi , M6N4STAzi , M6N4STVxi , M6N4STVyi , M6N4STVzi , M6N4Vxi , M6N4Vyi , & + M6N4Vzi , M6N5Axi , M6N5Ayi , M6N5Azi , M6N5DynP , M6N5FAFxi , M6N5FAFyi , & + M6N5FAFzi , M6N5FAGxi , M6N5FAGyi , M6N5FAGzi , M6N5FAMxi , M6N5FAMyi , M6N5FAMzi , & + M6N5FBFxi , M6N5FBFyi , M6N5FBFzi , M6N5FBxi , M6N5FByi , M6N5FBzi , M6N5FDxi , & + M6N5FDyi , M6N5FDzi , M6N5FIxi , M6N5FIyi , M6N5FIzi , M6N5FMGxi , M6N5FMGyi , & + M6N5FMGzi , M6N5MAFxi , M6N5MAFyi , M6N5MAFzi , M6N5MAGxi , M6N5MAGyi , M6N5MAGzi , & + M6N5MBFxi , M6N5MBFyi , M6N5MBFzi , M6N5MBxi , M6N5MByi , M6N5MBzi , M6N5MMGxi , & + M6N5MMGyi , M6N5MMGzi , M6N5STAxi , M6N5STAyi , M6N5STAzi , M6N5STVxi , M6N5STVyi , & + M6N5STVzi , M6N5Vxi , M6N5Vyi , M6N5Vzi , M6N6Axi , M6N6Ayi , M6N6Azi , & + M6N6DynP , M6N6FAFxi , M6N6FAFyi , M6N6FAFzi , M6N6FAGxi , M6N6FAGyi , M6N6FAGzi , & + M6N6FAMxi , M6N6FAMyi , M6N6FAMzi /) + ParamIndxAry(3001:3500) = (/ & + M6N6FBFxi , M6N6FBFyi , M6N6FBFzi , M6N6FBxi , M6N6FByi , M6N6FBzi , M6N6FDxi , & + M6N6FDyi , M6N6FDzi , M6N6FIxi , M6N6FIyi , M6N6FIzi , M6N6FMGxi , M6N6FMGyi , & + M6N6FMGzi , M6N6MAFxi , M6N6MAFyi , M6N6MAFzi , M6N6MAGxi , M6N6MAGyi , M6N6MAGzi , & + M6N6MBFxi , M6N6MBFyi , M6N6MBFzi , M6N6MBxi , M6N6MByi , M6N6MBzi , M6N6MMGxi , & + M6N6MMGyi , M6N6MMGzi , M6N6STAxi , M6N6STAyi , M6N6STAzi , M6N6STVxi , M6N6STVyi , & + M6N6STVzi , M6N6Vxi , M6N6Vyi , M6N6Vzi , M6N7Axi , M6N7Ayi , M6N7Azi , & + M6N7DynP , M6N7FAFxi , M6N7FAFyi , M6N7FAFzi , M6N7FAGxi , M6N7FAGyi , M6N7FAGzi , & + M6N7FAMxi , M6N7FAMyi , M6N7FAMzi , M6N7FBFxi , M6N7FBFyi , M6N7FBFzi , M6N7FBxi , & + M6N7FByi , M6N7FBzi , M6N7FDxi , M6N7FDyi , M6N7FDzi , M6N7FIxi , M6N7FIyi , & + M6N7FIzi , M6N7FMGxi , M6N7FMGyi , M6N7FMGzi , M6N7MAFxi , M6N7MAFyi , M6N7MAFzi , & + M6N7MAGxi , M6N7MAGyi , M6N7MAGzi , M6N7MBFxi , M6N7MBFyi , M6N7MBFzi , M6N7MBxi , & + M6N7MByi , M6N7MBzi , M6N7MMGxi , M6N7MMGyi , M6N7MMGzi , M6N7STAxi , M6N7STAyi , & + M6N7STAzi , M6N7STVxi , M6N7STVyi , M6N7STVzi , M6N7Vxi , M6N7Vyi , M6N7Vzi , & + M6N8Axi , M6N8Ayi , M6N8Azi , M6N8DynP , M6N8FAFxi , M6N8FAFyi , M6N8FAFzi , & + M6N8FAGxi , M6N8FAGyi , M6N8FAGzi , M6N8FAMxi , M6N8FAMyi , M6N8FAMzi , M6N8FBFxi , & + M6N8FBFyi , M6N8FBFzi , M6N8FBxi , M6N8FByi , M6N8FBzi , M6N8FDxi , M6N8FDyi , & + M6N8FDzi , M6N8FIxi , M6N8FIyi , M6N8FIzi , M6N8FMGxi , M6N8FMGyi , M6N8FMGzi , & + M6N8MAFxi , M6N8MAFyi , M6N8MAFzi , M6N8MAGxi , M6N8MAGyi , M6N8MAGzi , M6N8MBFxi , & + M6N8MBFyi , M6N8MBFzi , M6N8MBxi , M6N8MByi , M6N8MBzi , M6N8MMGxi , M6N8MMGyi , & + M6N8MMGzi , M6N8STAxi , M6N8STAyi , M6N8STAzi , M6N8STVxi , M6N8STVyi , M6N8STVzi , & + M6N8Vxi , M6N8Vyi , M6N8Vzi , M6N9Axi , M6N9Ayi , M6N9Azi , M6N9DynP , & + M6N9FAFxi , M6N9FAFyi , M6N9FAFzi , M6N9FAGxi , M6N9FAGyi , M6N9FAGzi , M6N9FAMxi , & + M6N9FAMyi , M6N9FAMzi , M6N9FBFxi , M6N9FBFyi , M6N9FBFzi , M6N9FBxi , M6N9FByi , & + M6N9FBzi , M6N9FDxi , M6N9FDyi , M6N9FDzi , M6N9FIxi , M6N9FIyi , M6N9FIzi , & + M6N9FMGxi , M6N9FMGyi , M6N9FMGzi , M6N9MAFxi , M6N9MAFyi , M6N9MAFzi , M6N9MAGxi , & + M6N9MAGyi , M6N9MAGzi , M6N9MBFxi , M6N9MBFyi , M6N9MBFzi , M6N9MBxi , M6N9MByi , & + M6N9MBzi , M6N9MMGxi , M6N9MMGyi , M6N9MMGzi , M6N9STAxi , M6N9STAyi , M6N9STAzi , & + M6N9STVxi , M6N9STVyi , M6N9STVzi , M6N9Vxi , M6N9Vyi , M6N9Vzi , M7N1Axi , & + M7N1Ayi , M7N1Azi , M7N1DynP , M7N1FAFxi , M7N1FAFyi , M7N1FAFzi , M7N1FAGxi , & + M7N1FAGyi , M7N1FAGzi , M7N1FAMxi , M7N1FAMyi , M7N1FAMzi , M7N1FBFxi , M7N1FBFyi , & + M7N1FBFzi , M7N1FBxi , M7N1FByi , M7N1FBzi , M7N1FDxi , M7N1FDyi , M7N1FDzi , & + M7N1FIxi , M7N1FIyi , M7N1FIzi , M7N1FMGxi , M7N1FMGyi , M7N1FMGzi , M7N1MAFxi , & + M7N1MAFyi , M7N1MAFzi , M7N1MAGxi , M7N1MAGyi , M7N1MAGzi , M7N1MBFxi , M7N1MBFyi , & + M7N1MBFzi , M7N1MBxi , M7N1MByi , M7N1MBzi , M7N1MMGxi , M7N1MMGyi , M7N1MMGzi , & + M7N1STAxi , M7N1STAyi , M7N1STAzi , M7N1STVxi , M7N1STVyi , M7N1STVzi , M7N1Vxi , & + M7N1Vyi , M7N1Vzi , M7N2Axi , M7N2Ayi , M7N2Azi , M7N2DynP , M7N2FAFxi , & + M7N2FAFyi , M7N2FAFzi , M7N2FAGxi , M7N2FAGyi , M7N2FAGzi , M7N2FAMxi , M7N2FAMyi , & + M7N2FAMzi , M7N2FBFxi , M7N2FBFyi , M7N2FBFzi , M7N2FBxi , M7N2FByi , M7N2FBzi , & + M7N2FDxi , M7N2FDyi , M7N2FDzi , M7N2FIxi , M7N2FIyi , M7N2FIzi , M7N2FMGxi , & + M7N2FMGyi , M7N2FMGzi , M7N2MAFxi , M7N2MAFyi , M7N2MAFzi , M7N2MAGxi , M7N2MAGyi , & + M7N2MAGzi , M7N2MBFxi , M7N2MBFyi , M7N2MBFzi , M7N2MBxi , M7N2MByi , M7N2MBzi , & + M7N2MMGxi , M7N2MMGyi , M7N2MMGzi , M7N2STAxi , M7N2STAyi , M7N2STAzi , M7N2STVxi , & + M7N2STVyi , M7N2STVzi , M7N2Vxi , M7N2Vyi , M7N2Vzi , M7N3Axi , M7N3Ayi , & + M7N3Azi , M7N3DynP , M7N3FAFxi , M7N3FAFyi , M7N3FAFzi , M7N3FAGxi , M7N3FAGyi , & + M7N3FAGzi , M7N3FAMxi , M7N3FAMyi , M7N3FAMzi , M7N3FBFxi , M7N3FBFyi , M7N3FBFzi , & + M7N3FBxi , M7N3FByi , M7N3FBzi , M7N3FDxi , M7N3FDyi , M7N3FDzi , M7N3FIxi , & + M7N3FIyi , M7N3FIzi , M7N3FMGxi , M7N3FMGyi , M7N3FMGzi , M7N3MAFxi , M7N3MAFyi , & + M7N3MAFzi , M7N3MAGxi , M7N3MAGyi , M7N3MAGzi , M7N3MBFxi , M7N3MBFyi , M7N3MBFzi , & + M7N3MBxi , M7N3MByi , M7N3MBzi , M7N3MMGxi , M7N3MMGyi , M7N3MMGzi , M7N3STAxi , & + M7N3STAyi , M7N3STAzi , M7N3STVxi , M7N3STVyi , M7N3STVzi , M7N3Vxi , M7N3Vyi , & + M7N3Vzi , M7N4Axi , M7N4Ayi , M7N4Azi , M7N4DynP , M7N4FAFxi , M7N4FAFyi , & + M7N4FAFzi , M7N4FAGxi , M7N4FAGyi , M7N4FAGzi , M7N4FAMxi , M7N4FAMyi , M7N4FAMzi , & + M7N4FBFxi , M7N4FBFyi , M7N4FBFzi , M7N4FBxi , M7N4FByi , M7N4FBzi , M7N4FDxi , & + M7N4FDyi , M7N4FDzi , M7N4FIxi , M7N4FIyi , M7N4FIzi , M7N4FMGxi , M7N4FMGyi , & + M7N4FMGzi , M7N4MAFxi , M7N4MAFyi , M7N4MAFzi , M7N4MAGxi , M7N4MAGyi , M7N4MAGzi , & + M7N4MBFxi , M7N4MBFyi , M7N4MBFzi , M7N4MBxi , M7N4MByi , M7N4MBzi , M7N4MMGxi , & + M7N4MMGyi , M7N4MMGzi , M7N4STAxi , M7N4STAyi , M7N4STAzi , M7N4STVxi , M7N4STVyi , & + M7N4STVzi , M7N4Vxi , M7N4Vyi , M7N4Vzi , M7N5Axi , M7N5Ayi , M7N5Azi , & + M7N5DynP , M7N5FAFxi , M7N5FAFyi , M7N5FAFzi , M7N5FAGxi , M7N5FAGyi , M7N5FAGzi , & + M7N5FAMxi , M7N5FAMyi , M7N5FAMzi , M7N5FBFxi , M7N5FBFyi , M7N5FBFzi , M7N5FBxi , & + M7N5FByi , M7N5FBzi , M7N5FDxi , M7N5FDyi , M7N5FDzi , M7N5FIxi , M7N5FIyi , & + M7N5FIzi , M7N5FMGxi , M7N5FMGyi , M7N5FMGzi , M7N5MAFxi , M7N5MAFyi , M7N5MAFzi , & + M7N5MAGxi , M7N5MAGyi , M7N5MAGzi , M7N5MBFxi , M7N5MBFyi , M7N5MBFzi , M7N5MBxi , & + M7N5MByi , M7N5MBzi , M7N5MMGxi , M7N5MMGyi , M7N5MMGzi , M7N5STAxi , M7N5STAyi , & + M7N5STAzi , M7N5STVxi , M7N5STVyi , M7N5STVzi , M7N5Vxi , M7N5Vyi , M7N5Vzi , & + M7N6Axi , M7N6Ayi , M7N6Azi , M7N6DynP , M7N6FAFxi , M7N6FAFyi , M7N6FAFzi , & + M7N6FAGxi , M7N6FAGyi , M7N6FAGzi , M7N6FAMxi , M7N6FAMyi , M7N6FAMzi , M7N6FBFxi , & + M7N6FBFyi , M7N6FBFzi , M7N6FBxi , M7N6FByi , M7N6FBzi , M7N6FDxi , M7N6FDyi , & + M7N6FDzi , M7N6FIxi , M7N6FIyi , M7N6FIzi , M7N6FMGxi , M7N6FMGyi , M7N6FMGzi , & + M7N6MAFxi , M7N6MAFyi , M7N6MAFzi , M7N6MAGxi , M7N6MAGyi , M7N6MAGzi , M7N6MBFxi , & + M7N6MBFyi , M7N6MBFzi , M7N6MBxi , M7N6MByi , M7N6MBzi , M7N6MMGxi , M7N6MMGyi , & + M7N6MMGzi , M7N6STAxi , M7N6STAyi /) + ParamIndxAry(3501:4000) = (/ & + M7N6STAzi , M7N6STVxi , M7N6STVyi , M7N6STVzi , M7N6Vxi , M7N6Vyi , M7N6Vzi , & + M7N7Axi , M7N7Ayi , M7N7Azi , M7N7DynP , M7N7FAFxi , M7N7FAFyi , M7N7FAFzi , & + M7N7FAGxi , M7N7FAGyi , M7N7FAGzi , M7N7FAMxi , M7N7FAMyi , M7N7FAMzi , M7N7FBFxi , & + M7N7FBFyi , M7N7FBFzi , M7N7FBxi , M7N7FByi , M7N7FBzi , M7N7FDxi , M7N7FDyi , & + M7N7FDzi , M7N7FIxi , M7N7FIyi , M7N7FIzi , M7N7FMGxi , M7N7FMGyi , M7N7FMGzi , & + M7N7MAFxi , M7N7MAFyi , M7N7MAFzi , M7N7MAGxi , M7N7MAGyi , M7N7MAGzi , M7N7MBFxi , & + M7N7MBFyi , M7N7MBFzi , M7N7MBxi , M7N7MByi , M7N7MBzi , M7N7MMGxi , M7N7MMGyi , & + M7N7MMGzi , M7N7STAxi , M7N7STAyi , M7N7STAzi , M7N7STVxi , M7N7STVyi , M7N7STVzi , & + M7N7Vxi , M7N7Vyi , M7N7Vzi , M7N8Axi , M7N8Ayi , M7N8Azi , M7N8DynP , & + M7N8FAFxi , M7N8FAFyi , M7N8FAFzi , M7N8FAGxi , M7N8FAGyi , M7N8FAGzi , M7N8FAMxi , & + M7N8FAMyi , M7N8FAMzi , M7N8FBFxi , M7N8FBFyi , M7N8FBFzi , M7N8FBxi , M7N8FByi , & + M7N8FBzi , M7N8FDxi , M7N8FDyi , M7N8FDzi , M7N8FIxi , M7N8FIyi , M7N8FIzi , & + M7N8FMGxi , M7N8FMGyi , M7N8FMGzi , M7N8MAFxi , M7N8MAFyi , M7N8MAFzi , M7N8MAGxi , & + M7N8MAGyi , M7N8MAGzi , M7N8MBFxi , M7N8MBFyi , M7N8MBFzi , M7N8MBxi , M7N8MByi , & + M7N8MBzi , M7N8MMGxi , M7N8MMGyi , M7N8MMGzi , M7N8STAxi , M7N8STAyi , M7N8STAzi , & + M7N8STVxi , M7N8STVyi , M7N8STVzi , M7N8Vxi , M7N8Vyi , M7N8Vzi , M7N9Axi , & + M7N9Ayi , M7N9Azi , M7N9DynP , M7N9FAFxi , M7N9FAFyi , M7N9FAFzi , M7N9FAGxi , & + M7N9FAGyi , M7N9FAGzi , M7N9FAMxi , M7N9FAMyi , M7N9FAMzi , M7N9FBFxi , M7N9FBFyi , & + M7N9FBFzi , M7N9FBxi , M7N9FByi , M7N9FBzi , M7N9FDxi , M7N9FDyi , M7N9FDzi , & + M7N9FIxi , M7N9FIyi , M7N9FIzi , M7N9FMGxi , M7N9FMGyi , M7N9FMGzi , M7N9MAFxi , & + M7N9MAFyi , M7N9MAFzi , M7N9MAGxi , M7N9MAGyi , M7N9MAGzi , M7N9MBFxi , M7N9MBFyi , & + M7N9MBFzi , M7N9MBxi , M7N9MByi , M7N9MBzi , M7N9MMGxi , M7N9MMGyi , M7N9MMGzi , & + M7N9STAxi , M7N9STAyi , M7N9STAzi , M7N9STVxi , M7N9STVyi , M7N9STVzi , M7N9Vxi , & + M7N9Vyi , M7N9Vzi , M8N1Axi , M8N1Ayi , M8N1Azi , M8N1DynP , M8N1FAFxi , & + M8N1FAFyi , M8N1FAFzi , M8N1FAGxi , M8N1FAGyi , M8N1FAGzi , M8N1FAMxi , M8N1FAMyi , & + M8N1FAMzi , M8N1FBFxi , M8N1FBFyi , M8N1FBFzi , M8N1FBxi , M8N1FByi , M8N1FBzi , & + M8N1FDxi , M8N1FDyi , M8N1FDzi , M8N1FIxi , M8N1FIyi , M8N1FIzi , M8N1FMGxi , & + M8N1FMGyi , M8N1FMGzi , M8N1MAFxi , M8N1MAFyi , M8N1MAFzi , M8N1MAGxi , M8N1MAGyi , & + M8N1MAGzi , M8N1MBFxi , M8N1MBFyi , M8N1MBFzi , M8N1MBxi , M8N1MByi , M8N1MBzi , & + M8N1MMGxi , M8N1MMGyi , M8N1MMGzi , M8N1STAxi , M8N1STAyi , M8N1STAzi , M8N1STVxi , & + M8N1STVyi , M8N1STVzi , M8N1Vxi , M8N1Vyi , M8N1Vzi , M8N2Axi , M8N2Ayi , & + M8N2Azi , M8N2DynP , M8N2FAFxi , M8N2FAFyi , M8N2FAFzi , M8N2FAGxi , M8N2FAGyi , & + M8N2FAGzi , M8N2FAMxi , M8N2FAMyi , M8N2FAMzi , M8N2FBFxi , M8N2FBFyi , M8N2FBFzi , & + M8N2FBxi , M8N2FByi , M8N2FBzi , M8N2FDxi , M8N2FDyi , M8N2FDzi , M8N2FIxi , & + M8N2FIyi , M8N2FIzi , M8N2FMGxi , M8N2FMGyi , M8N2FMGzi , M8N2MAFxi , M8N2MAFyi , & + M8N2MAFzi , M8N2MAGxi , M8N2MAGyi , M8N2MAGzi , M8N2MBFxi , M8N2MBFyi , M8N2MBFzi , & + M8N2MBxi , M8N2MByi , M8N2MBzi , M8N2MMGxi , M8N2MMGyi , M8N2MMGzi , M8N2STAxi , & + M8N2STAyi , M8N2STAzi , M8N2STVxi , M8N2STVyi , M8N2STVzi , M8N2Vxi , M8N2Vyi , & + M8N2Vzi , M8N3Axi , M8N3Ayi , M8N3Azi , M8N3DynP , M8N3FAFxi , M8N3FAFyi , & + M8N3FAFzi , M8N3FAGxi , M8N3FAGyi , M8N3FAGzi , M8N3FAMxi , M8N3FAMyi , M8N3FAMzi , & + M8N3FBFxi , M8N3FBFyi , M8N3FBFzi , M8N3FBxi , M8N3FByi , M8N3FBzi , M8N3FDxi , & + M8N3FDyi , M8N3FDzi , M8N3FIxi , M8N3FIyi , M8N3FIzi , M8N3FMGxi , M8N3FMGyi , & + M8N3FMGzi , M8N3MAFxi , M8N3MAFyi , M8N3MAFzi , M8N3MAGxi , M8N3MAGyi , M8N3MAGzi , & + M8N3MBFxi , M8N3MBFyi , M8N3MBFzi , M8N3MBxi , M8N3MByi , M8N3MBzi , M8N3MMGxi , & + M8N3MMGyi , M8N3MMGzi , M8N3STAxi , M8N3STAyi , M8N3STAzi , M8N3STVxi , M8N3STVyi , & + M8N3STVzi , M8N3Vxi , M8N3Vyi , M8N3Vzi , M8N4Axi , M8N4Ayi , M8N4Azi , & + M8N4DynP , M8N4FAFxi , M8N4FAFyi , M8N4FAFzi , M8N4FAGxi , M8N4FAGyi , M8N4FAGzi , & + M8N4FAMxi , M8N4FAMyi , M8N4FAMzi , M8N4FBFxi , M8N4FBFyi , M8N4FBFzi , M8N4FBxi , & + M8N4FByi , M8N4FBzi , M8N4FDxi , M8N4FDyi , M8N4FDzi , M8N4FIxi , M8N4FIyi , & + M8N4FIzi , M8N4FMGxi , M8N4FMGyi , M8N4FMGzi , M8N4MAFxi , M8N4MAFyi , M8N4MAFzi , & + M8N4MAGxi , M8N4MAGyi , M8N4MAGzi , M8N4MBFxi , M8N4MBFyi , M8N4MBFzi , M8N4MBxi , & + M8N4MByi , M8N4MBzi , M8N4MMGxi , M8N4MMGyi , M8N4MMGzi , M8N4STAxi , M8N4STAyi , & + M8N4STAzi , M8N4STVxi , M8N4STVyi , M8N4STVzi , M8N4Vxi , M8N4Vyi , M8N4Vzi , & + M8N5Axi , M8N5Ayi , M8N5Azi , M8N5DynP , M8N5FAFxi , M8N5FAFyi , M8N5FAFzi , & + M8N5FAGxi , M8N5FAGyi , M8N5FAGzi , M8N5FAMxi , M8N5FAMyi , M8N5FAMzi , M8N5FBFxi , & + M8N5FBFyi , M8N5FBFzi , M8N5FBxi , M8N5FByi , M8N5FBzi , M8N5FDxi , M8N5FDyi , & + M8N5FDzi , M8N5FIxi , M8N5FIyi , M8N5FIzi , M8N5FMGxi , M8N5FMGyi , M8N5FMGzi , & + M8N5MAFxi , M8N5MAFyi , M8N5MAFzi , M8N5MAGxi , M8N5MAGyi , M8N5MAGzi , M8N5MBFxi , & + M8N5MBFyi , M8N5MBFzi , M8N5MBxi , M8N5MByi , M8N5MBzi , M8N5MMGxi , M8N5MMGyi , & + M8N5MMGzi , M8N5STAxi , M8N5STAyi , M8N5STAzi , M8N5STVxi , M8N5STVyi , M8N5STVzi , & + M8N5Vxi , M8N5Vyi , M8N5Vzi , M8N6Axi , M8N6Ayi , M8N6Azi , M8N6DynP , & + M8N6FAFxi , M8N6FAFyi , M8N6FAFzi , M8N6FAGxi , M8N6FAGyi , M8N6FAGzi , M8N6FAMxi , & + M8N6FAMyi , M8N6FAMzi , M8N6FBFxi , M8N6FBFyi , M8N6FBFzi , M8N6FBxi , M8N6FByi , & + M8N6FBzi , M8N6FDxi , M8N6FDyi , M8N6FDzi , M8N6FIxi , M8N6FIyi , M8N6FIzi , & + M8N6FMGxi , M8N6FMGyi , M8N6FMGzi , M8N6MAFxi , M8N6MAFyi , M8N6MAFzi , M8N6MAGxi , & + M8N6MAGyi , M8N6MAGzi , M8N6MBFxi , M8N6MBFyi , M8N6MBFzi , M8N6MBxi , M8N6MByi , & + M8N6MBzi , M8N6MMGxi , M8N6MMGyi , M8N6MMGzi , M8N6STAxi , M8N6STAyi , M8N6STAzi , & + M8N6STVxi , M8N6STVyi , M8N6STVzi , M8N6Vxi , M8N6Vyi , M8N6Vzi , M8N7Axi , & + M8N7Ayi , M8N7Azi , M8N7DynP , M8N7FAFxi , M8N7FAFyi , M8N7FAFzi , M8N7FAGxi , & + M8N7FAGyi , M8N7FAGzi , M8N7FAMxi , M8N7FAMyi , M8N7FAMzi , M8N7FBFxi , M8N7FBFyi , & + M8N7FBFzi , M8N7FBxi , M8N7FByi , M8N7FBzi , M8N7FDxi , M8N7FDyi , M8N7FDzi , & + M8N7FIxi , M8N7FIyi , M8N7FIzi /) + ParamIndxAry(4001:4500) = (/ & + M8N7FMGxi , M8N7FMGyi , M8N7FMGzi , M8N7MAFxi , M8N7MAFyi , M8N7MAFzi , M8N7MAGxi , & + M8N7MAGyi , M8N7MAGzi , M8N7MBFxi , M8N7MBFyi , M8N7MBFzi , M8N7MBxi , M8N7MByi , & + M8N7MBzi , M8N7MMGxi , M8N7MMGyi , M8N7MMGzi , M8N7STAxi , M8N7STAyi , M8N7STAzi , & + M8N7STVxi , M8N7STVyi , M8N7STVzi , M8N7Vxi , M8N7Vyi , M8N7Vzi , M8N8Axi , & + M8N8Ayi , M8N8Azi , M8N8DynP , M8N8FAFxi , M8N8FAFyi , M8N8FAFzi , M8N8FAGxi , & + M8N8FAGyi , M8N8FAGzi , M8N8FAMxi , M8N8FAMyi , M8N8FAMzi , M8N8FBFxi , M8N8FBFyi , & + M8N8FBFzi , M8N8FBxi , M8N8FByi , M8N8FBzi , M8N8FDxi , M8N8FDyi , M8N8FDzi , & + M8N8FIxi , M8N8FIyi , M8N8FIzi , M8N8FMGxi , M8N8FMGyi , M8N8FMGzi , M8N8MAFxi , & + M8N8MAFyi , M8N8MAFzi , M8N8MAGxi , M8N8MAGyi , M8N8MAGzi , M8N8MBFxi , M8N8MBFyi , & + M8N8MBFzi , M8N8MBxi , M8N8MByi , M8N8MBzi , M8N8MMGxi , M8N8MMGyi , M8N8MMGzi , & + M8N8STAxi , M8N8STAyi , M8N8STAzi , M8N8STVxi , M8N8STVyi , M8N8STVzi , M8N8Vxi , & + M8N8Vyi , M8N8Vzi , M8N9Axi , M8N9Ayi , M8N9Azi , M8N9DynP , M8N9FAFxi , & + M8N9FAFyi , M8N9FAFzi , M8N9FAGxi , M8N9FAGyi , M8N9FAGzi , M8N9FAMxi , M8N9FAMyi , & + M8N9FAMzi , M8N9FBFxi , M8N9FBFyi , M8N9FBFzi , M8N9FBxi , M8N9FByi , M8N9FBzi , & + M8N9FDxi , M8N9FDyi , M8N9FDzi , M8N9FIxi , M8N9FIyi , M8N9FIzi , M8N9FMGxi , & + M8N9FMGyi , M8N9FMGzi , M8N9MAFxi , M8N9MAFyi , M8N9MAFzi , M8N9MAGxi , M8N9MAGyi , & + M8N9MAGzi , M8N9MBFxi , M8N9MBFyi , M8N9MBFzi , M8N9MBxi , M8N9MByi , M8N9MBzi , & + M8N9MMGxi , M8N9MMGyi , M8N9MMGzi , M8N9STAxi , M8N9STAyi , M8N9STAzi , M8N9STVxi , & + M8N9STVyi , M8N9STVzi , M8N9Vxi , M8N9Vyi , M8N9Vzi , M9N1Axi , M9N1Ayi , & + M9N1Azi , M9N1DynP , M9N1FAFxi , M9N1FAFyi , M9N1FAFzi , M9N1FAGxi , M9N1FAGyi , & + M9N1FAGzi , M9N1FAMxi , M9N1FAMyi , M9N1FAMzi , M9N1FBFxi , M9N1FBFyi , M9N1FBFzi , & + M9N1FBxi , M9N1FByi , M9N1FBzi , M9N1FDxi , M9N1FDyi , M9N1FDzi , M9N1FIxi , & + M9N1FIyi , M9N1FIzi , M9N1FMGxi , M9N1FMGyi , M9N1FMGzi , M9N1MAFxi , M9N1MAFyi , & + M9N1MAFzi , M9N1MAGxi , M9N1MAGyi , M9N1MAGzi , M9N1MBFxi , M9N1MBFyi , M9N1MBFzi , & + M9N1MBxi , M9N1MByi , M9N1MBzi , M9N1MMGxi , M9N1MMGyi , M9N1MMGzi , M9N1STAxi , & + M9N1STAyi , M9N1STAzi , M9N1STVxi , M9N1STVyi , M9N1STVzi , M9N1Vxi , M9N1Vyi , & + M9N1Vzi , M9N2Axi , M9N2Ayi , M9N2Azi , M9N2DynP , M9N2FAFxi , M9N2FAFyi , & + M9N2FAFzi , M9N2FAGxi , M9N2FAGyi , M9N2FAGzi , M9N2FAMxi , M9N2FAMyi , M9N2FAMzi , & + M9N2FBFxi , M9N2FBFyi , M9N2FBFzi , M9N2FBxi , M9N2FByi , M9N2FBzi , M9N2FDxi , & + M9N2FDyi , M9N2FDzi , M9N2FIxi , M9N2FIyi , M9N2FIzi , M9N2FMGxi , M9N2FMGyi , & + M9N2FMGzi , M9N2MAFxi , M9N2MAFyi , M9N2MAFzi , M9N2MAGxi , M9N2MAGyi , M9N2MAGzi , & + M9N2MBFxi , M9N2MBFyi , M9N2MBFzi , M9N2MBxi , M9N2MByi , M9N2MBzi , M9N2MMGxi , & + M9N2MMGyi , M9N2MMGzi , M9N2STAxi , M9N2STAyi , M9N2STAzi , M9N2STVxi , M9N2STVyi , & + M9N2STVzi , M9N2Vxi , M9N2Vyi , M9N2Vzi , M9N3Axi , M9N3Ayi , M9N3Azi , & + M9N3DynP , M9N3FAFxi , M9N3FAFyi , M9N3FAFzi , M9N3FAGxi , M9N3FAGyi , M9N3FAGzi , & + M9N3FAMxi , M9N3FAMyi , M9N3FAMzi , M9N3FBFxi , M9N3FBFyi , M9N3FBFzi , M9N3FBxi , & + M9N3FByi , M9N3FBzi , M9N3FDxi , M9N3FDyi , M9N3FDzi , M9N3FIxi , M9N3FIyi , & + M9N3FIzi , M9N3FMGxi , M9N3FMGyi , M9N3FMGzi , M9N3MAFxi , M9N3MAFyi , M9N3MAFzi , & + M9N3MAGxi , M9N3MAGyi , M9N3MAGzi , M9N3MBFxi , M9N3MBFyi , M9N3MBFzi , M9N3MBxi , & + M9N3MByi , M9N3MBzi , M9N3MMGxi , M9N3MMGyi , M9N3MMGzi , M9N3STAxi , M9N3STAyi , & + M9N3STAzi , M9N3STVxi , M9N3STVyi , M9N3STVzi , M9N3Vxi , M9N3Vyi , M9N3Vzi , & + M9N4Axi , M9N4Ayi , M9N4Azi , M9N4DynP , M9N4FAFxi , M9N4FAFyi , M9N4FAFzi , & + M9N4FAGxi , M9N4FAGyi , M9N4FAGzi , M9N4FAMxi , M9N4FAMyi , M9N4FAMzi , M9N4FBFxi , & + M9N4FBFyi , M9N4FBFzi , M9N4FBxi , M9N4FByi , M9N4FBzi , M9N4FDxi , M9N4FDyi , & + M9N4FDzi , M9N4FIxi , M9N4FIyi , M9N4FIzi , M9N4FMGxi , M9N4FMGyi , M9N4FMGzi , & + M9N4MAFxi , M9N4MAFyi , M9N4MAFzi , M9N4MAGxi , M9N4MAGyi , M9N4MAGzi , M9N4MBFxi , & + M9N4MBFyi , M9N4MBFzi , M9N4MBxi , M9N4MByi , M9N4MBzi , M9N4MMGxi , M9N4MMGyi , & + M9N4MMGzi , M9N4STAxi , M9N4STAyi , M9N4STAzi , M9N4STVxi , M9N4STVyi , M9N4STVzi , & + M9N4Vxi , M9N4Vyi , M9N4Vzi , M9N5Axi , M9N5Ayi , M9N5Azi , M9N5DynP , & + M9N5FAFxi , M9N5FAFyi , M9N5FAFzi , M9N5FAGxi , M9N5FAGyi , M9N5FAGzi , M9N5FAMxi , & + M9N5FAMyi , M9N5FAMzi , M9N5FBFxi , M9N5FBFyi , M9N5FBFzi , M9N5FBxi , M9N5FByi , & + M9N5FBzi , M9N5FDxi , M9N5FDyi , M9N5FDzi , M9N5FIxi , M9N5FIyi , M9N5FIzi , & + M9N5FMGxi , M9N5FMGyi , M9N5FMGzi , M9N5MAFxi , M9N5MAFyi , M9N5MAFzi , M9N5MAGxi , & + M9N5MAGyi , M9N5MAGzi , M9N5MBFxi , M9N5MBFyi , M9N5MBFzi , M9N5MBxi , M9N5MByi , & + M9N5MBzi , M9N5MMGxi , M9N5MMGyi , M9N5MMGzi , M9N5STAxi , M9N5STAyi , M9N5STAzi , & + M9N5STVxi , M9N5STVyi , M9N5STVzi , M9N5Vxi , M9N5Vyi , M9N5Vzi , M9N6Axi , & + M9N6Ayi , M9N6Azi , M9N6DynP , M9N6FAFxi , M9N6FAFyi , M9N6FAFzi , M9N6FAGxi , & + M9N6FAGyi , M9N6FAGzi , M9N6FAMxi , M9N6FAMyi , M9N6FAMzi , M9N6FBFxi , M9N6FBFyi , & + M9N6FBFzi , M9N6FBxi , M9N6FByi , M9N6FBzi , M9N6FDxi , M9N6FDyi , M9N6FDzi , & + M9N6FIxi , M9N6FIyi , M9N6FIzi , M9N6FMGxi , M9N6FMGyi , M9N6FMGzi , M9N6MAFxi , & + M9N6MAFyi , M9N6MAFzi , M9N6MAGxi , M9N6MAGyi , M9N6MAGzi , M9N6MBFxi , M9N6MBFyi , & + M9N6MBFzi , M9N6MBxi , M9N6MByi , M9N6MBzi , M9N6MMGxi , M9N6MMGyi , M9N6MMGzi , & + M9N6STAxi , M9N6STAyi , M9N6STAzi , M9N6STVxi , M9N6STVyi , M9N6STVzi , M9N6Vxi , & + M9N6Vyi , M9N6Vzi , M9N7Axi , M9N7Ayi , M9N7Azi , M9N7DynP , M9N7FAFxi , & + M9N7FAFyi , M9N7FAFzi , M9N7FAGxi , M9N7FAGyi , M9N7FAGzi , M9N7FAMxi , M9N7FAMyi , & + M9N7FAMzi , M9N7FBFxi , M9N7FBFyi , M9N7FBFzi , M9N7FBxi , M9N7FByi , M9N7FBzi , & + M9N7FDxi , M9N7FDyi , M9N7FDzi , M9N7FIxi , M9N7FIyi , M9N7FIzi , M9N7FMGxi , & + M9N7FMGyi , M9N7FMGzi , M9N7MAFxi , M9N7MAFyi , M9N7MAFzi , M9N7MAGxi , M9N7MAGyi , & + M9N7MAGzi , M9N7MBFxi , M9N7MBFyi , M9N7MBFzi , M9N7MBxi , M9N7MByi , M9N7MBzi , & + M9N7MMGxi , M9N7MMGyi , M9N7MMGzi , M9N7STAxi , M9N7STAyi , M9N7STAzi , M9N7STVxi , & + M9N7STVyi , M9N7STVzi , M9N7Vxi , M9N7Vyi , M9N7Vzi , M9N8Axi , M9N8Ayi , & + M9N8Azi , M9N8DynP , M9N8FAFxi /) + ParamIndxAry(4501:4599) = (/ & + M9N8FAFyi , M9N8FAFzi , M9N8FAGxi , M9N8FAGyi , M9N8FAGzi , M9N8FAMxi , M9N8FAMyi , & + M9N8FAMzi , M9N8FBFxi , M9N8FBFyi , M9N8FBFzi , M9N8FBxi , M9N8FByi , M9N8FBzi , & + M9N8FDxi , M9N8FDyi , M9N8FDzi , M9N8FIxi , M9N8FIyi , M9N8FIzi , M9N8FMGxi , & + M9N8FMGyi , M9N8FMGzi , M9N8MAFxi , M9N8MAFyi , M9N8MAFzi , M9N8MAGxi , M9N8MAGyi , & + M9N8MAGzi , M9N8MBFxi , M9N8MBFyi , M9N8MBFzi , M9N8MBxi , M9N8MByi , M9N8MBzi , & + M9N8MMGxi , M9N8MMGyi , M9N8MMGzi , M9N8STAxi , M9N8STAyi , M9N8STAzi , M9N8STVxi , & + M9N8STVyi , M9N8STVzi , M9N8Vxi , M9N8Vyi , M9N8Vzi , M9N9Axi , M9N9Ayi , & + M9N9Azi , M9N9DynP , M9N9FAFxi , M9N9FAFyi , M9N9FAFzi , M9N9FAGxi , M9N9FAGyi , & + M9N9FAGzi , M9N9FAMxi , M9N9FAMyi , M9N9FAMzi , M9N9FBFxi , M9N9FBFyi , M9N9FBFzi , & + M9N9FBxi , M9N9FByi , M9N9FBzi , M9N9FDxi , M9N9FDyi , M9N9FDzi , M9N9FIxi , & + M9N9FIyi , M9N9FIzi , M9N9FMGxi , M9N9FMGyi , M9N9FMGzi , M9N9MAFxi , M9N9MAFyi , & + M9N9MAFzi , M9N9MAGxi , M9N9MAGyi , M9N9MAGzi , M9N9MBFxi , M9N9MBFyi , M9N9MBFzi , & + M9N9MBxi , M9N9MByi , M9N9MBzi , M9N9MMGxi , M9N9MMGyi , M9N9MMGzi , M9N9STAxi , & + M9N9STAyi , M9N9STAzi , M9N9STVxi , M9N9STVyi , M9N9STVzi , M9N9Vxi , M9N9Vyi , & + M9N9Vzi /) + ParamUnitsAry(1:500) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(Pa) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(Pa) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(Pa) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) "/) + ParamUnitsAry(501:1000) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) "/) + ParamUnitsAry(1001:1500) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) "/) + ParamUnitsAry(1501:2000) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s^2) "/) + ParamUnitsAry(2001:2500) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) "/) + ParamUnitsAry(2501:3000) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) "/) + ParamUnitsAry(3001:3500) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(m/s^2) ","(m/s^2) "/) + ParamUnitsAry(3501:4000) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) "/) + ParamUnitsAry(4001:4500) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(Pa) ","(N/m) "/) + ParamUnitsAry(4501:4599) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ", & + "(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(N-m/m) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) "/) + + + GetMorisonChannels = 0 newFoundMask = .FALSE. diff --git a/modules/hydrodyn/src/Morison_Types.f90 b/modules/hydrodyn/src/Morison_Types.f90 index 5a0989fc09..57addb8d54 100644 --- a/modules/hydrodyn/src/Morison_Types.f90 +++ b/modules/hydrodyn/src/Morison_Types.f90 @@ -33,246 +33,268 @@ MODULE Morison_Types !--------------------------------------------------------------------------------------------------------------------------------- USE NWTC_Library IMPLICIT NONE - INTEGER(IntKi), PUBLIC, PARAMETER :: MaxMrsnOutputs = 4032 ! [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: MaxMrsnOutputs = 4599 ! Total number of possible Morison module output channels [-] ! ========= Morison_JointType ======= TYPE, PUBLIC :: Morison_JointType - INTEGER(IntKi) :: JointID !< [-] - REAL(ReKi) , DIMENSION(1:3) :: JointPos !< [-] - INTEGER(IntKi) :: JointAxID !< [-] - INTEGER(IntKi) :: JointAxIDIndx !< [-] - INTEGER(IntKi) :: JointOvrlp !< [-] - INTEGER(IntKi) :: NConnections !< [-] - INTEGER(IntKi) , DIMENSION(1:10) :: ConnectionList !< [-] + INTEGER(IntKi) :: JointID !< User-specified integer ID for the given joint [-] + REAL(ReKi) , DIMENSION(1:3) :: Position !< Undisplaced location of the joint in the platform coordinate system [m] + INTEGER(IntKi) :: JointAxID !< Axial ID (found in the user-supplied Axial Coefficients Table) for this joint: used to determine axial coefs [-] + INTEGER(IntKi) :: JointAxIDIndx !< The index into the Axial Coefs arrays corresponding to the above Axial ID [-] + INTEGER(IntKi) :: JointOvrlp !< Joint overlap code [Unused [-] + INTEGER(IntKi) :: NConnections !< Number of members connecting to this joint [-] + INTEGER(IntKi) , DIMENSION(1:10) :: ConnectionList !< List of Members connected to this joint. The member index is what is stored, not the Member ID [-] END TYPE Morison_JointType ! ======================= ! ========= Morison_MemberPropType ======= TYPE, PUBLIC :: Morison_MemberPropType - INTEGER(IntKi) :: PropSetID !< [-] - REAL(ReKi) :: PropD !< [-] - REAL(ReKi) :: PropThck !< [-] + INTEGER(IntKi) :: PropSetID !< User-specified integer ID for this group of properties [-] + REAL(ReKi) :: PropD !< Diameter [m] + REAL(ReKi) :: PropThck !< Wall thickness [m] END TYPE Morison_MemberPropType ! ======================= ! ========= Morison_FilledGroupType ======= TYPE, PUBLIC :: Morison_FilledGroupType - INTEGER(IntKi) :: FillNumM !< [-] - INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: FillMList !< [-] - REAL(ReKi) :: FillFSLoc !< [-] - CHARACTER(80) :: FillDensChr !< [-] - REAL(ReKi) :: FillDens !< [-] + INTEGER(IntKi) :: FillNumM !< Number of members in the Fill Group [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: FillMList !< List of Member IDs for the members in this fill group [-] + REAL(ReKi) :: FillFSLoc !< The free-surface location (in Z) for this fill group [m] + CHARACTER(80) :: FillDensChr !< String version of the Fill density [can be DEFAULT which sets the fill density to WtrDens] [kg/m^3] + REAL(ReKi) :: FillDens !< Numerical fill density [kg/m^3] END TYPE Morison_FilledGroupType ! ======================= ! ========= Morison_CoefDpths ======= TYPE, PUBLIC :: Morison_CoefDpths - REAL(ReKi) :: Dpth !< [-] - REAL(ReKi) :: DpthCd !< [-] - REAL(ReKi) :: DpthCdMG !< [-] - REAL(ReKi) :: DpthCa !< [-] - REAL(ReKi) :: DpthCaMG !< [-] - REAL(ReKi) :: DpthCp !< [-] - REAL(ReKi) :: DpthCpMG !< [-] - REAL(ReKi) :: DpthAxCa !< [-] - REAL(ReKi) :: DpthAxCaMG !< [-] - REAL(ReKi) :: DpthAxCp !< [-] - REAL(ReKi) :: DpthAxCpMG !< [-] + REAL(ReKi) :: Dpth !< Depth location for these depth-based hydrodynamic coefs [m] + REAL(ReKi) :: DpthCd !< Depth-based drag coef [-] + REAL(ReKi) :: DpthCdMG !< Depth-based drag coef for marine growth [-] + REAL(ReKi) :: DpthCa !< Depth-based Ca [-] + REAL(ReKi) :: DpthCaMG !< Depth-based Ca for marine growth [-] + REAL(ReKi) :: DpthCp !< Depth-based Cp [-] + REAL(ReKi) :: DpthCpMG !< Depth-based Cp for marine growth [-] + REAL(ReKi) :: DpthAxCd !< Depth-based Axial Cd [-] + REAL(ReKi) :: DpthAxCdMG !< Depth-based Axial Cd for marine growth [-] + REAL(ReKi) :: DpthAxCa !< Depth-based Axial Ca [-] + REAL(ReKi) :: DpthAxCaMG !< Depth-based Axial Ca for marine growth [-] + REAL(ReKi) :: DpthAxCp !< Depth-based Axial Cp [-] + REAL(ReKi) :: DpthAxCpMG !< Depth-based Axial Cp for marine growth [-] END TYPE Morison_CoefDpths ! ======================= ! ========= Morison_AxialCoefType ======= TYPE, PUBLIC :: Morison_AxialCoefType - INTEGER(IntKi) :: AxCoefID !< [-] - REAL(ReKi) :: AxCd !< [-] - REAL(ReKi) :: AxCa !< [-] - REAL(ReKi) :: AxCp !< [-] + INTEGER(IntKi) :: AxCoefID !< User-supplied integer ID for this set of Axial coefs [-] + REAL(ReKi) :: AxCd !< Axial Cd [-] + REAL(ReKi) :: AxCa !< Axial Ca [-] + REAL(ReKi) :: AxCp !< Axial Cp [-] END TYPE Morison_AxialCoefType ! ======================= ! ========= Morison_MemberInputType ======= TYPE, PUBLIC :: Morison_MemberInputType - INTEGER(IntKi) :: MemberID !< [-] - INTEGER(IntKi) :: MJointID1 !< [-] - INTEGER(IntKi) :: MJointID2 !< [-] - INTEGER(IntKi) :: MJointID1Indx !< [-] - INTEGER(IntKi) :: MJointID2Indx !< [-] - INTEGER(IntKi) :: MPropSetID1 !< [-] - INTEGER(IntKi) :: MPropSetID2 !< [-] - INTEGER(IntKi) :: MPropSetID1Indx !< [-] - INTEGER(IntKi) :: MPropSetID2Indx !< [-] - REAL(ReKi) :: MDivSize !< [-] - INTEGER(IntKi) :: MCoefMod !< [-] - INTEGER(IntKi) :: MmbrCoefIDIndx !< [-] - INTEGER(IntKi) :: MmbrFilledIDIndx !< [-] - LOGICAL :: PropPot !< [-] - INTEGER(IntKi) :: NumSplits !< [-] - REAL(ReKi) , DIMENSION(1:5) :: Splits !< [-] - REAL(ReKi) , DIMENSION(1:3,1:3) :: R_LToG !< [-] + INTEGER(IntKi) :: MemberID !< User-supplied integer ID for this member [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: NodeIndx !< Index of each of the member's nodes in the master node list [-] + INTEGER(IntKi) :: MJointID1 !< Joint ID for start of member [-] + INTEGER(IntKi) :: MJointID2 !< Joint ID for end of member [-] + INTEGER(IntKi) :: MJointID1Indx !< Index into the joint table for the start of this member [-] + INTEGER(IntKi) :: MJointID2Indx !< Index into the joint table for the end of this member [-] + INTEGER(IntKi) :: MPropSetID1 !< Property set ID for the start of this member [-] + INTEGER(IntKi) :: MPropSetID2 !< Property set ID for the end of this member [-] + INTEGER(IntKi) :: MPropSetID1Indx !< Index into the Property table for the start of this member [-] + INTEGER(IntKi) :: MPropSetID2Indx !< Index into the Property table for the end of this member [-] + REAL(ReKi) :: MDivSize !< User-specified desired member discretization size for the final element [m] + INTEGER(IntKi) :: MCoefMod !< Which coef. model is being used for this member [1=simple, 2=depth-based, 3=member-based] [-] + INTEGER(IntKi) :: MmbrCoefIDIndx !< Index into the appropriate coefs table for this member's properties [-] + INTEGER(IntKi) :: MmbrFilledIDIndx !< Index into the filled group table if this is a filled member [-] + LOGICAL :: PropPot !< Flag T/F for whether the member is modeled with potential flow theory [-] + INTEGER(IntKi) :: NElements !< number of elements in this member [-] + REAL(ReKi) :: RefLength !< the reference total length for this member [m] + REAL(ReKi) :: dl !< the reference element length for this member (may be less than MDivSize to achieve uniform element lengths) [m] END TYPE Morison_MemberInputType ! ======================= ! ========= Morison_NodeType ======= TYPE, PUBLIC :: Morison_NodeType - INTEGER(IntKi) :: NodeType !< [-] - INTEGER(IntKi) :: JointIndx !< [-] - REAL(ReKi) , DIMENSION(1:3) :: JointPos !< [-] + INTEGER(IntKi) :: JointIndx !< Joint index from the user joint table that this node corresponds to. If the software created this node, index is set to -1 [-] + REAL(ReKi) , DIMENSION(1:3) :: Position !< Position of the node in global coordinates [m] INTEGER(IntKi) :: JointOvrlp !< [-] INTEGER(IntKi) :: JointAxIDIndx !< [-] - INTEGER(IntKi) :: NConnections !< [-] - INTEGER(IntKi) , DIMENSION(1:10) :: ConnectionList !< [-] - INTEGER(IntKi) :: NConnectPreSplit !< [-] - REAL(ReKi) :: Cd !< [-] - REAL(ReKi) :: CdMG !< [-] - REAL(ReKi) :: Ca !< [-] - REAL(ReKi) :: CaMG !< [-] - REAL(ReKi) :: Cp !< [-] - REAL(ReKi) :: CpMG !< [-] - REAL(ReKi) :: JAxCd !< [-] - REAL(ReKi) :: JAxCa !< [-] - REAL(ReKi) :: JAxCp !< [-] - REAL(ReKi) :: AxCa !< [-] - REAL(ReKi) :: AxCp !< [-] - REAL(ReKi) :: AxCaMG !< [-] - REAL(ReKi) :: AxCpMG !< [-] - REAL(ReKi) :: R !< [-] - REAL(ReKi) :: t !< [-] - REAL(ReKi) :: tMG !< [-] - REAL(ReKi) :: dRdz !< [-] - REAL(ReKi) :: MGdensity !< [-] - REAL(ReKi) :: FillFSLoc !< [-] - LOGICAL :: FillFlag !< [-] - REAL(ReKi) :: FillDensity !< [-] - INTEGER(IntKi) :: InpMbrIndx !< [-] - REAL(ReKi) :: InpMbrDist !< [-] - LOGICAL :: PropPot !< [-] - REAL(ReKi) , DIMENSION(1:3,1:3) :: R_LToG !< [-] + INTEGER(IntKi) :: NConnections !< Number of elements connecting to this node [-] + INTEGER(IntKi) , DIMENSION(1:10) :: ConnectionList !< Indices of all the members connected to this node (positive if end 1, negative if end 2) [-] + REAL(ReKi) :: JAxCd !< Nodal lumped (joint) axial Cd [-] + REAL(ReKi) :: JAxCa !< Nodal lumped (joint) axial Cp [-] + REAL(ReKi) :: JAxCp !< Nodal lumped (joint) axial Ca [-] + REAL(ReKi) :: FillDensity !< Fill fluid density [kg/m^3] + REAL(ReKi) :: tMG !< Nodal thickness with marine growth [m] + REAL(ReKi) :: MGdensity !< Nodal density of marine growth [kg/m^3] END TYPE Morison_NodeType ! ======================= ! ========= Morison_MemberType ======= TYPE, PUBLIC :: Morison_MemberType - INTEGER(IntKi) :: Node1Indx !< [-] - INTEGER(IntKi) :: Node2Indx !< [-] - REAL(ReKi) :: R1 !< [-] - REAL(ReKi) :: t1 !< [-] - REAL(ReKi) :: R2 !< [-] - REAL(ReKi) :: t2 !< [-] - REAL(ReKi) :: Cd1 !< [-] - REAL(ReKi) :: CdMG1 !< [-] - REAL(ReKi) :: Ca1 !< [-] - REAL(ReKi) :: CaMG1 !< [-] - REAL(ReKi) :: Cp1 !< [-] - REAL(ReKi) :: CpMG1 !< [-] - REAL(ReKi) :: AxCa1 !< [-] - REAL(ReKi) :: AxCaMG1 !< [-] - REAL(ReKi) :: AxCp1 !< [-] - REAL(ReKi) :: AxCpMG1 !< [-] - REAL(ReKi) :: Cd2 !< [-] - REAL(ReKi) :: CdMG2 !< [-] - REAL(ReKi) :: Ca2 !< [-] - REAL(ReKi) :: CaMG2 !< [-] - REAL(ReKi) :: Cp2 !< [-] - REAL(ReKi) :: CpMG2 !< [-] - REAL(ReKi) :: AxCa2 !< [-] - REAL(ReKi) :: AxCaMG2 !< [-] - REAL(ReKi) :: AxCp2 !< [-] - REAL(ReKi) :: AxCpMG2 !< [-] - REAL(ReKi) :: InpMbrDist1 !< [-] - REAL(ReKi) :: InpMbrDist2 !< [-] - REAL(ReKi) :: InpMbrLen !< [-] - INTEGER(IntKi) :: InpMbrIndx !< [-] - REAL(ReKi) , DIMENSION(1:3,1:3) :: R_LToG !< [-] - INTEGER(IntKi) :: NumSplits !< [-] - REAL(ReKi) , DIMENSION(1:5) :: Splits !< [-] - REAL(ReKi) :: MGvolume !< [-] - REAL(ReKi) :: MDivSize !< [-] - INTEGER(IntKi) :: MCoefMod !< [-] - INTEGER(IntKi) :: MmbrCoefIDIndx !< [-] - INTEGER(IntKi) :: MmbrFilledIDIndx !< [-] - REAL(ReKi) :: FillFSLoc !< [-] - REAL(ReKi) :: FillDens !< [-] - REAL(ReKi) , DIMENSION(1:6) :: F_Bouy !< [-] - REAL(ReKi) , DIMENSION(1:6) :: F_DP !< [-] - LOGICAL :: PropPot !< [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: NodeIndx !< Index of each of the member's nodes in the master node list [-] + INTEGER(IntKi) :: MemberID !< User-supplied integer ID for this member [-] + INTEGER(IntKi) :: NElements !< number of elements in this member [-] + REAL(ReKi) :: RefLength !< the reference total length for this member [m] + REAL(ReKi) :: cosPhi_ref !< the reference cosine of the inclination angle of the member [-] + REAL(ReKi) :: dl !< the reference element length for this member (may be less than MDivSize to achieve uniform element lengths) [m] + REAL(ReKi) , DIMENSION(1:3) :: k !< unit vector of the member's orientation (may be changed to per-element once additional flexibility is accounted for in HydroDyn) [m] + REAL(ReKi) , DIMENSION(1:3,1:3) :: kkt !< matrix of matmul(k_hat, transpose(k_hat) [-] + REAL(ReKi) , DIMENSION(1:3,1:3) :: Ak !< matrix of I - kkt [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: R !< outer member radius at each node [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: RMG !< radius at each node including marine growth [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Rin !< inner member radius at node, equivalent to radius of water ballast at this node if filled [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: tMG !< Nodal thickness with marine growth (of member at node location) [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MGdensity !< Nodal density of marine growth [kg/m^3] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: dRdl_mg !< taper dr/dl of outer surface including marine growth of each element [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: dRdl_in !< taper dr/dl of interior surface of each element [-] + REAL(ReKi) :: Vinner !< Member volume without marine growth [m^3] + REAL(ReKi) :: Vouter !< Member volume including marine growth [m^3] + REAL(ReKi) :: Vballast !< Member ballast volume [m^3] + REAL(ReKi) :: Vsubmerged !< Submerged volume corresponding to portion of Member in the water [m^3] + REAL(ReKi) :: l_fill !< fill length along member axis from start node 1 [m] + REAL(ReKi) :: h_fill !< fill length of partially flooded element [m] + REAL(ReKi) :: z_overfill !< if member is fully filled, the head height of the fill pressure at the end node N+1. Zero if member is partially filled. [m] + REAL(ReKi) :: h_floor !< the distance from the node to the seabed along the member axis (negative value) [m] + INTEGER(IntKi) :: i_floor !< the number of the element that pierces the seabed (zero if the member doesn't pierce it) [-] + LOGICAL :: doEndBuoyancy !< compute the end plate effect for the hightest node of this member [-] + INTEGER(IntKi) :: memfloodstatus !< Member-level flooded status for each elemen: 0 unflooded or fully below seabed, 2 partially flooded, 1 fully flooded [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: floodstatus !< flooded status for each element: 0 unflooded or fully below seabed, 1 fully flooded, 2 partially flooded [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: alpha !< relative volume centroid of each element including marine growth, from node i to node i+1 [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: alpha_fb !< relative volume centroid of each element's flooded ballast, from node i to node i+1 [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: alpha_fb_star !< load distribution factor for each element after adjusting alpha_fb for node reference depths [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Cd !< Member Cd at each node [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Ca !< Member Ca at each node [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Cp !< Member Cp at each node [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AxCd !< Member axial Cd at each node [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AxCa !< Member axial Ca at each node [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AxCp !< Member axial Cp at each node [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: m_fb_l !< mass of flooded ballast in lower portion of each element [kg] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: m_fb_u !< mass of flooded ballast in upper portion of each element [kg] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: h_cfb_l !< distance to flooded ballast centroid from node point in lower portion of each element [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: h_cfb_u !< distance to flooded ballast centroid from node point in upper portion of each element [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: I_lfb_l !< axial moment of inertia of flooded ballast in lower portion of each element [kg-m^2] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: I_lfb_u !< axial moment of inertia of flooded ballast in upper portion of each element [kg-m^2] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: I_rfb_l !< radial moment of inertia of flooded ballast in lower portion of each element [kg-m^2] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: I_rfb_u !< radial moment of inertia of flooded ballast in upper portion of each element [kg-m^2] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: m_mg_l !< mass of marine growth in lower portion of each element [kg] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: m_mg_u !< mass of marine growth in upper portion of each element [kg] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: h_cmg_l !< distance to marine growth centroid from node point in lower portion of each element [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: h_cmg_u !< distance to marine growth centroid from node point in upper portion of each element [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: I_lmg_l !< axial moment of inertia of marine growth in lower portion of each element [kg-m^2] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: I_lmg_u !< axial moment of inertia of marine growth in upper portion of each element [kg-m^2] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: I_rmg_l !< radial moment of inertia of marine growth in lower portion of each element [kg-m^2] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: I_rmg_u !< radial moment of inertia of flooded ballast in upper portion of each element [kg-m^2] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Cfl_fb !< axial force constant due to flooded ballast, for each element [N] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Cfr_fb !< radial force constant due to flooded ballast, for each element [N] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: CM0_fb !< moment constant due to flooded ballast, for each element about lower node [Nm] + REAL(ReKi) :: MGvolume !< Volume of marine growth material for this member/element [m^3] + REAL(ReKi) :: MDivSize !< User-requested final element length (actual length may vary from this request) [m] + INTEGER(IntKi) :: MCoefMod !< Coefs model for member: 1 = simple, 2 =depth, 3 = member-based [-] + INTEGER(IntKi) :: MmbrCoefIDIndx !< If MCoefMod=3, then this is the index for the member's coefs in the master Member Coefs Table [-] + INTEGER(IntKi) :: MmbrFilledIDIndx !< If this member is part of a fill group, this is the index into the master fill group table, if not = -1 [-] + REAL(ReKi) :: FillFSLoc !< Z-location of the filled free-surface [m] + REAL(ReKi) :: FillDens !< Filled fluid density [kg/m^3] + LOGICAL :: PropPot !< Is this element/member modeled with potential flow theory T/F [-] + LOGICAL :: Flipped !< Was the member flipped in a reordering event? Need to know this to get the correct normal vector to the ends [-] END TYPE Morison_MemberType ! ======================= +! ========= Morison_MemberLoads ======= + TYPE, PUBLIC :: Morison_MemberLoads + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_D !< Member-based (side-effects) Nodal viscous drag loads at time t [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_I !< Member-based (side-effects) Nodal inertial loads at time t [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_A !< Member-based (side-effects) Nodal added mass loads at time t [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_B !< Member-based (side-effects) Nodal buoyancy loads [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_BF !< Member-based (side-effects) Nodal flooded ballast weight/buoyancy loads [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_If !< Member-based (side-effects) Nodal flooded ballast inertia loads [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_WMG !< Member-based (side-effects) Nodal marine growth weight loads [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_IMG !< Member-based (side-effects) Nodal marine growth inertia loads [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: FV !< Fluid velocity at line element node at time t, which may not correspond to the WaveTime array of times [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: FA !< Fluid acceleration at line element node at time t, which may not correspond to the WaveTime array of times [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_DP !< Lumped dynamic pressure loads at time t, which may not correspond to the WaveTime array of times [-] + END TYPE Morison_MemberLoads +! ======================= ! ========= Morison_CoefMembers ======= TYPE, PUBLIC :: Morison_CoefMembers - INTEGER(IntKi) :: MemberID !< [-] - REAL(ReKi) :: MemberCd1 !< [-] - REAL(ReKi) :: MemberCd2 !< [-] - REAL(ReKi) :: MemberCdMG1 !< [-] - REAL(ReKi) :: MemberCdMG2 !< [-] - REAL(ReKi) :: MemberCa1 !< [-] - REAL(ReKi) :: MemberCa2 !< [-] - REAL(ReKi) :: MemberCaMG1 !< [-] - REAL(ReKi) :: MemberCaMG2 !< [-] - REAL(ReKi) :: MemberCp1 !< [-] - REAL(ReKi) :: MemberCp2 !< [-] - REAL(ReKi) :: MemberCpMG1 !< [-] - REAL(ReKi) :: MemberCpMG2 !< [-] - REAL(ReKi) :: MemberAxCa1 !< [-] - REAL(ReKi) :: MemberAxCa2 !< [-] - REAL(ReKi) :: MemberAxCaMG1 !< [-] - REAL(ReKi) :: MemberAxCaMG2 !< [-] - REAL(ReKi) :: MemberAxCp1 !< [-] - REAL(ReKi) :: MemberAxCp2 !< [-] - REAL(ReKi) :: MemberAxCpMG1 !< [-] - REAL(ReKi) :: MemberAxCpMG2 !< [-] + INTEGER(IntKi) :: MemberID !< User-specified integer id for the Member-based coefs [-] + REAL(ReKi) :: MemberCd1 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberCd2 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberCdMG1 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberCdMG2 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberCa1 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberCa2 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberCaMG1 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberCaMG2 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberCp1 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberCp2 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberCpMG1 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberCpMG2 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberAxCd1 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberAxCd2 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberAxCdMG1 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberAxCdMG2 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberAxCa1 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberAxCa2 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberAxCaMG1 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberAxCaMG2 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberAxCp1 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberAxCp2 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberAxCpMG1 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] + REAL(ReKi) :: MemberAxCpMG2 !< Member-based coefs, see above descriptions for meanings (1 = start, 2=end) [-] END TYPE Morison_CoefMembers ! ======================= ! ========= Morison_MGDepthsType ======= TYPE, PUBLIC :: Morison_MGDepthsType - REAL(ReKi) :: MGDpth !< [-] - REAL(ReKi) :: MGThck !< [-] - REAL(ReKi) :: MGDens !< [-] + REAL(ReKi) :: MGDpth !< Marine growth depth location for these properties [m] + REAL(ReKi) :: MGThck !< Marine growth thickness [m] + REAL(ReKi) :: MGDens !< Marine growth density [kg/m^3] END TYPE Morison_MGDepthsType ! ======================= ! ========= Morison_MOutput ======= TYPE, PUBLIC :: Morison_MOutput - INTEGER(IntKi) :: MemberID !< [-] - INTEGER(IntKi) :: NOutLoc !< [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: NodeLocs !< [-] - INTEGER(IntKi) :: MemberIDIndx !< [-] - INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: Marker1 !< [-] - INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: Marker2 !< [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: s !< [-] + INTEGER(IntKi) :: MemberID !< Member ID for requested output [-] + INTEGER(IntKi) :: NOutLoc !< The number of requested output locations [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: NodeLocs !< Normalized locations along user-specified member for the outputs [-] + INTEGER(IntKi) :: MemberIDIndx !< Index for member in the master list [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: MeshIndx1 !< Index of node in Mesh for the start of the member element [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: MeshIndx2 !< Index of node in Mesh for the end of the member element [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: MemberIndx1 !< Index of Member nodes for the start of the member element [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: MemberIndx2 !< Index of Member nodes for the end of the member element [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: s !< Linear interpolation factor between node1 and node2 for the output location [-] END TYPE Morison_MOutput ! ======================= ! ========= Morison_JOutput ======= TYPE, PUBLIC :: Morison_JOutput - INTEGER(IntKi) :: JointID !< [-] - INTEGER(IntKi) :: JointIDIndx !< [-] - INTEGER(IntKi) :: NumMarkers !< [-] - INTEGER(IntKi) , DIMENSION(1:10) :: Markers !< [-] + INTEGER(IntKi) :: JointID !< Joint ID for the requested output [-] + INTEGER(IntKi) :: JointIDIndx !< Joint index in the master list [-] END TYPE Morison_JOutput ! ======================= ! ========= Morison_InitInputType ======= TYPE, PUBLIC :: Morison_InitInputType - REAL(ReKi) :: Gravity !< [-] - REAL(ReKi) :: WtrDens !< [-] - REAL(ReKi) :: WtrDpth !< [-] - REAL(ReKi) :: MSL2SWL !< [-] - INTEGER(IntKi) :: NJoints !< [-] - INTEGER(IntKi) :: NNodes !< [-] - INTEGER(IntKi) :: TotalPossibleSuperMembers !< [-] - TYPE(Morison_JointType) , DIMENSION(:), ALLOCATABLE :: InpJoints !< [-] - TYPE(Morison_NodeType) , DIMENSION(:), ALLOCATABLE :: Nodes !< [-] - INTEGER(IntKi) :: NElements !< [-] - TYPE(Morison_MemberType) , DIMENSION(:), ALLOCATABLE :: Elements !< [-] - INTEGER(IntKi) :: NAxCoefs !< [-] - TYPE(Morison_AxialCoefType) , DIMENSION(:), ALLOCATABLE :: AxialCoefs !< [-] - INTEGER(IntKi) :: NPropSets !< [-] - TYPE(Morison_MemberPropType) , DIMENSION(:), ALLOCATABLE :: MPropSets !< [-] - REAL(ReKi) :: SimplCd !< [-] - REAL(ReKi) :: SimplCdMG !< [-] - REAL(ReKi) :: SimplCa !< [-] - REAL(ReKi) :: SimplCaMG !< [-] - REAL(ReKi) :: SimplCp !< [-] - REAL(ReKi) :: SimplCpMG !< [-] - REAL(ReKi) :: SimplAxCa !< [-] - REAL(ReKi) :: SimplAxCaMG !< [-] - REAL(ReKi) :: SimplAxCp !< [-] - REAL(ReKi) :: SimplAxCpMG !< [-] + REAL(ReKi) :: Gravity !< Gravity (scalar, positive-valued) [m/s^2] + REAL(ReKi) :: WtrDens !< Water density [kg/m^3] + REAL(ReKi) :: WtrDpth !< Water depth (positive-valued) [m] + REAL(ReKi) :: MSL2SWL !< Mean Sea Level to Still Water Level offset [m] + INTEGER(IntKi) :: NJoints !< Number of user-specified joints [-] + INTEGER(IntKi) :: NNodes !< Total number of nodes in the final software model [-] + TYPE(Morison_JointType) , DIMENSION(:), ALLOCATABLE :: InpJoints !< Array of user-specified joints [-] + TYPE(Morison_NodeType) , DIMENSION(:), ALLOCATABLE :: Nodes !< Array of simulation node (some correspond to user-specified joints, others are created by software) [-] + INTEGER(IntKi) :: NAxCoefs !< Number of axial Coefs entries in input file table [-] + TYPE(Morison_AxialCoefType) , DIMENSION(:), ALLOCATABLE :: AxialCoefs !< List of axial coefs [-] + INTEGER(IntKi) :: NPropSets !< Number of member property sets [-] + TYPE(Morison_MemberPropType) , DIMENSION(:), ALLOCATABLE :: MPropSets !< List of Member property sets [-] + REAL(ReKi) :: SimplCd !< Simple model drag coef [-] + REAL(ReKi) :: SimplCdMG !< Simple model drag coef for marine growth [-] + REAL(ReKi) :: SimplCa !< Simple model Ca [-] + REAL(ReKi) :: SimplCaMG !< Simple model Ca for marine growth [-] + REAL(ReKi) :: SimplCp !< Simple model Cp [-] + REAL(ReKi) :: SimplCpMG !< Simple model Cp for marine growth [-] + REAL(ReKi) :: SimplAxCd !< Simple model Axial Cd [-] + REAL(ReKi) :: SimplAxCdMG !< Simple model Axial Cd for marine growth [-] + REAL(ReKi) :: SimplAxCa !< Simple model Axial Ca [-] + REAL(ReKi) :: SimplAxCaMG !< Simple model Axial Ca for marine growth [-] + REAL(ReKi) :: SimplAxCp !< Simple model Axial Cp [-] + REAL(ReKi) :: SimplAxCpMG !< Simple model Axial Cp for marine growth [-] INTEGER(IntKi) :: NCoefDpth !< [-] TYPE(Morison_CoefDpths) , DIMENSION(:), ALLOCATABLE :: CoefDpths !< [-] INTEGER(IntKi) :: NCoefMembers !< [-] TYPE(Morison_CoefMembers) , DIMENSION(:), ALLOCATABLE :: CoefMembers !< [-] - INTEGER(IntKi) :: NMembers !< [-] - TYPE(Morison_MemberInputType) , DIMENSION(:), ALLOCATABLE :: InpMembers !< [-] + INTEGER(IntKi) :: NMembers !< Number of user-specified members in the input file [-] + TYPE(Morison_MemberInputType) , DIMENSION(:), ALLOCATABLE :: InpMembers !< Array of user-specified members [-] INTEGER(IntKi) :: NFillGroups !< [-] TYPE(Morison_FilledGroupType) , DIMENSION(:), ALLOCATABLE :: FilledGroups !< [-] INTEGER(IntKi) :: NMGDepths !< [-] @@ -301,10 +323,7 @@ MODULE Morison_Types ! ======================= ! ========= Morison_InitOutputType ======= TYPE, PUBLIC :: Morison_InitOutputType - TYPE(MeshType) :: DistribMesh !< [-] - TYPE(MeshType) :: LumpedMesh !< [-] - REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: Morison_Rad !< radius of node (for FAST visualization) [(m)] - CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< [-] + CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< User-requested Output channel names [-] CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputUnt !< [-] END TYPE Morison_InitOutputType ! ======================= @@ -315,7 +334,7 @@ MODULE Morison_Types ! ======================= ! ========= Morison_DiscreteStateType ======= TYPE, PUBLIC :: Morison_DiscreteStateType - REAL(SiKi) :: DummyDiscState !< [-] + REAL(SiKi) :: DummyDiscState !< Remove this variable if you have discrete states [-] END TYPE Morison_DiscreteStateType ! ======================= ! ========= Morison_ConstraintStateType ======= @@ -330,60 +349,43 @@ MODULE Morison_Types ! ======================= ! ========= Morison_MiscVarType ======= TYPE, PUBLIC :: Morison_MiscVarType - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D_F_D !< Distributed viscous drag loads [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D_F_I !< Distributed inertial loads [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D_F_B !< Distributed bounancy loads [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D_F_AM !< Distributed total added mass loads [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D_F_AM_M !< Distributed member added mass loads [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D_F_AM_MG !< Distributed marine growth added mass (weight) loads [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D_F_AM_F !< Distributed added mass loads due to flooding/filled fluid [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D_FV !< Fluid velocity at line element node [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D_FA !< Fluid acceleration at line element node [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: D_FDynP !< Fluid dynamic pressure at line element node [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: L_F_B !< [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: L_F_D !< Lumped viscous drag loads [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: L_F_I !< Lumped intertia loads [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: L_F_DP !< Lumped dynamic pressure loads [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: L_F_AM !< Lumped added mass loads [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: L_FV !< Fluid velocity at point element node [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: L_FA !< Fluid acceleration at point element node [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: L_FDynP !< Fluid dynamic pressure at point element node [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: FV !< Fluid velocity at line element node at time t, which may not correspond to the WaveTime array of times [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: FA !< Fluid acceleration at line element node at time t, which may not correspond to the WaveTime array of times [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FDynP !< Fluid dynamic pressure at line element node at time t, which may not correspond to the WaveTime array of times [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: vrel !< velocity of structural node relative to the water [m/s^2] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: nodeInWater !< Logical flag indicating if the node at the given time step is in the water, and hence needs to have hydrodynamic forces calculated [-] + TYPE(Morison_MemberLoads) , DIMENSION(:), ALLOCATABLE :: memberLoads !< Array (NMembers long) of member-based side-effects load contributions [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_B_End !< [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_D_End !< Lumped viscous drag loads at time t, which may not correspond to the WaveTime array of times [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_I_End !< Lumped intertia loads at time t, which may not correspond to the WaveTime array of times [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_IMG_End !< Joint marine growth intertia loads at time t, which may not correspond to the WaveTime array of times [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_A_End !< Lumped added mass loads at time t, which may not correspond to the WaveTime array of times [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_BF_End !< [-] INTEGER(IntKi) :: LastIndWave !< Last time index used in the wave kinematics arrays [-] END TYPE Morison_MiscVarType ! ======================= ! ========= Morison_ParameterType ======= TYPE, PUBLIC :: Morison_ParameterType REAL(DbKi) :: DT !< Time step for continuous state integration & discrete state update [(sec)] - REAL(ReKi) :: WtrDens !< [-] + REAL(ReKi) :: Gravity !< Gravity (scalar, positive-valued) [m/s^2] + REAL(ReKi) :: WtrDens !< Water density [kg/m^3] + REAL(ReKi) :: WtrDpth !< Water depth (positive-valued) [m] + INTEGER(IntKi) :: NMembers !< number of members [-] + TYPE(Morison_MemberType) , DIMENSION(:), ALLOCATABLE :: Members !< Array of Morison members used during simulation [-] INTEGER(IntKi) :: NNodes !< [-] - TYPE(Morison_NodeType) , DIMENSION(:), ALLOCATABLE :: Nodes !< [-] - REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: D_F_I !< [-] - REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: D_F_DP !< [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: D_dragConst !< [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: L_An !< [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: L_F_B !< [-] - REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: L_F_I !< [-] - REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: L_F_DP !< [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: L_F_BF !< [-] - REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: L_AM_M !< [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: L_dragConst !< [-] - INTEGER(IntKi) :: NDistribMarkers !< [-] - INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: distribToNodeIndx !< [-] - INTEGER(IntKi) :: NLumpedMarkers !< [-] - INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: lumpedToNodeIndx !< [-] + INTEGER(IntKi) :: NJoints !< Number of user-specified joints [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: I_MG_End !< Inertial matrix associated with marine growth mass at joint [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: An_End !< directional area vector of each joint [m^2] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: DragConst_End !< [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_WMG_End !< Joint marine growth weight loads, constant for all t [N] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: DP_Const_End !< Constant part of Joint dynamic pressure term [N] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Mass_MG_End !< Joint marine growth mass [kg] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: AM_End !< 3x3 Joint added mass matrix, constant for all t [N] REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: WaveVel !< [-] REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: WaveAcc !< [-] REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: WaveDynP !< [-] - REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveTime !< [-] - INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: elementWaterState !< State indicating if the element a node is attached to at the given time step is in the water [0], above the water [1], or in the seabed [2] [-] - INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: elementFillState !< State indicating if the element a node is attached to is in the filled fluid [0], above the fluid [1], or in the seabed [2] [-] + REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveTime !< Times for which the wave kinematics are pre-computed [s] INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: nodeInWater !< Logical flag indicating if the node at the given time step is in the water, and hence needs to have hydrodynamic forces calculated [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D_F_B !< Distributed buoyancy loads [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D_F_BF !< Distributed filled buoyancy loads [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D_F_MG !< Distributed marine growth loads [-] - REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: D_AM_M !< Distributed member added mass matrix [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: D_AM_MG !< Distributed marine growth added mass matrix (weight) [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: D_AM_F !< Distributed added mass matrix due to flooding/filled fluid [-] INTEGER(IntKi) :: NStepWave !< [-] INTEGER(IntKi) :: NMOutputs !< [-] TYPE(Morison_MOutput) , DIMENSION(:), ALLOCATABLE :: MOutLst !< [-] @@ -401,14 +403,12 @@ MODULE Morison_Types ! ======================= ! ========= Morison_InputType ======= TYPE, PUBLIC :: Morison_InputType - TYPE(MeshType) :: DistribMesh !< Distributed Loads Meshed input data [-] - TYPE(MeshType) :: LumpedMesh !< Lumped Loads Meshed input data [-] + TYPE(MeshType) :: Mesh !< Kinematics of each node input mesh [-] END TYPE Morison_InputType ! ======================= ! ========= Morison_OutputType ======= TYPE, PUBLIC :: Morison_OutputType - TYPE(MeshType) :: DistribMesh !< Distributed Loads Meshed output data [-] - TYPE(MeshType) :: LumpedMesh !< Lumped Loads Meshed output data [-] + TYPE(MeshType) :: Mesh !< Loads on each node output mesh [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WriteOutput !< [-] END TYPE Morison_OutputType ! ======================= @@ -431,7 +431,7 @@ SUBROUTINE Morison_CopyJointType( SrcJointTypeData, DstJointTypeData, CtrlCode, ErrStat = ErrID_None ErrMsg = "" DstJointTypeData%JointID = SrcJointTypeData%JointID - DstJointTypeData%JointPos = SrcJointTypeData%JointPos + DstJointTypeData%Position = SrcJointTypeData%Position DstJointTypeData%JointAxID = SrcJointTypeData%JointAxID DstJointTypeData%JointAxIDIndx = SrcJointTypeData%JointAxIDIndx DstJointTypeData%JointOvrlp = SrcJointTypeData%JointOvrlp @@ -486,7 +486,7 @@ SUBROUTINE Morison_PackJointType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Db_BufSz = 0 Int_BufSz = 0 Int_BufSz = Int_BufSz + 1 ! JointID - Re_BufSz = Re_BufSz + SIZE(InData%JointPos) ! JointPos + Re_BufSz = Re_BufSz + SIZE(InData%Position) ! Position Int_BufSz = Int_BufSz + 1 ! JointAxID Int_BufSz = Int_BufSz + 1 ! JointAxIDIndx Int_BufSz = Int_BufSz + 1 ! JointOvrlp @@ -521,8 +521,8 @@ SUBROUTINE Morison_PackJointType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E IntKiBuf(Int_Xferred) = InData%JointID Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%JointPos,1), UBOUND(InData%JointPos,1) - ReKiBuf(Re_Xferred) = InData%JointPos(i1) + DO i1 = LBOUND(InData%Position,1), UBOUND(InData%Position,1) + ReKiBuf(Re_Xferred) = InData%Position(i1) Re_Xferred = Re_Xferred + 1 END DO IntKiBuf(Int_Xferred) = InData%JointAxID @@ -570,10 +570,10 @@ SUBROUTINE Morison_UnPackJointType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Int_Xferred = 1 OutData%JointID = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%JointPos,1) - i1_u = UBOUND(OutData%JointPos,1) - DO i1 = LBOUND(OutData%JointPos,1), UBOUND(OutData%JointPos,1) - OutData%JointPos(i1) = ReKiBuf(Re_Xferred) + i1_l = LBOUND(OutData%Position,1) + i1_u = UBOUND(OutData%Position,1) + DO i1 = LBOUND(OutData%Position,1), UBOUND(OutData%Position,1) + OutData%Position(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO OutData%JointAxID = IntKiBuf(Int_Xferred) @@ -952,6 +952,8 @@ SUBROUTINE Morison_CopyCoefDpths( SrcCoefDpthsData, DstCoefDpthsData, CtrlCode, DstCoefDpthsData%DpthCaMG = SrcCoefDpthsData%DpthCaMG DstCoefDpthsData%DpthCp = SrcCoefDpthsData%DpthCp DstCoefDpthsData%DpthCpMG = SrcCoefDpthsData%DpthCpMG + DstCoefDpthsData%DpthAxCd = SrcCoefDpthsData%DpthAxCd + DstCoefDpthsData%DpthAxCdMG = SrcCoefDpthsData%DpthAxCdMG DstCoefDpthsData%DpthAxCa = SrcCoefDpthsData%DpthAxCa DstCoefDpthsData%DpthAxCaMG = SrcCoefDpthsData%DpthAxCaMG DstCoefDpthsData%DpthAxCp = SrcCoefDpthsData%DpthAxCp @@ -1011,6 +1013,8 @@ SUBROUTINE Morison_PackCoefDpths( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Re_BufSz = Re_BufSz + 1 ! DpthCaMG Re_BufSz = Re_BufSz + 1 ! DpthCp Re_BufSz = Re_BufSz + 1 ! DpthCpMG + Re_BufSz = Re_BufSz + 1 ! DpthAxCd + Re_BufSz = Re_BufSz + 1 ! DpthAxCdMG Re_BufSz = Re_BufSz + 1 ! DpthAxCa Re_BufSz = Re_BufSz + 1 ! DpthAxCaMG Re_BufSz = Re_BufSz + 1 ! DpthAxCp @@ -1056,6 +1060,10 @@ SUBROUTINE Morison_PackCoefDpths( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%DpthCpMG Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%DpthAxCd + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%DpthAxCdMG + Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%DpthAxCa Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%DpthAxCaMG @@ -1106,6 +1114,10 @@ SUBROUTINE Morison_UnPackCoefDpths( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Re_Xferred = Re_Xferred + 1 OutData%DpthCpMG = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%DpthAxCd = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%DpthAxCdMG = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 OutData%DpthAxCa = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%DpthAxCaMG = ReKiBuf(Re_Xferred) @@ -1268,7 +1280,6 @@ SUBROUTINE Morison_CopyMemberInputType( SrcMemberInputTypeData, DstMemberInputTy ! Local INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'Morison_CopyMemberInputType' @@ -1276,6 +1287,18 @@ SUBROUTINE Morison_CopyMemberInputType( SrcMemberInputTypeData, DstMemberInputTy ErrStat = ErrID_None ErrMsg = "" DstMemberInputTypeData%MemberID = SrcMemberInputTypeData%MemberID +IF (ALLOCATED(SrcMemberInputTypeData%NodeIndx)) THEN + i1_l = LBOUND(SrcMemberInputTypeData%NodeIndx,1) + i1_u = UBOUND(SrcMemberInputTypeData%NodeIndx,1) + IF (.NOT. ALLOCATED(DstMemberInputTypeData%NodeIndx)) THEN + ALLOCATE(DstMemberInputTypeData%NodeIndx(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberInputTypeData%NodeIndx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberInputTypeData%NodeIndx = SrcMemberInputTypeData%NodeIndx +ENDIF DstMemberInputTypeData%MJointID1 = SrcMemberInputTypeData%MJointID1 DstMemberInputTypeData%MJointID2 = SrcMemberInputTypeData%MJointID2 DstMemberInputTypeData%MJointID1Indx = SrcMemberInputTypeData%MJointID1Indx @@ -1289,9 +1312,9 @@ SUBROUTINE Morison_CopyMemberInputType( SrcMemberInputTypeData, DstMemberInputTy DstMemberInputTypeData%MmbrCoefIDIndx = SrcMemberInputTypeData%MmbrCoefIDIndx DstMemberInputTypeData%MmbrFilledIDIndx = SrcMemberInputTypeData%MmbrFilledIDIndx DstMemberInputTypeData%PropPot = SrcMemberInputTypeData%PropPot - DstMemberInputTypeData%NumSplits = SrcMemberInputTypeData%NumSplits - DstMemberInputTypeData%Splits = SrcMemberInputTypeData%Splits - DstMemberInputTypeData%R_LToG = SrcMemberInputTypeData%R_LToG + DstMemberInputTypeData%NElements = SrcMemberInputTypeData%NElements + DstMemberInputTypeData%RefLength = SrcMemberInputTypeData%RefLength + DstMemberInputTypeData%dl = SrcMemberInputTypeData%dl END SUBROUTINE Morison_CopyMemberInputType SUBROUTINE Morison_DestroyMemberInputType( MemberInputTypeData, ErrStat, ErrMsg ) @@ -1303,6 +1326,9 @@ SUBROUTINE Morison_DestroyMemberInputType( MemberInputTypeData, ErrStat, ErrMsg ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(MemberInputTypeData%NodeIndx)) THEN + DEALLOCATE(MemberInputTypeData%NodeIndx) +ENDIF END SUBROUTINE Morison_DestroyMemberInputType SUBROUTINE Morison_PackMemberInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1341,6 +1367,11 @@ SUBROUTINE Morison_PackMemberInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrS Db_BufSz = 0 Int_BufSz = 0 Int_BufSz = Int_BufSz + 1 ! MemberID + Int_BufSz = Int_BufSz + 1 ! NodeIndx allocated yes/no + IF ( ALLOCATED(InData%NodeIndx) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! NodeIndx upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%NodeIndx) ! NodeIndx + END IF Int_BufSz = Int_BufSz + 1 ! MJointID1 Int_BufSz = Int_BufSz + 1 ! MJointID2 Int_BufSz = Int_BufSz + 1 ! MJointID1Indx @@ -1354,9 +1385,9 @@ SUBROUTINE Morison_PackMemberInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrS Int_BufSz = Int_BufSz + 1 ! MmbrCoefIDIndx Int_BufSz = Int_BufSz + 1 ! MmbrFilledIDIndx Int_BufSz = Int_BufSz + 1 ! PropPot - Int_BufSz = Int_BufSz + 1 ! NumSplits - Re_BufSz = Re_BufSz + SIZE(InData%Splits) ! Splits - Re_BufSz = Re_BufSz + SIZE(InData%R_LToG) ! R_LToG + Int_BufSz = Int_BufSz + 1 ! NElements + Re_BufSz = Re_BufSz + 1 ! RefLength + Re_BufSz = Re_BufSz + 1 ! dl IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1386,6 +1417,21 @@ SUBROUTINE Morison_PackMemberInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrS IntKiBuf(Int_Xferred) = InData%MemberID Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%NodeIndx) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%NodeIndx,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NodeIndx,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%NodeIndx,1), UBOUND(InData%NodeIndx,1) + IntKiBuf(Int_Xferred) = InData%NodeIndx(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF IntKiBuf(Int_Xferred) = InData%MJointID1 Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%MJointID2 @@ -1412,18 +1458,12 @@ SUBROUTINE Morison_PackMemberInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrS Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%PropPot, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NumSplits + IntKiBuf(Int_Xferred) = InData%NElements Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%Splits,1), UBOUND(InData%Splits,1) - ReKiBuf(Re_Xferred) = InData%Splits(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i2 = LBOUND(InData%R_LToG,2), UBOUND(InData%R_LToG,2) - DO i1 = LBOUND(InData%R_LToG,1), UBOUND(InData%R_LToG,1) - ReKiBuf(Re_Xferred) = InData%R_LToG(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + ReKiBuf(Re_Xferred) = InData%RefLength + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%dl + Re_Xferred = Re_Xferred + 1 END SUBROUTINE Morison_PackMemberInputType SUBROUTINE Morison_UnPackMemberInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1440,7 +1480,6 @@ SUBROUTINE Morison_UnPackMemberInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, E INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'Morison_UnPackMemberInputType' @@ -1456,6 +1495,24 @@ SUBROUTINE Morison_UnPackMemberInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, E Int_Xferred = 1 OutData%MemberID = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NodeIndx not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%NodeIndx)) DEALLOCATE(OutData%NodeIndx) + ALLOCATE(OutData%NodeIndx(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%NodeIndx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%NodeIndx,1), UBOUND(OutData%NodeIndx,1) + OutData%NodeIndx(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF OutData%MJointID1 = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%MJointID2 = IntKiBuf(Int_Xferred) @@ -1482,24 +1539,12 @@ SUBROUTINE Morison_UnPackMemberInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, E Int_Xferred = Int_Xferred + 1 OutData%PropPot = TRANSFER(IntKiBuf(Int_Xferred), OutData%PropPot) Int_Xferred = Int_Xferred + 1 - OutData%NumSplits = IntKiBuf(Int_Xferred) + OutData%NElements = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%Splits,1) - i1_u = UBOUND(OutData%Splits,1) - DO i1 = LBOUND(OutData%Splits,1), UBOUND(OutData%Splits,1) - OutData%Splits(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%R_LToG,1) - i1_u = UBOUND(OutData%R_LToG,1) - i2_l = LBOUND(OutData%R_LToG,2) - i2_u = UBOUND(OutData%R_LToG,2) - DO i2 = LBOUND(OutData%R_LToG,2), UBOUND(OutData%R_LToG,2) - DO i1 = LBOUND(OutData%R_LToG,1), UBOUND(OutData%R_LToG,1) - OutData%R_LToG(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + OutData%RefLength = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%dl = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE Morison_UnPackMemberInputType SUBROUTINE Morison_CopyNodeType( SrcNodeTypeData, DstNodeTypeData, CtrlCode, ErrStat, ErrMsg ) @@ -1511,46 +1556,24 @@ SUBROUTINE Morison_CopyNodeType( SrcNodeTypeData, DstNodeTypeData, CtrlCode, Err ! Local INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'Morison_CopyNodeType' ! ErrStat = ErrID_None ErrMsg = "" - DstNodeTypeData%NodeType = SrcNodeTypeData%NodeType DstNodeTypeData%JointIndx = SrcNodeTypeData%JointIndx - DstNodeTypeData%JointPos = SrcNodeTypeData%JointPos + DstNodeTypeData%Position = SrcNodeTypeData%Position DstNodeTypeData%JointOvrlp = SrcNodeTypeData%JointOvrlp DstNodeTypeData%JointAxIDIndx = SrcNodeTypeData%JointAxIDIndx DstNodeTypeData%NConnections = SrcNodeTypeData%NConnections DstNodeTypeData%ConnectionList = SrcNodeTypeData%ConnectionList - DstNodeTypeData%NConnectPreSplit = SrcNodeTypeData%NConnectPreSplit - DstNodeTypeData%Cd = SrcNodeTypeData%Cd - DstNodeTypeData%CdMG = SrcNodeTypeData%CdMG - DstNodeTypeData%Ca = SrcNodeTypeData%Ca - DstNodeTypeData%CaMG = SrcNodeTypeData%CaMG - DstNodeTypeData%Cp = SrcNodeTypeData%Cp - DstNodeTypeData%CpMG = SrcNodeTypeData%CpMG DstNodeTypeData%JAxCd = SrcNodeTypeData%JAxCd DstNodeTypeData%JAxCa = SrcNodeTypeData%JAxCa DstNodeTypeData%JAxCp = SrcNodeTypeData%JAxCp - DstNodeTypeData%AxCa = SrcNodeTypeData%AxCa - DstNodeTypeData%AxCp = SrcNodeTypeData%AxCp - DstNodeTypeData%AxCaMG = SrcNodeTypeData%AxCaMG - DstNodeTypeData%AxCpMG = SrcNodeTypeData%AxCpMG - DstNodeTypeData%R = SrcNodeTypeData%R - DstNodeTypeData%t = SrcNodeTypeData%t + DstNodeTypeData%FillDensity = SrcNodeTypeData%FillDensity DstNodeTypeData%tMG = SrcNodeTypeData%tMG - DstNodeTypeData%dRdz = SrcNodeTypeData%dRdz DstNodeTypeData%MGdensity = SrcNodeTypeData%MGdensity - DstNodeTypeData%FillFSLoc = SrcNodeTypeData%FillFSLoc - DstNodeTypeData%FillFlag = SrcNodeTypeData%FillFlag - DstNodeTypeData%FillDensity = SrcNodeTypeData%FillDensity - DstNodeTypeData%InpMbrIndx = SrcNodeTypeData%InpMbrIndx - DstNodeTypeData%InpMbrDist = SrcNodeTypeData%InpMbrDist - DstNodeTypeData%PropPot = SrcNodeTypeData%PropPot - DstNodeTypeData%R_LToG = SrcNodeTypeData%R_LToG END SUBROUTINE Morison_CopyNodeType SUBROUTINE Morison_DestroyNodeType( NodeTypeData, ErrStat, ErrMsg ) @@ -1599,39 +1622,18 @@ SUBROUTINE Morison_PackNodeType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! NodeType Int_BufSz = Int_BufSz + 1 ! JointIndx - Re_BufSz = Re_BufSz + SIZE(InData%JointPos) ! JointPos + Re_BufSz = Re_BufSz + SIZE(InData%Position) ! Position Int_BufSz = Int_BufSz + 1 ! JointOvrlp Int_BufSz = Int_BufSz + 1 ! JointAxIDIndx Int_BufSz = Int_BufSz + 1 ! NConnections Int_BufSz = Int_BufSz + SIZE(InData%ConnectionList) ! ConnectionList - Int_BufSz = Int_BufSz + 1 ! NConnectPreSplit - Re_BufSz = Re_BufSz + 1 ! Cd - Re_BufSz = Re_BufSz + 1 ! CdMG - Re_BufSz = Re_BufSz + 1 ! Ca - Re_BufSz = Re_BufSz + 1 ! CaMG - Re_BufSz = Re_BufSz + 1 ! Cp - Re_BufSz = Re_BufSz + 1 ! CpMG Re_BufSz = Re_BufSz + 1 ! JAxCd Re_BufSz = Re_BufSz + 1 ! JAxCa Re_BufSz = Re_BufSz + 1 ! JAxCp - Re_BufSz = Re_BufSz + 1 ! AxCa - Re_BufSz = Re_BufSz + 1 ! AxCp - Re_BufSz = Re_BufSz + 1 ! AxCaMG - Re_BufSz = Re_BufSz + 1 ! AxCpMG - Re_BufSz = Re_BufSz + 1 ! R - Re_BufSz = Re_BufSz + 1 ! t + Re_BufSz = Re_BufSz + 1 ! FillDensity Re_BufSz = Re_BufSz + 1 ! tMG - Re_BufSz = Re_BufSz + 1 ! dRdz Re_BufSz = Re_BufSz + 1 ! MGdensity - Re_BufSz = Re_BufSz + 1 ! FillFSLoc - Int_BufSz = Int_BufSz + 1 ! FillFlag - Re_BufSz = Re_BufSz + 1 ! FillDensity - Int_BufSz = Int_BufSz + 1 ! InpMbrIndx - Re_BufSz = Re_BufSz + 1 ! InpMbrDist - Int_BufSz = Int_BufSz + 1 ! PropPot - Re_BufSz = Re_BufSz + SIZE(InData%R_LToG) ! R_LToG IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1659,12 +1661,10 @@ SUBROUTINE Morison_PackNodeType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = InData%NodeType - Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%JointIndx Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%JointPos,1), UBOUND(InData%JointPos,1) - ReKiBuf(Re_Xferred) = InData%JointPos(i1) + DO i1 = LBOUND(InData%Position,1), UBOUND(InData%Position,1) + ReKiBuf(Re_Xferred) = InData%Position(i1) Re_Xferred = Re_Xferred + 1 END DO IntKiBuf(Int_Xferred) = InData%JointOvrlp @@ -1677,62 +1677,18 @@ SUBROUTINE Morison_PackNodeType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er IntKiBuf(Int_Xferred) = InData%ConnectionList(i1) Int_Xferred = Int_Xferred + 1 END DO - IntKiBuf(Int_Xferred) = InData%NConnectPreSplit - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Cd - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%CdMG - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Ca - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%CaMG - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Cp - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%CpMG - Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%JAxCd Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%JAxCa Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%JAxCp Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%AxCa - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%AxCp - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%AxCaMG - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%AxCpMG - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%R - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%t + ReKiBuf(Re_Xferred) = InData%FillDensity Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%tMG Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%dRdz - Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%MGdensity Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%FillFSLoc - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%FillFlag, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%FillDensity - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%InpMbrIndx - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InpMbrDist - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%PropPot, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - DO i2 = LBOUND(InData%R_LToG,2), UBOUND(InData%R_LToG,2) - DO i1 = LBOUND(InData%R_LToG,1), UBOUND(InData%R_LToG,1) - ReKiBuf(Re_Xferred) = InData%R_LToG(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO END SUBROUTINE Morison_PackNodeType SUBROUTINE Morison_UnPackNodeType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1749,7 +1705,6 @@ SUBROUTINE Morison_UnPackNodeType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'Morison_UnPackNodeType' @@ -1763,14 +1718,12 @@ SUBROUTINE Morison_UnPackNodeType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%NodeType = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 OutData%JointIndx = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%JointPos,1) - i1_u = UBOUND(OutData%JointPos,1) - DO i1 = LBOUND(OutData%JointPos,1), UBOUND(OutData%JointPos,1) - OutData%JointPos(i1) = ReKiBuf(Re_Xferred) + i1_l = LBOUND(OutData%Position,1) + i1_u = UBOUND(OutData%Position,1) + DO i1 = LBOUND(OutData%Position,1), UBOUND(OutData%Position,1) + OutData%Position(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO OutData%JointOvrlp = IntKiBuf(Int_Xferred) @@ -1785,66 +1738,18 @@ SUBROUTINE Morison_UnPackNodeType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, OutData%ConnectionList(i1) = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 END DO - OutData%NConnectPreSplit = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%Cd = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%CdMG = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Ca = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%CaMG = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Cp = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%CpMG = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 OutData%JAxCd = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%JAxCa = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%JAxCp = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%AxCa = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%AxCp = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%AxCaMG = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%AxCpMG = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%R = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%t = ReKiBuf(Re_Xferred) + OutData%FillDensity = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%tMG = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%dRdz = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 OutData%MGdensity = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%FillFSLoc = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%FillFlag = TRANSFER(IntKiBuf(Int_Xferred), OutData%FillFlag) - Int_Xferred = Int_Xferred + 1 - OutData%FillDensity = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InpMbrIndx = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%InpMbrDist = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%PropPot = TRANSFER(IntKiBuf(Int_Xferred), OutData%PropPot) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%R_LToG,1) - i1_u = UBOUND(OutData%R_LToG,1) - i2_l = LBOUND(OutData%R_LToG,2) - i2_u = UBOUND(OutData%R_LToG,2) - DO i2 = LBOUND(OutData%R_LToG,2), UBOUND(OutData%R_LToG,2) - DO i1 = LBOUND(OutData%R_LToG,1), UBOUND(OutData%R_LToG,1) - OutData%R_LToG(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO END SUBROUTINE Morison_UnPackNodeType SUBROUTINE Morison_CopyMemberType( SrcMemberTypeData, DstMemberTypeData, CtrlCode, ErrStat, ErrMsg ) @@ -1863,400 +1768,3109 @@ SUBROUTINE Morison_CopyMemberType( SrcMemberTypeData, DstMemberTypeData, CtrlCod ! ErrStat = ErrID_None ErrMsg = "" - DstMemberTypeData%Node1Indx = SrcMemberTypeData%Node1Indx - DstMemberTypeData%Node2Indx = SrcMemberTypeData%Node2Indx - DstMemberTypeData%R1 = SrcMemberTypeData%R1 - DstMemberTypeData%t1 = SrcMemberTypeData%t1 - DstMemberTypeData%R2 = SrcMemberTypeData%R2 - DstMemberTypeData%t2 = SrcMemberTypeData%t2 - DstMemberTypeData%Cd1 = SrcMemberTypeData%Cd1 - DstMemberTypeData%CdMG1 = SrcMemberTypeData%CdMG1 - DstMemberTypeData%Ca1 = SrcMemberTypeData%Ca1 - DstMemberTypeData%CaMG1 = SrcMemberTypeData%CaMG1 - DstMemberTypeData%Cp1 = SrcMemberTypeData%Cp1 - DstMemberTypeData%CpMG1 = SrcMemberTypeData%CpMG1 - DstMemberTypeData%AxCa1 = SrcMemberTypeData%AxCa1 - DstMemberTypeData%AxCaMG1 = SrcMemberTypeData%AxCaMG1 - DstMemberTypeData%AxCp1 = SrcMemberTypeData%AxCp1 - DstMemberTypeData%AxCpMG1 = SrcMemberTypeData%AxCpMG1 - DstMemberTypeData%Cd2 = SrcMemberTypeData%Cd2 - DstMemberTypeData%CdMG2 = SrcMemberTypeData%CdMG2 - DstMemberTypeData%Ca2 = SrcMemberTypeData%Ca2 - DstMemberTypeData%CaMG2 = SrcMemberTypeData%CaMG2 - DstMemberTypeData%Cp2 = SrcMemberTypeData%Cp2 - DstMemberTypeData%CpMG2 = SrcMemberTypeData%CpMG2 - DstMemberTypeData%AxCa2 = SrcMemberTypeData%AxCa2 - DstMemberTypeData%AxCaMG2 = SrcMemberTypeData%AxCaMG2 - DstMemberTypeData%AxCp2 = SrcMemberTypeData%AxCp2 - DstMemberTypeData%AxCpMG2 = SrcMemberTypeData%AxCpMG2 - DstMemberTypeData%InpMbrDist1 = SrcMemberTypeData%InpMbrDist1 - DstMemberTypeData%InpMbrDist2 = SrcMemberTypeData%InpMbrDist2 - DstMemberTypeData%InpMbrLen = SrcMemberTypeData%InpMbrLen - DstMemberTypeData%InpMbrIndx = SrcMemberTypeData%InpMbrIndx - DstMemberTypeData%R_LToG = SrcMemberTypeData%R_LToG - DstMemberTypeData%NumSplits = SrcMemberTypeData%NumSplits - DstMemberTypeData%Splits = SrcMemberTypeData%Splits - DstMemberTypeData%MGvolume = SrcMemberTypeData%MGvolume - DstMemberTypeData%MDivSize = SrcMemberTypeData%MDivSize - DstMemberTypeData%MCoefMod = SrcMemberTypeData%MCoefMod - DstMemberTypeData%MmbrCoefIDIndx = SrcMemberTypeData%MmbrCoefIDIndx - DstMemberTypeData%MmbrFilledIDIndx = SrcMemberTypeData%MmbrFilledIDIndx - DstMemberTypeData%FillFSLoc = SrcMemberTypeData%FillFSLoc - DstMemberTypeData%FillDens = SrcMemberTypeData%FillDens - DstMemberTypeData%F_Bouy = SrcMemberTypeData%F_Bouy - DstMemberTypeData%F_DP = SrcMemberTypeData%F_DP - DstMemberTypeData%PropPot = SrcMemberTypeData%PropPot - END SUBROUTINE Morison_CopyMemberType - - SUBROUTINE Morison_DestroyMemberType( MemberTypeData, ErrStat, ErrMsg ) - TYPE(Morison_MemberType), INTENT(INOUT) :: MemberTypeData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMemberType' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE Morison_DestroyMemberType - - SUBROUTINE Morison_PackMemberType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(Morison_MemberType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_PackMemberType' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! Node1Indx - Int_BufSz = Int_BufSz + 1 ! Node2Indx - Re_BufSz = Re_BufSz + 1 ! R1 - Re_BufSz = Re_BufSz + 1 ! t1 - Re_BufSz = Re_BufSz + 1 ! R2 - Re_BufSz = Re_BufSz + 1 ! t2 - Re_BufSz = Re_BufSz + 1 ! Cd1 - Re_BufSz = Re_BufSz + 1 ! CdMG1 - Re_BufSz = Re_BufSz + 1 ! Ca1 - Re_BufSz = Re_BufSz + 1 ! CaMG1 - Re_BufSz = Re_BufSz + 1 ! Cp1 - Re_BufSz = Re_BufSz + 1 ! CpMG1 - Re_BufSz = Re_BufSz + 1 ! AxCa1 - Re_BufSz = Re_BufSz + 1 ! AxCaMG1 - Re_BufSz = Re_BufSz + 1 ! AxCp1 - Re_BufSz = Re_BufSz + 1 ! AxCpMG1 - Re_BufSz = Re_BufSz + 1 ! Cd2 - Re_BufSz = Re_BufSz + 1 ! CdMG2 - Re_BufSz = Re_BufSz + 1 ! Ca2 - Re_BufSz = Re_BufSz + 1 ! CaMG2 - Re_BufSz = Re_BufSz + 1 ! Cp2 - Re_BufSz = Re_BufSz + 1 ! CpMG2 - Re_BufSz = Re_BufSz + 1 ! AxCa2 - Re_BufSz = Re_BufSz + 1 ! AxCaMG2 - Re_BufSz = Re_BufSz + 1 ! AxCp2 - Re_BufSz = Re_BufSz + 1 ! AxCpMG2 - Re_BufSz = Re_BufSz + 1 ! InpMbrDist1 - Re_BufSz = Re_BufSz + 1 ! InpMbrDist2 - Re_BufSz = Re_BufSz + 1 ! InpMbrLen - Int_BufSz = Int_BufSz + 1 ! InpMbrIndx - Re_BufSz = Re_BufSz + SIZE(InData%R_LToG) ! R_LToG - Int_BufSz = Int_BufSz + 1 ! NumSplits - Re_BufSz = Re_BufSz + SIZE(InData%Splits) ! Splits - Re_BufSz = Re_BufSz + 1 ! MGvolume - Re_BufSz = Re_BufSz + 1 ! MDivSize - Int_BufSz = Int_BufSz + 1 ! MCoefMod - Int_BufSz = Int_BufSz + 1 ! MmbrCoefIDIndx - Int_BufSz = Int_BufSz + 1 ! MmbrFilledIDIndx - Re_BufSz = Re_BufSz + 1 ! FillFSLoc - Re_BufSz = Re_BufSz + 1 ! FillDens - Re_BufSz = Re_BufSz + SIZE(InData%F_Bouy) ! F_Bouy - Re_BufSz = Re_BufSz + SIZE(InData%F_DP) ! F_DP - Int_BufSz = Int_BufSz + 1 ! PropPot - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF +IF (ALLOCATED(SrcMemberTypeData%NodeIndx)) THEN + i1_l = LBOUND(SrcMemberTypeData%NodeIndx,1) + i1_u = UBOUND(SrcMemberTypeData%NodeIndx,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%NodeIndx)) THEN + ALLOCATE(DstMemberTypeData%NodeIndx(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%NodeIndx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + DstMemberTypeData%NodeIndx = SrcMemberTypeData%NodeIndx +ENDIF + DstMemberTypeData%MemberID = SrcMemberTypeData%MemberID + DstMemberTypeData%NElements = SrcMemberTypeData%NElements + DstMemberTypeData%RefLength = SrcMemberTypeData%RefLength + DstMemberTypeData%cosPhi_ref = SrcMemberTypeData%cosPhi_ref + DstMemberTypeData%dl = SrcMemberTypeData%dl + DstMemberTypeData%k = SrcMemberTypeData%k + DstMemberTypeData%kkt = SrcMemberTypeData%kkt + DstMemberTypeData%Ak = SrcMemberTypeData%Ak +IF (ALLOCATED(SrcMemberTypeData%R)) THEN + i1_l = LBOUND(SrcMemberTypeData%R,1) + i1_u = UBOUND(SrcMemberTypeData%R,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%R)) THEN + ALLOCATE(DstMemberTypeData%R(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%R.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + DstMemberTypeData%R = SrcMemberTypeData%R +ENDIF +IF (ALLOCATED(SrcMemberTypeData%RMG)) THEN + i1_l = LBOUND(SrcMemberTypeData%RMG,1) + i1_u = UBOUND(SrcMemberTypeData%RMG,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%RMG)) THEN + ALLOCATE(DstMemberTypeData%RMG(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%RMG.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IntKiBuf(Int_Xferred) = InData%Node1Indx - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%Node2Indx - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%R1 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%t1 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%R2 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%t2 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Cd1 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%CdMG1 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Ca1 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%CaMG1 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Cp1 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%CpMG1 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%AxCa1 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%AxCaMG1 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%AxCp1 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%AxCpMG1 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Cd2 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%CdMG2 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Ca2 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%CaMG2 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Cp2 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%CpMG2 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%AxCa2 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%AxCaMG2 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%AxCp2 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%AxCpMG2 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InpMbrDist1 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InpMbrDist2 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InpMbrLen - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%InpMbrIndx - Int_Xferred = Int_Xferred + 1 - DO i2 = LBOUND(InData%R_LToG,2), UBOUND(InData%R_LToG,2) - DO i1 = LBOUND(InData%R_LToG,1), UBOUND(InData%R_LToG,1) - ReKiBuf(Re_Xferred) = InData%R_LToG(i1,i2) - Re_Xferred = Re_Xferred + 1 + DstMemberTypeData%RMG = SrcMemberTypeData%RMG +ENDIF +IF (ALLOCATED(SrcMemberTypeData%Rin)) THEN + i1_l = LBOUND(SrcMemberTypeData%Rin,1) + i1_u = UBOUND(SrcMemberTypeData%Rin,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%Rin)) THEN + ALLOCATE(DstMemberTypeData%Rin(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%Rin.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%Rin = SrcMemberTypeData%Rin +ENDIF +IF (ALLOCATED(SrcMemberTypeData%tMG)) THEN + i1_l = LBOUND(SrcMemberTypeData%tMG,1) + i1_u = UBOUND(SrcMemberTypeData%tMG,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%tMG)) THEN + ALLOCATE(DstMemberTypeData%tMG(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%tMG.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%tMG = SrcMemberTypeData%tMG +ENDIF +IF (ALLOCATED(SrcMemberTypeData%MGdensity)) THEN + i1_l = LBOUND(SrcMemberTypeData%MGdensity,1) + i1_u = UBOUND(SrcMemberTypeData%MGdensity,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%MGdensity)) THEN + ALLOCATE(DstMemberTypeData%MGdensity(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%MGdensity.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%MGdensity = SrcMemberTypeData%MGdensity +ENDIF +IF (ALLOCATED(SrcMemberTypeData%dRdl_mg)) THEN + i1_l = LBOUND(SrcMemberTypeData%dRdl_mg,1) + i1_u = UBOUND(SrcMemberTypeData%dRdl_mg,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%dRdl_mg)) THEN + ALLOCATE(DstMemberTypeData%dRdl_mg(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%dRdl_mg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%dRdl_mg = SrcMemberTypeData%dRdl_mg +ENDIF +IF (ALLOCATED(SrcMemberTypeData%dRdl_in)) THEN + i1_l = LBOUND(SrcMemberTypeData%dRdl_in,1) + i1_u = UBOUND(SrcMemberTypeData%dRdl_in,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%dRdl_in)) THEN + ALLOCATE(DstMemberTypeData%dRdl_in(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%dRdl_in.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%dRdl_in = SrcMemberTypeData%dRdl_in +ENDIF + DstMemberTypeData%Vinner = SrcMemberTypeData%Vinner + DstMemberTypeData%Vouter = SrcMemberTypeData%Vouter + DstMemberTypeData%Vballast = SrcMemberTypeData%Vballast + DstMemberTypeData%Vsubmerged = SrcMemberTypeData%Vsubmerged + DstMemberTypeData%l_fill = SrcMemberTypeData%l_fill + DstMemberTypeData%h_fill = SrcMemberTypeData%h_fill + DstMemberTypeData%z_overfill = SrcMemberTypeData%z_overfill + DstMemberTypeData%h_floor = SrcMemberTypeData%h_floor + DstMemberTypeData%i_floor = SrcMemberTypeData%i_floor + DstMemberTypeData%doEndBuoyancy = SrcMemberTypeData%doEndBuoyancy + DstMemberTypeData%memfloodstatus = SrcMemberTypeData%memfloodstatus +IF (ALLOCATED(SrcMemberTypeData%floodstatus)) THEN + i1_l = LBOUND(SrcMemberTypeData%floodstatus,1) + i1_u = UBOUND(SrcMemberTypeData%floodstatus,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%floodstatus)) THEN + ALLOCATE(DstMemberTypeData%floodstatus(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%floodstatus.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%floodstatus = SrcMemberTypeData%floodstatus +ENDIF +IF (ALLOCATED(SrcMemberTypeData%alpha)) THEN + i1_l = LBOUND(SrcMemberTypeData%alpha,1) + i1_u = UBOUND(SrcMemberTypeData%alpha,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%alpha)) THEN + ALLOCATE(DstMemberTypeData%alpha(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%alpha.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%alpha = SrcMemberTypeData%alpha +ENDIF +IF (ALLOCATED(SrcMemberTypeData%alpha_fb)) THEN + i1_l = LBOUND(SrcMemberTypeData%alpha_fb,1) + i1_u = UBOUND(SrcMemberTypeData%alpha_fb,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%alpha_fb)) THEN + ALLOCATE(DstMemberTypeData%alpha_fb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%alpha_fb.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%alpha_fb = SrcMemberTypeData%alpha_fb +ENDIF +IF (ALLOCATED(SrcMemberTypeData%alpha_fb_star)) THEN + i1_l = LBOUND(SrcMemberTypeData%alpha_fb_star,1) + i1_u = UBOUND(SrcMemberTypeData%alpha_fb_star,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%alpha_fb_star)) THEN + ALLOCATE(DstMemberTypeData%alpha_fb_star(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%alpha_fb_star.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%alpha_fb_star = SrcMemberTypeData%alpha_fb_star +ENDIF +IF (ALLOCATED(SrcMemberTypeData%Cd)) THEN + i1_l = LBOUND(SrcMemberTypeData%Cd,1) + i1_u = UBOUND(SrcMemberTypeData%Cd,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%Cd)) THEN + ALLOCATE(DstMemberTypeData%Cd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%Cd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%Cd = SrcMemberTypeData%Cd +ENDIF +IF (ALLOCATED(SrcMemberTypeData%Ca)) THEN + i1_l = LBOUND(SrcMemberTypeData%Ca,1) + i1_u = UBOUND(SrcMemberTypeData%Ca,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%Ca)) THEN + ALLOCATE(DstMemberTypeData%Ca(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%Ca.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%Ca = SrcMemberTypeData%Ca +ENDIF +IF (ALLOCATED(SrcMemberTypeData%Cp)) THEN + i1_l = LBOUND(SrcMemberTypeData%Cp,1) + i1_u = UBOUND(SrcMemberTypeData%Cp,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%Cp)) THEN + ALLOCATE(DstMemberTypeData%Cp(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%Cp.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%Cp = SrcMemberTypeData%Cp +ENDIF +IF (ALLOCATED(SrcMemberTypeData%AxCd)) THEN + i1_l = LBOUND(SrcMemberTypeData%AxCd,1) + i1_u = UBOUND(SrcMemberTypeData%AxCd,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%AxCd)) THEN + ALLOCATE(DstMemberTypeData%AxCd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%AxCd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%AxCd = SrcMemberTypeData%AxCd +ENDIF +IF (ALLOCATED(SrcMemberTypeData%AxCa)) THEN + i1_l = LBOUND(SrcMemberTypeData%AxCa,1) + i1_u = UBOUND(SrcMemberTypeData%AxCa,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%AxCa)) THEN + ALLOCATE(DstMemberTypeData%AxCa(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%AxCa.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%AxCa = SrcMemberTypeData%AxCa +ENDIF +IF (ALLOCATED(SrcMemberTypeData%AxCp)) THEN + i1_l = LBOUND(SrcMemberTypeData%AxCp,1) + i1_u = UBOUND(SrcMemberTypeData%AxCp,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%AxCp)) THEN + ALLOCATE(DstMemberTypeData%AxCp(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%AxCp.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%AxCp = SrcMemberTypeData%AxCp +ENDIF +IF (ALLOCATED(SrcMemberTypeData%m_fb_l)) THEN + i1_l = LBOUND(SrcMemberTypeData%m_fb_l,1) + i1_u = UBOUND(SrcMemberTypeData%m_fb_l,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%m_fb_l)) THEN + ALLOCATE(DstMemberTypeData%m_fb_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%m_fb_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%m_fb_l = SrcMemberTypeData%m_fb_l +ENDIF +IF (ALLOCATED(SrcMemberTypeData%m_fb_u)) THEN + i1_l = LBOUND(SrcMemberTypeData%m_fb_u,1) + i1_u = UBOUND(SrcMemberTypeData%m_fb_u,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%m_fb_u)) THEN + ALLOCATE(DstMemberTypeData%m_fb_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%m_fb_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%m_fb_u = SrcMemberTypeData%m_fb_u +ENDIF +IF (ALLOCATED(SrcMemberTypeData%h_cfb_l)) THEN + i1_l = LBOUND(SrcMemberTypeData%h_cfb_l,1) + i1_u = UBOUND(SrcMemberTypeData%h_cfb_l,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%h_cfb_l)) THEN + ALLOCATE(DstMemberTypeData%h_cfb_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%h_cfb_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%h_cfb_l = SrcMemberTypeData%h_cfb_l +ENDIF +IF (ALLOCATED(SrcMemberTypeData%h_cfb_u)) THEN + i1_l = LBOUND(SrcMemberTypeData%h_cfb_u,1) + i1_u = UBOUND(SrcMemberTypeData%h_cfb_u,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%h_cfb_u)) THEN + ALLOCATE(DstMemberTypeData%h_cfb_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%h_cfb_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%h_cfb_u = SrcMemberTypeData%h_cfb_u +ENDIF +IF (ALLOCATED(SrcMemberTypeData%I_lfb_l)) THEN + i1_l = LBOUND(SrcMemberTypeData%I_lfb_l,1) + i1_u = UBOUND(SrcMemberTypeData%I_lfb_l,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%I_lfb_l)) THEN + ALLOCATE(DstMemberTypeData%I_lfb_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%I_lfb_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%I_lfb_l = SrcMemberTypeData%I_lfb_l +ENDIF +IF (ALLOCATED(SrcMemberTypeData%I_lfb_u)) THEN + i1_l = LBOUND(SrcMemberTypeData%I_lfb_u,1) + i1_u = UBOUND(SrcMemberTypeData%I_lfb_u,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%I_lfb_u)) THEN + ALLOCATE(DstMemberTypeData%I_lfb_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%I_lfb_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%I_lfb_u = SrcMemberTypeData%I_lfb_u +ENDIF +IF (ALLOCATED(SrcMemberTypeData%I_rfb_l)) THEN + i1_l = LBOUND(SrcMemberTypeData%I_rfb_l,1) + i1_u = UBOUND(SrcMemberTypeData%I_rfb_l,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%I_rfb_l)) THEN + ALLOCATE(DstMemberTypeData%I_rfb_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%I_rfb_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%I_rfb_l = SrcMemberTypeData%I_rfb_l +ENDIF +IF (ALLOCATED(SrcMemberTypeData%I_rfb_u)) THEN + i1_l = LBOUND(SrcMemberTypeData%I_rfb_u,1) + i1_u = UBOUND(SrcMemberTypeData%I_rfb_u,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%I_rfb_u)) THEN + ALLOCATE(DstMemberTypeData%I_rfb_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%I_rfb_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%I_rfb_u = SrcMemberTypeData%I_rfb_u +ENDIF +IF (ALLOCATED(SrcMemberTypeData%m_mg_l)) THEN + i1_l = LBOUND(SrcMemberTypeData%m_mg_l,1) + i1_u = UBOUND(SrcMemberTypeData%m_mg_l,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%m_mg_l)) THEN + ALLOCATE(DstMemberTypeData%m_mg_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%m_mg_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%m_mg_l = SrcMemberTypeData%m_mg_l +ENDIF +IF (ALLOCATED(SrcMemberTypeData%m_mg_u)) THEN + i1_l = LBOUND(SrcMemberTypeData%m_mg_u,1) + i1_u = UBOUND(SrcMemberTypeData%m_mg_u,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%m_mg_u)) THEN + ALLOCATE(DstMemberTypeData%m_mg_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%m_mg_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%m_mg_u = SrcMemberTypeData%m_mg_u +ENDIF +IF (ALLOCATED(SrcMemberTypeData%h_cmg_l)) THEN + i1_l = LBOUND(SrcMemberTypeData%h_cmg_l,1) + i1_u = UBOUND(SrcMemberTypeData%h_cmg_l,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%h_cmg_l)) THEN + ALLOCATE(DstMemberTypeData%h_cmg_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%h_cmg_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%h_cmg_l = SrcMemberTypeData%h_cmg_l +ENDIF +IF (ALLOCATED(SrcMemberTypeData%h_cmg_u)) THEN + i1_l = LBOUND(SrcMemberTypeData%h_cmg_u,1) + i1_u = UBOUND(SrcMemberTypeData%h_cmg_u,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%h_cmg_u)) THEN + ALLOCATE(DstMemberTypeData%h_cmg_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%h_cmg_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%h_cmg_u = SrcMemberTypeData%h_cmg_u +ENDIF +IF (ALLOCATED(SrcMemberTypeData%I_lmg_l)) THEN + i1_l = LBOUND(SrcMemberTypeData%I_lmg_l,1) + i1_u = UBOUND(SrcMemberTypeData%I_lmg_l,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%I_lmg_l)) THEN + ALLOCATE(DstMemberTypeData%I_lmg_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%I_lmg_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%I_lmg_l = SrcMemberTypeData%I_lmg_l +ENDIF +IF (ALLOCATED(SrcMemberTypeData%I_lmg_u)) THEN + i1_l = LBOUND(SrcMemberTypeData%I_lmg_u,1) + i1_u = UBOUND(SrcMemberTypeData%I_lmg_u,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%I_lmg_u)) THEN + ALLOCATE(DstMemberTypeData%I_lmg_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%I_lmg_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%I_lmg_u = SrcMemberTypeData%I_lmg_u +ENDIF +IF (ALLOCATED(SrcMemberTypeData%I_rmg_l)) THEN + i1_l = LBOUND(SrcMemberTypeData%I_rmg_l,1) + i1_u = UBOUND(SrcMemberTypeData%I_rmg_l,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%I_rmg_l)) THEN + ALLOCATE(DstMemberTypeData%I_rmg_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%I_rmg_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%I_rmg_l = SrcMemberTypeData%I_rmg_l +ENDIF +IF (ALLOCATED(SrcMemberTypeData%I_rmg_u)) THEN + i1_l = LBOUND(SrcMemberTypeData%I_rmg_u,1) + i1_u = UBOUND(SrcMemberTypeData%I_rmg_u,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%I_rmg_u)) THEN + ALLOCATE(DstMemberTypeData%I_rmg_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%I_rmg_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%I_rmg_u = SrcMemberTypeData%I_rmg_u +ENDIF +IF (ALLOCATED(SrcMemberTypeData%Cfl_fb)) THEN + i1_l = LBOUND(SrcMemberTypeData%Cfl_fb,1) + i1_u = UBOUND(SrcMemberTypeData%Cfl_fb,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%Cfl_fb)) THEN + ALLOCATE(DstMemberTypeData%Cfl_fb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%Cfl_fb.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%Cfl_fb = SrcMemberTypeData%Cfl_fb +ENDIF +IF (ALLOCATED(SrcMemberTypeData%Cfr_fb)) THEN + i1_l = LBOUND(SrcMemberTypeData%Cfr_fb,1) + i1_u = UBOUND(SrcMemberTypeData%Cfr_fb,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%Cfr_fb)) THEN + ALLOCATE(DstMemberTypeData%Cfr_fb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%Cfr_fb.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%Cfr_fb = SrcMemberTypeData%Cfr_fb +ENDIF +IF (ALLOCATED(SrcMemberTypeData%CM0_fb)) THEN + i1_l = LBOUND(SrcMemberTypeData%CM0_fb,1) + i1_u = UBOUND(SrcMemberTypeData%CM0_fb,1) + IF (.NOT. ALLOCATED(DstMemberTypeData%CM0_fb)) THEN + ALLOCATE(DstMemberTypeData%CM0_fb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberTypeData%CM0_fb.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberTypeData%CM0_fb = SrcMemberTypeData%CM0_fb +ENDIF + DstMemberTypeData%MGvolume = SrcMemberTypeData%MGvolume + DstMemberTypeData%MDivSize = SrcMemberTypeData%MDivSize + DstMemberTypeData%MCoefMod = SrcMemberTypeData%MCoefMod + DstMemberTypeData%MmbrCoefIDIndx = SrcMemberTypeData%MmbrCoefIDIndx + DstMemberTypeData%MmbrFilledIDIndx = SrcMemberTypeData%MmbrFilledIDIndx + DstMemberTypeData%FillFSLoc = SrcMemberTypeData%FillFSLoc + DstMemberTypeData%FillDens = SrcMemberTypeData%FillDens + DstMemberTypeData%PropPot = SrcMemberTypeData%PropPot + DstMemberTypeData%Flipped = SrcMemberTypeData%Flipped + END SUBROUTINE Morison_CopyMemberType + + SUBROUTINE Morison_DestroyMemberType( MemberTypeData, ErrStat, ErrMsg ) + TYPE(Morison_MemberType), INTENT(INOUT) :: MemberTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMemberType' + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(MemberTypeData%NodeIndx)) THEN + DEALLOCATE(MemberTypeData%NodeIndx) +ENDIF +IF (ALLOCATED(MemberTypeData%R)) THEN + DEALLOCATE(MemberTypeData%R) +ENDIF +IF (ALLOCATED(MemberTypeData%RMG)) THEN + DEALLOCATE(MemberTypeData%RMG) +ENDIF +IF (ALLOCATED(MemberTypeData%Rin)) THEN + DEALLOCATE(MemberTypeData%Rin) +ENDIF +IF (ALLOCATED(MemberTypeData%tMG)) THEN + DEALLOCATE(MemberTypeData%tMG) +ENDIF +IF (ALLOCATED(MemberTypeData%MGdensity)) THEN + DEALLOCATE(MemberTypeData%MGdensity) +ENDIF +IF (ALLOCATED(MemberTypeData%dRdl_mg)) THEN + DEALLOCATE(MemberTypeData%dRdl_mg) +ENDIF +IF (ALLOCATED(MemberTypeData%dRdl_in)) THEN + DEALLOCATE(MemberTypeData%dRdl_in) +ENDIF +IF (ALLOCATED(MemberTypeData%floodstatus)) THEN + DEALLOCATE(MemberTypeData%floodstatus) +ENDIF +IF (ALLOCATED(MemberTypeData%alpha)) THEN + DEALLOCATE(MemberTypeData%alpha) +ENDIF +IF (ALLOCATED(MemberTypeData%alpha_fb)) THEN + DEALLOCATE(MemberTypeData%alpha_fb) +ENDIF +IF (ALLOCATED(MemberTypeData%alpha_fb_star)) THEN + DEALLOCATE(MemberTypeData%alpha_fb_star) +ENDIF +IF (ALLOCATED(MemberTypeData%Cd)) THEN + DEALLOCATE(MemberTypeData%Cd) +ENDIF +IF (ALLOCATED(MemberTypeData%Ca)) THEN + DEALLOCATE(MemberTypeData%Ca) +ENDIF +IF (ALLOCATED(MemberTypeData%Cp)) THEN + DEALLOCATE(MemberTypeData%Cp) +ENDIF +IF (ALLOCATED(MemberTypeData%AxCd)) THEN + DEALLOCATE(MemberTypeData%AxCd) +ENDIF +IF (ALLOCATED(MemberTypeData%AxCa)) THEN + DEALLOCATE(MemberTypeData%AxCa) +ENDIF +IF (ALLOCATED(MemberTypeData%AxCp)) THEN + DEALLOCATE(MemberTypeData%AxCp) +ENDIF +IF (ALLOCATED(MemberTypeData%m_fb_l)) THEN + DEALLOCATE(MemberTypeData%m_fb_l) +ENDIF +IF (ALLOCATED(MemberTypeData%m_fb_u)) THEN + DEALLOCATE(MemberTypeData%m_fb_u) +ENDIF +IF (ALLOCATED(MemberTypeData%h_cfb_l)) THEN + DEALLOCATE(MemberTypeData%h_cfb_l) +ENDIF +IF (ALLOCATED(MemberTypeData%h_cfb_u)) THEN + DEALLOCATE(MemberTypeData%h_cfb_u) +ENDIF +IF (ALLOCATED(MemberTypeData%I_lfb_l)) THEN + DEALLOCATE(MemberTypeData%I_lfb_l) +ENDIF +IF (ALLOCATED(MemberTypeData%I_lfb_u)) THEN + DEALLOCATE(MemberTypeData%I_lfb_u) +ENDIF +IF (ALLOCATED(MemberTypeData%I_rfb_l)) THEN + DEALLOCATE(MemberTypeData%I_rfb_l) +ENDIF +IF (ALLOCATED(MemberTypeData%I_rfb_u)) THEN + DEALLOCATE(MemberTypeData%I_rfb_u) +ENDIF +IF (ALLOCATED(MemberTypeData%m_mg_l)) THEN + DEALLOCATE(MemberTypeData%m_mg_l) +ENDIF +IF (ALLOCATED(MemberTypeData%m_mg_u)) THEN + DEALLOCATE(MemberTypeData%m_mg_u) +ENDIF +IF (ALLOCATED(MemberTypeData%h_cmg_l)) THEN + DEALLOCATE(MemberTypeData%h_cmg_l) +ENDIF +IF (ALLOCATED(MemberTypeData%h_cmg_u)) THEN + DEALLOCATE(MemberTypeData%h_cmg_u) +ENDIF +IF (ALLOCATED(MemberTypeData%I_lmg_l)) THEN + DEALLOCATE(MemberTypeData%I_lmg_l) +ENDIF +IF (ALLOCATED(MemberTypeData%I_lmg_u)) THEN + DEALLOCATE(MemberTypeData%I_lmg_u) +ENDIF +IF (ALLOCATED(MemberTypeData%I_rmg_l)) THEN + DEALLOCATE(MemberTypeData%I_rmg_l) +ENDIF +IF (ALLOCATED(MemberTypeData%I_rmg_u)) THEN + DEALLOCATE(MemberTypeData%I_rmg_u) +ENDIF +IF (ALLOCATED(MemberTypeData%Cfl_fb)) THEN + DEALLOCATE(MemberTypeData%Cfl_fb) +ENDIF +IF (ALLOCATED(MemberTypeData%Cfr_fb)) THEN + DEALLOCATE(MemberTypeData%Cfr_fb) +ENDIF +IF (ALLOCATED(MemberTypeData%CM0_fb)) THEN + DEALLOCATE(MemberTypeData%CM0_fb) +ENDIF + END SUBROUTINE Morison_DestroyMemberType + + SUBROUTINE Morison_PackMemberType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Morison_MemberType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_PackMemberType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! NodeIndx allocated yes/no + IF ( ALLOCATED(InData%NodeIndx) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! NodeIndx upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%NodeIndx) ! NodeIndx + END IF + Int_BufSz = Int_BufSz + 1 ! MemberID + Int_BufSz = Int_BufSz + 1 ! NElements + Re_BufSz = Re_BufSz + 1 ! RefLength + Re_BufSz = Re_BufSz + 1 ! cosPhi_ref + Re_BufSz = Re_BufSz + 1 ! dl + Re_BufSz = Re_BufSz + SIZE(InData%k) ! k + Re_BufSz = Re_BufSz + SIZE(InData%kkt) ! kkt + Re_BufSz = Re_BufSz + SIZE(InData%Ak) ! Ak + Int_BufSz = Int_BufSz + 1 ! R allocated yes/no + IF ( ALLOCATED(InData%R) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! R upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%R) ! R + END IF + Int_BufSz = Int_BufSz + 1 ! RMG allocated yes/no + IF ( ALLOCATED(InData%RMG) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! RMG upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%RMG) ! RMG + END IF + Int_BufSz = Int_BufSz + 1 ! Rin allocated yes/no + IF ( ALLOCATED(InData%Rin) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Rin upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Rin) ! Rin + END IF + Int_BufSz = Int_BufSz + 1 ! tMG allocated yes/no + IF ( ALLOCATED(InData%tMG) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! tMG upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%tMG) ! tMG + END IF + Int_BufSz = Int_BufSz + 1 ! MGdensity allocated yes/no + IF ( ALLOCATED(InData%MGdensity) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MGdensity upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%MGdensity) ! MGdensity + END IF + Int_BufSz = Int_BufSz + 1 ! dRdl_mg allocated yes/no + IF ( ALLOCATED(InData%dRdl_mg) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! dRdl_mg upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%dRdl_mg) ! dRdl_mg + END IF + Int_BufSz = Int_BufSz + 1 ! dRdl_in allocated yes/no + IF ( ALLOCATED(InData%dRdl_in) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! dRdl_in upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%dRdl_in) ! dRdl_in + END IF + Re_BufSz = Re_BufSz + 1 ! Vinner + Re_BufSz = Re_BufSz + 1 ! Vouter + Re_BufSz = Re_BufSz + 1 ! Vballast + Re_BufSz = Re_BufSz + 1 ! Vsubmerged + Re_BufSz = Re_BufSz + 1 ! l_fill + Re_BufSz = Re_BufSz + 1 ! h_fill + Re_BufSz = Re_BufSz + 1 ! z_overfill + Re_BufSz = Re_BufSz + 1 ! h_floor + Int_BufSz = Int_BufSz + 1 ! i_floor + Int_BufSz = Int_BufSz + 1 ! doEndBuoyancy + Int_BufSz = Int_BufSz + 1 ! memfloodstatus + Int_BufSz = Int_BufSz + 1 ! floodstatus allocated yes/no + IF ( ALLOCATED(InData%floodstatus) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! floodstatus upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%floodstatus) ! floodstatus + END IF + Int_BufSz = Int_BufSz + 1 ! alpha allocated yes/no + IF ( ALLOCATED(InData%alpha) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! alpha upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%alpha) ! alpha + END IF + Int_BufSz = Int_BufSz + 1 ! alpha_fb allocated yes/no + IF ( ALLOCATED(InData%alpha_fb) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! alpha_fb upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%alpha_fb) ! alpha_fb + END IF + Int_BufSz = Int_BufSz + 1 ! alpha_fb_star allocated yes/no + IF ( ALLOCATED(InData%alpha_fb_star) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! alpha_fb_star upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%alpha_fb_star) ! alpha_fb_star + END IF + Int_BufSz = Int_BufSz + 1 ! Cd allocated yes/no + IF ( ALLOCATED(InData%Cd) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Cd upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Cd) ! Cd + END IF + Int_BufSz = Int_BufSz + 1 ! Ca allocated yes/no + IF ( ALLOCATED(InData%Ca) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Ca upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Ca) ! Ca + END IF + Int_BufSz = Int_BufSz + 1 ! Cp allocated yes/no + IF ( ALLOCATED(InData%Cp) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Cp upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Cp) ! Cp + END IF + Int_BufSz = Int_BufSz + 1 ! AxCd allocated yes/no + IF ( ALLOCATED(InData%AxCd) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AxCd upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AxCd) ! AxCd + END IF + Int_BufSz = Int_BufSz + 1 ! AxCa allocated yes/no + IF ( ALLOCATED(InData%AxCa) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AxCa upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AxCa) ! AxCa + END IF + Int_BufSz = Int_BufSz + 1 ! AxCp allocated yes/no + IF ( ALLOCATED(InData%AxCp) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AxCp upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AxCp) ! AxCp + END IF + Int_BufSz = Int_BufSz + 1 ! m_fb_l allocated yes/no + IF ( ALLOCATED(InData%m_fb_l) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! m_fb_l upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%m_fb_l) ! m_fb_l + END IF + Int_BufSz = Int_BufSz + 1 ! m_fb_u allocated yes/no + IF ( ALLOCATED(InData%m_fb_u) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! m_fb_u upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%m_fb_u) ! m_fb_u + END IF + Int_BufSz = Int_BufSz + 1 ! h_cfb_l allocated yes/no + IF ( ALLOCATED(InData%h_cfb_l) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! h_cfb_l upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%h_cfb_l) ! h_cfb_l + END IF + Int_BufSz = Int_BufSz + 1 ! h_cfb_u allocated yes/no + IF ( ALLOCATED(InData%h_cfb_u) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! h_cfb_u upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%h_cfb_u) ! h_cfb_u + END IF + Int_BufSz = Int_BufSz + 1 ! I_lfb_l allocated yes/no + IF ( ALLOCATED(InData%I_lfb_l) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! I_lfb_l upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%I_lfb_l) ! I_lfb_l + END IF + Int_BufSz = Int_BufSz + 1 ! I_lfb_u allocated yes/no + IF ( ALLOCATED(InData%I_lfb_u) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! I_lfb_u upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%I_lfb_u) ! I_lfb_u + END IF + Int_BufSz = Int_BufSz + 1 ! I_rfb_l allocated yes/no + IF ( ALLOCATED(InData%I_rfb_l) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! I_rfb_l upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%I_rfb_l) ! I_rfb_l + END IF + Int_BufSz = Int_BufSz + 1 ! I_rfb_u allocated yes/no + IF ( ALLOCATED(InData%I_rfb_u) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! I_rfb_u upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%I_rfb_u) ! I_rfb_u + END IF + Int_BufSz = Int_BufSz + 1 ! m_mg_l allocated yes/no + IF ( ALLOCATED(InData%m_mg_l) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! m_mg_l upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%m_mg_l) ! m_mg_l + END IF + Int_BufSz = Int_BufSz + 1 ! m_mg_u allocated yes/no + IF ( ALLOCATED(InData%m_mg_u) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! m_mg_u upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%m_mg_u) ! m_mg_u + END IF + Int_BufSz = Int_BufSz + 1 ! h_cmg_l allocated yes/no + IF ( ALLOCATED(InData%h_cmg_l) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! h_cmg_l upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%h_cmg_l) ! h_cmg_l + END IF + Int_BufSz = Int_BufSz + 1 ! h_cmg_u allocated yes/no + IF ( ALLOCATED(InData%h_cmg_u) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! h_cmg_u upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%h_cmg_u) ! h_cmg_u + END IF + Int_BufSz = Int_BufSz + 1 ! I_lmg_l allocated yes/no + IF ( ALLOCATED(InData%I_lmg_l) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! I_lmg_l upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%I_lmg_l) ! I_lmg_l + END IF + Int_BufSz = Int_BufSz + 1 ! I_lmg_u allocated yes/no + IF ( ALLOCATED(InData%I_lmg_u) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! I_lmg_u upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%I_lmg_u) ! I_lmg_u + END IF + Int_BufSz = Int_BufSz + 1 ! I_rmg_l allocated yes/no + IF ( ALLOCATED(InData%I_rmg_l) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! I_rmg_l upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%I_rmg_l) ! I_rmg_l + END IF + Int_BufSz = Int_BufSz + 1 ! I_rmg_u allocated yes/no + IF ( ALLOCATED(InData%I_rmg_u) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! I_rmg_u upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%I_rmg_u) ! I_rmg_u + END IF + Int_BufSz = Int_BufSz + 1 ! Cfl_fb allocated yes/no + IF ( ALLOCATED(InData%Cfl_fb) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Cfl_fb upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Cfl_fb) ! Cfl_fb + END IF + Int_BufSz = Int_BufSz + 1 ! Cfr_fb allocated yes/no + IF ( ALLOCATED(InData%Cfr_fb) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Cfr_fb upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Cfr_fb) ! Cfr_fb + END IF + Int_BufSz = Int_BufSz + 1 ! CM0_fb allocated yes/no + IF ( ALLOCATED(InData%CM0_fb) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! CM0_fb upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%CM0_fb) ! CM0_fb + END IF + Re_BufSz = Re_BufSz + 1 ! MGvolume + Re_BufSz = Re_BufSz + 1 ! MDivSize + Int_BufSz = Int_BufSz + 1 ! MCoefMod + Int_BufSz = Int_BufSz + 1 ! MmbrCoefIDIndx + Int_BufSz = Int_BufSz + 1 ! MmbrFilledIDIndx + Re_BufSz = Re_BufSz + 1 ! FillFSLoc + Re_BufSz = Re_BufSz + 1 ! FillDens + Int_BufSz = Int_BufSz + 1 ! PropPot + Int_BufSz = Int_BufSz + 1 ! Flipped + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IF ( .NOT. ALLOCATED(InData%NodeIndx) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%NodeIndx,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NodeIndx,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%NodeIndx,1), UBOUND(InData%NodeIndx,1) + IntKiBuf(Int_Xferred) = InData%NodeIndx(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IntKiBuf(Int_Xferred) = InData%MemberID + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NElements + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefLength + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%cosPhi_ref + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%dl + Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%k,1), UBOUND(InData%k,1) + ReKiBuf(Re_Xferred) = InData%k(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i2 = LBOUND(InData%kkt,2), UBOUND(InData%kkt,2) + DO i1 = LBOUND(InData%kkt,1), UBOUND(InData%kkt,1) + ReKiBuf(Re_Xferred) = InData%kkt(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + DO i2 = LBOUND(InData%Ak,2), UBOUND(InData%Ak,2) + DO i1 = LBOUND(InData%Ak,1), UBOUND(InData%Ak,1) + ReKiBuf(Re_Xferred) = InData%Ak(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + IF ( .NOT. ALLOCATED(InData%R) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%R,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%R,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%R,1), UBOUND(InData%R,1) + ReKiBuf(Re_Xferred) = InData%R(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%RMG) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%RMG,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RMG,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%RMG,1), UBOUND(InData%RMG,1) + ReKiBuf(Re_Xferred) = InData%RMG(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Rin) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Rin,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Rin,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Rin,1), UBOUND(InData%Rin,1) + ReKiBuf(Re_Xferred) = InData%Rin(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%tMG) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%tMG,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%tMG,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%tMG,1), UBOUND(InData%tMG,1) + ReKiBuf(Re_Xferred) = InData%tMG(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MGdensity) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MGdensity,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MGdensity,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MGdensity,1), UBOUND(InData%MGdensity,1) + ReKiBuf(Re_Xferred) = InData%MGdensity(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%dRdl_mg) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dRdl_mg,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dRdl_mg,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%dRdl_mg,1), UBOUND(InData%dRdl_mg,1) + ReKiBuf(Re_Xferred) = InData%dRdl_mg(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%dRdl_in) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dRdl_in,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dRdl_in,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%dRdl_in,1), UBOUND(InData%dRdl_in,1) + ReKiBuf(Re_Xferred) = InData%dRdl_in(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + ReKiBuf(Re_Xferred) = InData%Vinner + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Vouter + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Vballast + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Vsubmerged + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%l_fill + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%h_fill + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%z_overfill + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%h_floor + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%i_floor + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%doEndBuoyancy, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%memfloodstatus + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%floodstatus) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%floodstatus,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%floodstatus,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%floodstatus,1), UBOUND(InData%floodstatus,1) + IntKiBuf(Int_Xferred) = InData%floodstatus(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%alpha) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%alpha,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%alpha,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%alpha,1), UBOUND(InData%alpha,1) + ReKiBuf(Re_Xferred) = InData%alpha(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%alpha_fb) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%alpha_fb,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%alpha_fb,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%alpha_fb,1), UBOUND(InData%alpha_fb,1) + ReKiBuf(Re_Xferred) = InData%alpha_fb(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%alpha_fb_star) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%alpha_fb_star,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%alpha_fb_star,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%alpha_fb_star,1), UBOUND(InData%alpha_fb_star,1) + ReKiBuf(Re_Xferred) = InData%alpha_fb_star(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Cd) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Cd,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Cd,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Cd,1), UBOUND(InData%Cd,1) + ReKiBuf(Re_Xferred) = InData%Cd(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Ca) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Ca,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Ca,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Ca,1), UBOUND(InData%Ca,1) + ReKiBuf(Re_Xferred) = InData%Ca(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Cp) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Cp,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Cp,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Cp,1), UBOUND(InData%Cp,1) + ReKiBuf(Re_Xferred) = InData%Cp(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AxCd) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AxCd,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AxCd,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AxCd,1), UBOUND(InData%AxCd,1) + ReKiBuf(Re_Xferred) = InData%AxCd(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AxCa) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AxCa,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AxCa,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AxCa,1), UBOUND(InData%AxCa,1) + ReKiBuf(Re_Xferred) = InData%AxCa(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AxCp) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AxCp,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AxCp,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AxCp,1), UBOUND(InData%AxCp,1) + ReKiBuf(Re_Xferred) = InData%AxCp(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%m_fb_l) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%m_fb_l,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%m_fb_l,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%m_fb_l,1), UBOUND(InData%m_fb_l,1) + ReKiBuf(Re_Xferred) = InData%m_fb_l(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%m_fb_u) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%m_fb_u,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%m_fb_u,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%m_fb_u,1), UBOUND(InData%m_fb_u,1) + ReKiBuf(Re_Xferred) = InData%m_fb_u(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%h_cfb_l) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%h_cfb_l,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%h_cfb_l,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%h_cfb_l,1), UBOUND(InData%h_cfb_l,1) + ReKiBuf(Re_Xferred) = InData%h_cfb_l(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%h_cfb_u) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%h_cfb_u,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%h_cfb_u,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%h_cfb_u,1), UBOUND(InData%h_cfb_u,1) + ReKiBuf(Re_Xferred) = InData%h_cfb_u(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%I_lfb_l) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%I_lfb_l,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%I_lfb_l,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%I_lfb_l,1), UBOUND(InData%I_lfb_l,1) + ReKiBuf(Re_Xferred) = InData%I_lfb_l(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%I_lfb_u) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%I_lfb_u,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%I_lfb_u,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%I_lfb_u,1), UBOUND(InData%I_lfb_u,1) + ReKiBuf(Re_Xferred) = InData%I_lfb_u(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%I_rfb_l) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%I_rfb_l,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%I_rfb_l,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%I_rfb_l,1), UBOUND(InData%I_rfb_l,1) + ReKiBuf(Re_Xferred) = InData%I_rfb_l(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%I_rfb_u) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%I_rfb_u,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%I_rfb_u,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%I_rfb_u,1), UBOUND(InData%I_rfb_u,1) + ReKiBuf(Re_Xferred) = InData%I_rfb_u(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%m_mg_l) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%m_mg_l,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%m_mg_l,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%m_mg_l,1), UBOUND(InData%m_mg_l,1) + ReKiBuf(Re_Xferred) = InData%m_mg_l(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%m_mg_u) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%m_mg_u,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%m_mg_u,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%m_mg_u,1), UBOUND(InData%m_mg_u,1) + ReKiBuf(Re_Xferred) = InData%m_mg_u(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%h_cmg_l) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%h_cmg_l,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%h_cmg_l,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%h_cmg_l,1), UBOUND(InData%h_cmg_l,1) + ReKiBuf(Re_Xferred) = InData%h_cmg_l(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%h_cmg_u) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%h_cmg_u,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%h_cmg_u,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%h_cmg_u,1), UBOUND(InData%h_cmg_u,1) + ReKiBuf(Re_Xferred) = InData%h_cmg_u(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%I_lmg_l) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%I_lmg_l,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%I_lmg_l,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%I_lmg_l,1), UBOUND(InData%I_lmg_l,1) + ReKiBuf(Re_Xferred) = InData%I_lmg_l(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%I_lmg_u) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%I_lmg_u,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%I_lmg_u,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%I_lmg_u,1), UBOUND(InData%I_lmg_u,1) + ReKiBuf(Re_Xferred) = InData%I_lmg_u(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%I_rmg_l) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%I_rmg_l,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%I_rmg_l,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%I_rmg_l,1), UBOUND(InData%I_rmg_l,1) + ReKiBuf(Re_Xferred) = InData%I_rmg_l(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%I_rmg_u) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%I_rmg_u,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%I_rmg_u,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%I_rmg_u,1), UBOUND(InData%I_rmg_u,1) + ReKiBuf(Re_Xferred) = InData%I_rmg_u(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Cfl_fb) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Cfl_fb,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Cfl_fb,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Cfl_fb,1), UBOUND(InData%Cfl_fb,1) + ReKiBuf(Re_Xferred) = InData%Cfl_fb(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Cfr_fb) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Cfr_fb,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Cfr_fb,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Cfr_fb,1), UBOUND(InData%Cfr_fb,1) + ReKiBuf(Re_Xferred) = InData%Cfr_fb(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%CM0_fb) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CM0_fb,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CM0_fb,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%CM0_fb,1), UBOUND(InData%CM0_fb,1) + ReKiBuf(Re_Xferred) = InData%CM0_fb(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + ReKiBuf(Re_Xferred) = InData%MGvolume + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%MDivSize + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%MCoefMod + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%MmbrCoefIDIndx + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%MmbrFilledIDIndx + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%FillFSLoc + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%FillDens + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%PropPot, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%Flipped, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE Morison_PackMemberType + + SUBROUTINE Morison_UnPackMemberType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Morison_MemberType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_UnPackMemberType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NodeIndx not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%NodeIndx)) DEALLOCATE(OutData%NodeIndx) + ALLOCATE(OutData%NodeIndx(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%NodeIndx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%NodeIndx,1), UBOUND(OutData%NodeIndx,1) + OutData%NodeIndx(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + OutData%MemberID = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NElements = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%RefLength = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%cosPhi_ref = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%dl = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%k,1) + i1_u = UBOUND(OutData%k,1) + DO i1 = LBOUND(OutData%k,1), UBOUND(OutData%k,1) + OutData%k(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%kkt,1) + i1_u = UBOUND(OutData%kkt,1) + i2_l = LBOUND(OutData%kkt,2) + i2_u = UBOUND(OutData%kkt,2) + DO i2 = LBOUND(OutData%kkt,2), UBOUND(OutData%kkt,2) + DO i1 = LBOUND(OutData%kkt,1), UBOUND(OutData%kkt,1) + OutData%kkt(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + i1_l = LBOUND(OutData%Ak,1) + i1_u = UBOUND(OutData%Ak,1) + i2_l = LBOUND(OutData%Ak,2) + i2_u = UBOUND(OutData%Ak,2) + DO i2 = LBOUND(OutData%Ak,2), UBOUND(OutData%Ak,2) + DO i1 = LBOUND(OutData%Ak,1), UBOUND(OutData%Ak,1) + OutData%Ak(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! R not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%R)) DEALLOCATE(OutData%R) + ALLOCATE(OutData%R(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%R.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%R,1), UBOUND(OutData%R,1) + OutData%R(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! RMG not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%RMG)) DEALLOCATE(OutData%RMG) + ALLOCATE(OutData%RMG(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%RMG.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%RMG,1), UBOUND(OutData%RMG,1) + OutData%RMG(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Rin not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Rin)) DEALLOCATE(OutData%Rin) + ALLOCATE(OutData%Rin(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Rin.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Rin,1), UBOUND(OutData%Rin,1) + OutData%Rin(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! tMG not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%tMG)) DEALLOCATE(OutData%tMG) + ALLOCATE(OutData%tMG(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%tMG.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%tMG,1), UBOUND(OutData%tMG,1) + OutData%tMG(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MGdensity not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MGdensity)) DEALLOCATE(OutData%MGdensity) + ALLOCATE(OutData%MGdensity(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MGdensity.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MGdensity,1), UBOUND(OutData%MGdensity,1) + OutData%MGdensity(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! dRdl_mg not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%dRdl_mg)) DEALLOCATE(OutData%dRdl_mg) + ALLOCATE(OutData%dRdl_mg(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%dRdl_mg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%dRdl_mg,1), UBOUND(OutData%dRdl_mg,1) + OutData%dRdl_mg(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! dRdl_in not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%dRdl_in)) DEALLOCATE(OutData%dRdl_in) + ALLOCATE(OutData%dRdl_in(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%dRdl_in.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%dRdl_in,1), UBOUND(OutData%dRdl_in,1) + OutData%dRdl_in(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + OutData%Vinner = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Vouter = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Vballast = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Vsubmerged = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%l_fill = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%h_fill = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%z_overfill = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%h_floor = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%i_floor = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%doEndBuoyancy = TRANSFER(IntKiBuf(Int_Xferred), OutData%doEndBuoyancy) + Int_Xferred = Int_Xferred + 1 + OutData%memfloodstatus = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! floodstatus not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%floodstatus)) DEALLOCATE(OutData%floodstatus) + ALLOCATE(OutData%floodstatus(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%floodstatus.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%floodstatus,1), UBOUND(OutData%floodstatus,1) + OutData%floodstatus(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! alpha not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%alpha)) DEALLOCATE(OutData%alpha) + ALLOCATE(OutData%alpha(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%alpha.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%alpha,1), UBOUND(OutData%alpha,1) + OutData%alpha(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! alpha_fb not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%alpha_fb)) DEALLOCATE(OutData%alpha_fb) + ALLOCATE(OutData%alpha_fb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%alpha_fb.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%alpha_fb,1), UBOUND(OutData%alpha_fb,1) + OutData%alpha_fb(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! alpha_fb_star not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%alpha_fb_star)) DEALLOCATE(OutData%alpha_fb_star) + ALLOCATE(OutData%alpha_fb_star(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%alpha_fb_star.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%alpha_fb_star,1), UBOUND(OutData%alpha_fb_star,1) + OutData%alpha_fb_star(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Cd not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Cd)) DEALLOCATE(OutData%Cd) + ALLOCATE(OutData%Cd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Cd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Cd,1), UBOUND(OutData%Cd,1) + OutData%Cd(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Ca not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Ca)) DEALLOCATE(OutData%Ca) + ALLOCATE(OutData%Ca(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Ca.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Ca,1), UBOUND(OutData%Ca,1) + OutData%Ca(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Cp not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Cp)) DEALLOCATE(OutData%Cp) + ALLOCATE(OutData%Cp(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Cp.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Cp,1), UBOUND(OutData%Cp,1) + OutData%Cp(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AxCd not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AxCd)) DEALLOCATE(OutData%AxCd) + ALLOCATE(OutData%AxCd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AxCd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AxCd,1), UBOUND(OutData%AxCd,1) + OutData%AxCd(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AxCa not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AxCa)) DEALLOCATE(OutData%AxCa) + ALLOCATE(OutData%AxCa(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AxCa.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AxCa,1), UBOUND(OutData%AxCa,1) + OutData%AxCa(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AxCp not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AxCp)) DEALLOCATE(OutData%AxCp) + ALLOCATE(OutData%AxCp(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AxCp.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AxCp,1), UBOUND(OutData%AxCp,1) + OutData%AxCp(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! m_fb_l not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%m_fb_l)) DEALLOCATE(OutData%m_fb_l) + ALLOCATE(OutData%m_fb_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%m_fb_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%m_fb_l,1), UBOUND(OutData%m_fb_l,1) + OutData%m_fb_l(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! m_fb_u not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%m_fb_u)) DEALLOCATE(OutData%m_fb_u) + ALLOCATE(OutData%m_fb_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%m_fb_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%m_fb_u,1), UBOUND(OutData%m_fb_u,1) + OutData%m_fb_u(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! h_cfb_l not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%h_cfb_l)) DEALLOCATE(OutData%h_cfb_l) + ALLOCATE(OutData%h_cfb_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%h_cfb_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%h_cfb_l,1), UBOUND(OutData%h_cfb_l,1) + OutData%h_cfb_l(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! h_cfb_u not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%h_cfb_u)) DEALLOCATE(OutData%h_cfb_u) + ALLOCATE(OutData%h_cfb_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%h_cfb_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%h_cfb_u,1), UBOUND(OutData%h_cfb_u,1) + OutData%h_cfb_u(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! I_lfb_l not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%I_lfb_l)) DEALLOCATE(OutData%I_lfb_l) + ALLOCATE(OutData%I_lfb_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%I_lfb_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%I_lfb_l,1), UBOUND(OutData%I_lfb_l,1) + OutData%I_lfb_l(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! I_lfb_u not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%I_lfb_u)) DEALLOCATE(OutData%I_lfb_u) + ALLOCATE(OutData%I_lfb_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%I_lfb_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%I_lfb_u,1), UBOUND(OutData%I_lfb_u,1) + OutData%I_lfb_u(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! I_rfb_l not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%I_rfb_l)) DEALLOCATE(OutData%I_rfb_l) + ALLOCATE(OutData%I_rfb_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%I_rfb_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%I_rfb_l,1), UBOUND(OutData%I_rfb_l,1) + OutData%I_rfb_l(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! I_rfb_u not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%I_rfb_u)) DEALLOCATE(OutData%I_rfb_u) + ALLOCATE(OutData%I_rfb_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%I_rfb_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%I_rfb_u,1), UBOUND(OutData%I_rfb_u,1) + OutData%I_rfb_u(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! m_mg_l not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%m_mg_l)) DEALLOCATE(OutData%m_mg_l) + ALLOCATE(OutData%m_mg_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%m_mg_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%m_mg_l,1), UBOUND(OutData%m_mg_l,1) + OutData%m_mg_l(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! m_mg_u not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%m_mg_u)) DEALLOCATE(OutData%m_mg_u) + ALLOCATE(OutData%m_mg_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%m_mg_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%m_mg_u,1), UBOUND(OutData%m_mg_u,1) + OutData%m_mg_u(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! h_cmg_l not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%h_cmg_l)) DEALLOCATE(OutData%h_cmg_l) + ALLOCATE(OutData%h_cmg_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%h_cmg_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%h_cmg_l,1), UBOUND(OutData%h_cmg_l,1) + OutData%h_cmg_l(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! h_cmg_u not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%h_cmg_u)) DEALLOCATE(OutData%h_cmg_u) + ALLOCATE(OutData%h_cmg_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%h_cmg_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%h_cmg_u,1), UBOUND(OutData%h_cmg_u,1) + OutData%h_cmg_u(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! I_lmg_l not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%I_lmg_l)) DEALLOCATE(OutData%I_lmg_l) + ALLOCATE(OutData%I_lmg_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%I_lmg_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%I_lmg_l,1), UBOUND(OutData%I_lmg_l,1) + OutData%I_lmg_l(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! I_lmg_u not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%I_lmg_u)) DEALLOCATE(OutData%I_lmg_u) + ALLOCATE(OutData%I_lmg_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%I_lmg_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%I_lmg_u,1), UBOUND(OutData%I_lmg_u,1) + OutData%I_lmg_u(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! I_rmg_l not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%I_rmg_l)) DEALLOCATE(OutData%I_rmg_l) + ALLOCATE(OutData%I_rmg_l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%I_rmg_l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%I_rmg_l,1), UBOUND(OutData%I_rmg_l,1) + OutData%I_rmg_l(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! I_rmg_u not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%I_rmg_u)) DEALLOCATE(OutData%I_rmg_u) + ALLOCATE(OutData%I_rmg_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%I_rmg_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%I_rmg_u,1), UBOUND(OutData%I_rmg_u,1) + OutData%I_rmg_u(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Cfl_fb not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Cfl_fb)) DEALLOCATE(OutData%Cfl_fb) + ALLOCATE(OutData%Cfl_fb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Cfl_fb.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Cfl_fb,1), UBOUND(OutData%Cfl_fb,1) + OutData%Cfl_fb(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Cfr_fb not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Cfr_fb)) DEALLOCATE(OutData%Cfr_fb) + ALLOCATE(OutData%Cfr_fb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Cfr_fb.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Cfr_fb,1), UBOUND(OutData%Cfr_fb,1) + OutData%Cfr_fb(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CM0_fb not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%CM0_fb)) DEALLOCATE(OutData%CM0_fb) + ALLOCATE(OutData%CM0_fb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CM0_fb.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%CM0_fb,1), UBOUND(OutData%CM0_fb,1) + OutData%CM0_fb(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + OutData%MGvolume = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%MDivSize = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%MCoefMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%MmbrCoefIDIndx = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%MmbrFilledIDIndx = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%FillFSLoc = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%FillDens = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%PropPot = TRANSFER(IntKiBuf(Int_Xferred), OutData%PropPot) + Int_Xferred = Int_Xferred + 1 + OutData%Flipped = TRANSFER(IntKiBuf(Int_Xferred), OutData%Flipped) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE Morison_UnPackMemberType + + SUBROUTINE Morison_CopyMemberLoads( SrcMemberLoadsData, DstMemberLoadsData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Morison_MemberLoads), INTENT(IN) :: SrcMemberLoadsData + TYPE(Morison_MemberLoads), INTENT(INOUT) :: DstMemberLoadsData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_CopyMemberLoads' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcMemberLoadsData%F_D)) THEN + i1_l = LBOUND(SrcMemberLoadsData%F_D,1) + i1_u = UBOUND(SrcMemberLoadsData%F_D,1) + i2_l = LBOUND(SrcMemberLoadsData%F_D,2) + i2_u = UBOUND(SrcMemberLoadsData%F_D,2) + IF (.NOT. ALLOCATED(DstMemberLoadsData%F_D)) THEN + ALLOCATE(DstMemberLoadsData%F_D(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberLoadsData%F_D.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberLoadsData%F_D = SrcMemberLoadsData%F_D +ENDIF +IF (ALLOCATED(SrcMemberLoadsData%F_I)) THEN + i1_l = LBOUND(SrcMemberLoadsData%F_I,1) + i1_u = UBOUND(SrcMemberLoadsData%F_I,1) + i2_l = LBOUND(SrcMemberLoadsData%F_I,2) + i2_u = UBOUND(SrcMemberLoadsData%F_I,2) + IF (.NOT. ALLOCATED(DstMemberLoadsData%F_I)) THEN + ALLOCATE(DstMemberLoadsData%F_I(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberLoadsData%F_I.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberLoadsData%F_I = SrcMemberLoadsData%F_I +ENDIF +IF (ALLOCATED(SrcMemberLoadsData%F_A)) THEN + i1_l = LBOUND(SrcMemberLoadsData%F_A,1) + i1_u = UBOUND(SrcMemberLoadsData%F_A,1) + i2_l = LBOUND(SrcMemberLoadsData%F_A,2) + i2_u = UBOUND(SrcMemberLoadsData%F_A,2) + IF (.NOT. ALLOCATED(DstMemberLoadsData%F_A)) THEN + ALLOCATE(DstMemberLoadsData%F_A(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberLoadsData%F_A.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberLoadsData%F_A = SrcMemberLoadsData%F_A +ENDIF +IF (ALLOCATED(SrcMemberLoadsData%F_B)) THEN + i1_l = LBOUND(SrcMemberLoadsData%F_B,1) + i1_u = UBOUND(SrcMemberLoadsData%F_B,1) + i2_l = LBOUND(SrcMemberLoadsData%F_B,2) + i2_u = UBOUND(SrcMemberLoadsData%F_B,2) + IF (.NOT. ALLOCATED(DstMemberLoadsData%F_B)) THEN + ALLOCATE(DstMemberLoadsData%F_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberLoadsData%F_B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberLoadsData%F_B = SrcMemberLoadsData%F_B +ENDIF +IF (ALLOCATED(SrcMemberLoadsData%F_BF)) THEN + i1_l = LBOUND(SrcMemberLoadsData%F_BF,1) + i1_u = UBOUND(SrcMemberLoadsData%F_BF,1) + i2_l = LBOUND(SrcMemberLoadsData%F_BF,2) + i2_u = UBOUND(SrcMemberLoadsData%F_BF,2) + IF (.NOT. ALLOCATED(DstMemberLoadsData%F_BF)) THEN + ALLOCATE(DstMemberLoadsData%F_BF(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberLoadsData%F_BF.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberLoadsData%F_BF = SrcMemberLoadsData%F_BF +ENDIF +IF (ALLOCATED(SrcMemberLoadsData%F_If)) THEN + i1_l = LBOUND(SrcMemberLoadsData%F_If,1) + i1_u = UBOUND(SrcMemberLoadsData%F_If,1) + i2_l = LBOUND(SrcMemberLoadsData%F_If,2) + i2_u = UBOUND(SrcMemberLoadsData%F_If,2) + IF (.NOT. ALLOCATED(DstMemberLoadsData%F_If)) THEN + ALLOCATE(DstMemberLoadsData%F_If(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberLoadsData%F_If.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberLoadsData%F_If = SrcMemberLoadsData%F_If +ENDIF +IF (ALLOCATED(SrcMemberLoadsData%F_WMG)) THEN + i1_l = LBOUND(SrcMemberLoadsData%F_WMG,1) + i1_u = UBOUND(SrcMemberLoadsData%F_WMG,1) + i2_l = LBOUND(SrcMemberLoadsData%F_WMG,2) + i2_u = UBOUND(SrcMemberLoadsData%F_WMG,2) + IF (.NOT. ALLOCATED(DstMemberLoadsData%F_WMG)) THEN + ALLOCATE(DstMemberLoadsData%F_WMG(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberLoadsData%F_WMG.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberLoadsData%F_WMG = SrcMemberLoadsData%F_WMG +ENDIF +IF (ALLOCATED(SrcMemberLoadsData%F_IMG)) THEN + i1_l = LBOUND(SrcMemberLoadsData%F_IMG,1) + i1_u = UBOUND(SrcMemberLoadsData%F_IMG,1) + i2_l = LBOUND(SrcMemberLoadsData%F_IMG,2) + i2_u = UBOUND(SrcMemberLoadsData%F_IMG,2) + IF (.NOT. ALLOCATED(DstMemberLoadsData%F_IMG)) THEN + ALLOCATE(DstMemberLoadsData%F_IMG(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberLoadsData%F_IMG.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberLoadsData%F_IMG = SrcMemberLoadsData%F_IMG +ENDIF +IF (ALLOCATED(SrcMemberLoadsData%FV)) THEN + i1_l = LBOUND(SrcMemberLoadsData%FV,1) + i1_u = UBOUND(SrcMemberLoadsData%FV,1) + i2_l = LBOUND(SrcMemberLoadsData%FV,2) + i2_u = UBOUND(SrcMemberLoadsData%FV,2) + IF (.NOT. ALLOCATED(DstMemberLoadsData%FV)) THEN + ALLOCATE(DstMemberLoadsData%FV(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberLoadsData%FV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberLoadsData%FV = SrcMemberLoadsData%FV +ENDIF +IF (ALLOCATED(SrcMemberLoadsData%FA)) THEN + i1_l = LBOUND(SrcMemberLoadsData%FA,1) + i1_u = UBOUND(SrcMemberLoadsData%FA,1) + i2_l = LBOUND(SrcMemberLoadsData%FA,2) + i2_u = UBOUND(SrcMemberLoadsData%FA,2) + IF (.NOT. ALLOCATED(DstMemberLoadsData%FA)) THEN + ALLOCATE(DstMemberLoadsData%FA(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberLoadsData%FA.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberLoadsData%FA = SrcMemberLoadsData%FA +ENDIF +IF (ALLOCATED(SrcMemberLoadsData%F_DP)) THEN + i1_l = LBOUND(SrcMemberLoadsData%F_DP,1) + i1_u = UBOUND(SrcMemberLoadsData%F_DP,1) + i2_l = LBOUND(SrcMemberLoadsData%F_DP,2) + i2_u = UBOUND(SrcMemberLoadsData%F_DP,2) + IF (.NOT. ALLOCATED(DstMemberLoadsData%F_DP)) THEN + ALLOCATE(DstMemberLoadsData%F_DP(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMemberLoadsData%F_DP.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMemberLoadsData%F_DP = SrcMemberLoadsData%F_DP +ENDIF + END SUBROUTINE Morison_CopyMemberLoads + + SUBROUTINE Morison_DestroyMemberLoads( MemberLoadsData, ErrStat, ErrMsg ) + TYPE(Morison_MemberLoads), INTENT(INOUT) :: MemberLoadsData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMemberLoads' + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(MemberLoadsData%F_D)) THEN + DEALLOCATE(MemberLoadsData%F_D) +ENDIF +IF (ALLOCATED(MemberLoadsData%F_I)) THEN + DEALLOCATE(MemberLoadsData%F_I) +ENDIF +IF (ALLOCATED(MemberLoadsData%F_A)) THEN + DEALLOCATE(MemberLoadsData%F_A) +ENDIF +IF (ALLOCATED(MemberLoadsData%F_B)) THEN + DEALLOCATE(MemberLoadsData%F_B) +ENDIF +IF (ALLOCATED(MemberLoadsData%F_BF)) THEN + DEALLOCATE(MemberLoadsData%F_BF) +ENDIF +IF (ALLOCATED(MemberLoadsData%F_If)) THEN + DEALLOCATE(MemberLoadsData%F_If) +ENDIF +IF (ALLOCATED(MemberLoadsData%F_WMG)) THEN + DEALLOCATE(MemberLoadsData%F_WMG) +ENDIF +IF (ALLOCATED(MemberLoadsData%F_IMG)) THEN + DEALLOCATE(MemberLoadsData%F_IMG) +ENDIF +IF (ALLOCATED(MemberLoadsData%FV)) THEN + DEALLOCATE(MemberLoadsData%FV) +ENDIF +IF (ALLOCATED(MemberLoadsData%FA)) THEN + DEALLOCATE(MemberLoadsData%FA) +ENDIF +IF (ALLOCATED(MemberLoadsData%F_DP)) THEN + DEALLOCATE(MemberLoadsData%F_DP) +ENDIF + END SUBROUTINE Morison_DestroyMemberLoads + + SUBROUTINE Morison_PackMemberLoads( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Morison_MemberLoads), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_PackMemberLoads' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! F_D allocated yes/no + IF ( ALLOCATED(InData%F_D) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_D upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_D) ! F_D + END IF + Int_BufSz = Int_BufSz + 1 ! F_I allocated yes/no + IF ( ALLOCATED(InData%F_I) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_I upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_I) ! F_I + END IF + Int_BufSz = Int_BufSz + 1 ! F_A allocated yes/no + IF ( ALLOCATED(InData%F_A) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_A upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_A) ! F_A + END IF + Int_BufSz = Int_BufSz + 1 ! F_B allocated yes/no + IF ( ALLOCATED(InData%F_B) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_B upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_B) ! F_B + END IF + Int_BufSz = Int_BufSz + 1 ! F_BF allocated yes/no + IF ( ALLOCATED(InData%F_BF) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_BF upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_BF) ! F_BF + END IF + Int_BufSz = Int_BufSz + 1 ! F_If allocated yes/no + IF ( ALLOCATED(InData%F_If) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_If upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_If) ! F_If + END IF + Int_BufSz = Int_BufSz + 1 ! F_WMG allocated yes/no + IF ( ALLOCATED(InData%F_WMG) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_WMG upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_WMG) ! F_WMG + END IF + Int_BufSz = Int_BufSz + 1 ! F_IMG allocated yes/no + IF ( ALLOCATED(InData%F_IMG) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_IMG upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_IMG) ! F_IMG + END IF + Int_BufSz = Int_BufSz + 1 ! FV allocated yes/no + IF ( ALLOCATED(InData%FV) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! FV upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%FV) ! FV + END IF + Int_BufSz = Int_BufSz + 1 ! FA allocated yes/no + IF ( ALLOCATED(InData%FA) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! FA upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%FA) ! FA + END IF + Int_BufSz = Int_BufSz + 1 ! F_DP allocated yes/no + IF ( ALLOCATED(InData%F_DP) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_DP upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_DP) ! F_DP + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IF ( .NOT. ALLOCATED(InData%F_D) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_D,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_D,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_D,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_D,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%F_D,2), UBOUND(InData%F_D,2) + DO i1 = LBOUND(InData%F_D,1), UBOUND(InData%F_D,1) + ReKiBuf(Re_Xferred) = InData%F_D(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO END DO - END DO - IntKiBuf(Int_Xferred) = InData%NumSplits + END IF + IF ( .NOT. ALLOCATED(InData%F_I) ) THEN + IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%Splits,1), UBOUND(InData%Splits,1) - ReKiBuf(Re_Xferred) = InData%Splits(i1) - Re_Xferred = Re_Xferred + 1 - END DO - ReKiBuf(Re_Xferred) = InData%MGvolume - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%MDivSize - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%MCoefMod + ELSE + IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%MmbrCoefIDIndx + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_I,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_I,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_I,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_I,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%F_I,2), UBOUND(InData%F_I,2) + DO i1 = LBOUND(InData%F_I,1), UBOUND(InData%F_I,1) + ReKiBuf(Re_Xferred) = InData%F_I(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%F_A) ) THEN + IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%MmbrFilledIDIndx + ELSE + IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%FillFSLoc - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%FillDens - Re_Xferred = Re_Xferred + 1 - DO i1 = LBOUND(InData%F_Bouy,1), UBOUND(InData%F_Bouy,1) - ReKiBuf(Re_Xferred) = InData%F_Bouy(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%F_DP,1), UBOUND(InData%F_DP,1) - ReKiBuf(Re_Xferred) = InData%F_DP(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = TRANSFER(InData%PropPot, IntKiBuf(1)) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_A,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_A,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_A,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_A,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%F_A,2), UBOUND(InData%F_A,2) + DO i1 = LBOUND(InData%F_A,1), UBOUND(InData%F_A,1) + ReKiBuf(Re_Xferred) = InData%F_A(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%F_B) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_B,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_B,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_B,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_B,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%F_B,2), UBOUND(InData%F_B,2) + DO i1 = LBOUND(InData%F_B,1), UBOUND(InData%F_B,1) + ReKiBuf(Re_Xferred) = InData%F_B(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%F_BF) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_BF,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_BF,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_BF,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_BF,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%F_BF,2), UBOUND(InData%F_BF,2) + DO i1 = LBOUND(InData%F_BF,1), UBOUND(InData%F_BF,1) + ReKiBuf(Re_Xferred) = InData%F_BF(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%F_If) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_If,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_If,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_If,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_If,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%F_If,2), UBOUND(InData%F_If,2) + DO i1 = LBOUND(InData%F_If,1), UBOUND(InData%F_If,1) + ReKiBuf(Re_Xferred) = InData%F_If(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%F_WMG) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_WMG,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_WMG,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_WMG,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_WMG,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%F_WMG,2), UBOUND(InData%F_WMG,2) + DO i1 = LBOUND(InData%F_WMG,1), UBOUND(InData%F_WMG,1) + ReKiBuf(Re_Xferred) = InData%F_WMG(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%F_IMG) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_IMG,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_IMG,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_IMG,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_IMG,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%F_IMG,2), UBOUND(InData%F_IMG,2) + DO i1 = LBOUND(InData%F_IMG,1), UBOUND(InData%F_IMG,1) + ReKiBuf(Re_Xferred) = InData%F_IMG(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%FV) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FV,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FV,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FV,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FV,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%FV,2), UBOUND(InData%FV,2) + DO i1 = LBOUND(InData%FV,1), UBOUND(InData%FV,1) + ReKiBuf(Re_Xferred) = InData%FV(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%FA) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FA,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FA,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FA,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FA,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%FA,2), UBOUND(InData%FA,2) + DO i1 = LBOUND(InData%FA,1), UBOUND(InData%FA,1) + ReKiBuf(Re_Xferred) = InData%FA(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%F_DP) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_DP,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_DP,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_DP,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_DP,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%F_DP,2), UBOUND(InData%F_DP,2) + DO i1 = LBOUND(InData%F_DP,1), UBOUND(InData%F_DP,1) + ReKiBuf(Re_Xferred) = InData%F_DP(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + END SUBROUTINE Morison_PackMemberLoads + + SUBROUTINE Morison_UnPackMemberLoads( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Morison_MemberLoads), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_UnPackMemberLoads' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_D not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_D)) DEALLOCATE(OutData%F_D) + ALLOCATE(OutData%F_D(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_D.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%F_D,2), UBOUND(OutData%F_D,2) + DO i1 = LBOUND(OutData%F_D,1), UBOUND(OutData%F_D,1) + OutData%F_D(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_I not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_I)) DEALLOCATE(OutData%F_I) + ALLOCATE(OutData%F_I(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_I.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%F_I,2), UBOUND(OutData%F_I,2) + DO i1 = LBOUND(OutData%F_I,1), UBOUND(OutData%F_I,1) + OutData%F_I(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_A not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_A)) DEALLOCATE(OutData%F_A) + ALLOCATE(OutData%F_A(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_A.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%F_A,2), UBOUND(OutData%F_A,2) + DO i1 = LBOUND(OutData%F_A,1), UBOUND(OutData%F_A,1) + OutData%F_A(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_B not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_B)) DEALLOCATE(OutData%F_B) + ALLOCATE(OutData%F_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%F_B,2), UBOUND(OutData%F_B,2) + DO i1 = LBOUND(OutData%F_B,1), UBOUND(OutData%F_B,1) + OutData%F_B(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_BF not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_BF)) DEALLOCATE(OutData%F_BF) + ALLOCATE(OutData%F_BF(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_BF.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%F_BF,2), UBOUND(OutData%F_BF,2) + DO i1 = LBOUND(OutData%F_BF,1), UBOUND(OutData%F_BF,1) + OutData%F_BF(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_If not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_If)) DEALLOCATE(OutData%F_If) + ALLOCATE(OutData%F_If(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_If.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%F_If,2), UBOUND(OutData%F_If,2) + DO i1 = LBOUND(OutData%F_If,1), UBOUND(OutData%F_If,1) + OutData%F_If(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_WMG not allocated Int_Xferred = Int_Xferred + 1 - END SUBROUTINE Morison_PackMemberType - - SUBROUTINE Morison_UnPackMemberType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(Morison_MemberType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_UnPackMemberType' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%Node1Indx = IntKiBuf(Int_Xferred) + ELSE Int_Xferred = Int_Xferred + 1 - OutData%Node2Indx = IntKiBuf(Int_Xferred) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_WMG)) DEALLOCATE(OutData%F_WMG) + ALLOCATE(OutData%F_WMG(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_WMG.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%F_WMG,2), UBOUND(OutData%F_WMG,2) + DO i1 = LBOUND(OutData%F_WMG,1), UBOUND(OutData%F_WMG,1) + OutData%F_WMG(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_IMG not allocated Int_Xferred = Int_Xferred + 1 - OutData%R1 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%t1 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%R2 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%t2 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Cd1 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%CdMG1 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Ca1 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%CaMG1 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Cp1 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%CpMG1 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%AxCa1 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%AxCaMG1 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%AxCp1 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%AxCpMG1 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Cd2 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%CdMG2 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Ca2 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%CaMG2 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Cp2 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%CpMG2 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%AxCa2 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%AxCaMG2 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%AxCp2 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%AxCpMG2 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InpMbrDist1 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InpMbrDist2 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InpMbrLen = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InpMbrIndx = IntKiBuf(Int_Xferred) + ELSE Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%R_LToG,1) - i1_u = UBOUND(OutData%R_LToG,1) - i2_l = LBOUND(OutData%R_LToG,2) - i2_u = UBOUND(OutData%R_LToG,2) - DO i2 = LBOUND(OutData%R_LToG,2), UBOUND(OutData%R_LToG,2) - DO i1 = LBOUND(OutData%R_LToG,1), UBOUND(OutData%R_LToG,1) - OutData%R_LToG(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_IMG)) DEALLOCATE(OutData%F_IMG) + ALLOCATE(OutData%F_IMG(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_IMG.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%F_IMG,2), UBOUND(OutData%F_IMG,2) + DO i1 = LBOUND(OutData%F_IMG,1), UBOUND(OutData%F_IMG,1) + OutData%F_IMG(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO - END DO - OutData%NumSplits = IntKiBuf(Int_Xferred) + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FV not allocated Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%Splits,1) - i1_u = UBOUND(OutData%Splits,1) - DO i1 = LBOUND(OutData%Splits,1), UBOUND(OutData%Splits,1) - OutData%Splits(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%MGvolume = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%MDivSize = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%MCoefMod = IntKiBuf(Int_Xferred) + ELSE Int_Xferred = Int_Xferred + 1 - OutData%MmbrCoefIDIndx = IntKiBuf(Int_Xferred) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%FV)) DEALLOCATE(OutData%FV) + ALLOCATE(OutData%FV(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%FV,2), UBOUND(OutData%FV,2) + DO i1 = LBOUND(OutData%FV,1), UBOUND(OutData%FV,1) + OutData%FV(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FA not allocated Int_Xferred = Int_Xferred + 1 - OutData%MmbrFilledIDIndx = IntKiBuf(Int_Xferred) + ELSE Int_Xferred = Int_Xferred + 1 - OutData%FillFSLoc = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%FillDens = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - i1_l = LBOUND(OutData%F_Bouy,1) - i1_u = UBOUND(OutData%F_Bouy,1) - DO i1 = LBOUND(OutData%F_Bouy,1), UBOUND(OutData%F_Bouy,1) - OutData%F_Bouy(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%F_DP,1) - i1_u = UBOUND(OutData%F_DP,1) - DO i1 = LBOUND(OutData%F_DP,1), UBOUND(OutData%F_DP,1) - OutData%F_DP(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%PropPot = TRANSFER(IntKiBuf(Int_Xferred), OutData%PropPot) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%FA)) DEALLOCATE(OutData%FA) + ALLOCATE(OutData%FA(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FA.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%FA,2), UBOUND(OutData%FA,2) + DO i1 = LBOUND(OutData%FA,1), UBOUND(OutData%FA,1) + OutData%FA(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_DP not allocated Int_Xferred = Int_Xferred + 1 - END SUBROUTINE Morison_UnPackMemberType + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_DP)) DEALLOCATE(OutData%F_DP) + ALLOCATE(OutData%F_DP(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_DP.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%F_DP,2), UBOUND(OutData%F_DP,2) + DO i1 = LBOUND(OutData%F_DP,1), UBOUND(OutData%F_DP,1) + OutData%F_DP(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + END SUBROUTINE Morison_UnPackMemberLoads SUBROUTINE Morison_CopyCoefMembers( SrcCoefMembersData, DstCoefMembersData, CtrlCode, ErrStat, ErrMsg ) TYPE(Morison_CoefMembers), INTENT(IN) :: SrcCoefMembersData @@ -2285,6 +4899,10 @@ SUBROUTINE Morison_CopyCoefMembers( SrcCoefMembersData, DstCoefMembersData, Ctrl DstCoefMembersData%MemberCp2 = SrcCoefMembersData%MemberCp2 DstCoefMembersData%MemberCpMG1 = SrcCoefMembersData%MemberCpMG1 DstCoefMembersData%MemberCpMG2 = SrcCoefMembersData%MemberCpMG2 + DstCoefMembersData%MemberAxCd1 = SrcCoefMembersData%MemberAxCd1 + DstCoefMembersData%MemberAxCd2 = SrcCoefMembersData%MemberAxCd2 + DstCoefMembersData%MemberAxCdMG1 = SrcCoefMembersData%MemberAxCdMG1 + DstCoefMembersData%MemberAxCdMG2 = SrcCoefMembersData%MemberAxCdMG2 DstCoefMembersData%MemberAxCa1 = SrcCoefMembersData%MemberAxCa1 DstCoefMembersData%MemberAxCa2 = SrcCoefMembersData%MemberAxCa2 DstCoefMembersData%MemberAxCaMG1 = SrcCoefMembersData%MemberAxCaMG1 @@ -2354,6 +4972,10 @@ SUBROUTINE Morison_PackCoefMembers( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_BufSz = Re_BufSz + 1 ! MemberCp2 Re_BufSz = Re_BufSz + 1 ! MemberCpMG1 Re_BufSz = Re_BufSz + 1 ! MemberCpMG2 + Re_BufSz = Re_BufSz + 1 ! MemberAxCd1 + Re_BufSz = Re_BufSz + 1 ! MemberAxCd2 + Re_BufSz = Re_BufSz + 1 ! MemberAxCdMG1 + Re_BufSz = Re_BufSz + 1 ! MemberAxCdMG2 Re_BufSz = Re_BufSz + 1 ! MemberAxCa1 Re_BufSz = Re_BufSz + 1 ! MemberAxCa2 Re_BufSz = Re_BufSz + 1 ! MemberAxCaMG1 @@ -2415,6 +5037,14 @@ SUBROUTINE Morison_PackCoefMembers( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%MemberCpMG2 Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%MemberAxCd1 + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%MemberAxCd2 + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%MemberAxCdMG1 + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%MemberAxCdMG2 + Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%MemberAxCa1 Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%MemberAxCa2 @@ -2485,6 +5115,14 @@ SUBROUTINE Morison_UnPackCoefMembers( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Re_Xferred = Re_Xferred + 1 OutData%MemberCpMG2 = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%MemberAxCd1 = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%MemberAxCd2 = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%MemberAxCdMG1 = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%MemberAxCdMG2 = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 OutData%MemberAxCa1 = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%MemberAxCa2 = ReKiBuf(Re_Xferred) @@ -2670,29 +5308,53 @@ SUBROUTINE Morison_CopyMOutput( SrcMOutputData, DstMOutputData, CtrlCode, ErrSta DstMOutputData%NodeLocs = SrcMOutputData%NodeLocs ENDIF DstMOutputData%MemberIDIndx = SrcMOutputData%MemberIDIndx -IF (ALLOCATED(SrcMOutputData%Marker1)) THEN - i1_l = LBOUND(SrcMOutputData%Marker1,1) - i1_u = UBOUND(SrcMOutputData%Marker1,1) - IF (.NOT. ALLOCATED(DstMOutputData%Marker1)) THEN - ALLOCATE(DstMOutputData%Marker1(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMOutputData%MeshIndx1)) THEN + i1_l = LBOUND(SrcMOutputData%MeshIndx1,1) + i1_u = UBOUND(SrcMOutputData%MeshIndx1,1) + IF (.NOT. ALLOCATED(DstMOutputData%MeshIndx1)) THEN + ALLOCATE(DstMOutputData%MeshIndx1(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMOutputData%MeshIndx1.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMOutputData%MeshIndx1 = SrcMOutputData%MeshIndx1 +ENDIF +IF (ALLOCATED(SrcMOutputData%MeshIndx2)) THEN + i1_l = LBOUND(SrcMOutputData%MeshIndx2,1) + i1_u = UBOUND(SrcMOutputData%MeshIndx2,1) + IF (.NOT. ALLOCATED(DstMOutputData%MeshIndx2)) THEN + ALLOCATE(DstMOutputData%MeshIndx2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMOutputData%MeshIndx2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMOutputData%MeshIndx2 = SrcMOutputData%MeshIndx2 +ENDIF +IF (ALLOCATED(SrcMOutputData%MemberIndx1)) THEN + i1_l = LBOUND(SrcMOutputData%MemberIndx1,1) + i1_u = UBOUND(SrcMOutputData%MemberIndx1,1) + IF (.NOT. ALLOCATED(DstMOutputData%MemberIndx1)) THEN + ALLOCATE(DstMOutputData%MemberIndx1(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMOutputData%Marker1.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMOutputData%MemberIndx1.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMOutputData%Marker1 = SrcMOutputData%Marker1 + DstMOutputData%MemberIndx1 = SrcMOutputData%MemberIndx1 ENDIF -IF (ALLOCATED(SrcMOutputData%Marker2)) THEN - i1_l = LBOUND(SrcMOutputData%Marker2,1) - i1_u = UBOUND(SrcMOutputData%Marker2,1) - IF (.NOT. ALLOCATED(DstMOutputData%Marker2)) THEN - ALLOCATE(DstMOutputData%Marker2(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMOutputData%MemberIndx2)) THEN + i1_l = LBOUND(SrcMOutputData%MemberIndx2,1) + i1_u = UBOUND(SrcMOutputData%MemberIndx2,1) + IF (.NOT. ALLOCATED(DstMOutputData%MemberIndx2)) THEN + ALLOCATE(DstMOutputData%MemberIndx2(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMOutputData%Marker2.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMOutputData%MemberIndx2.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMOutputData%Marker2 = SrcMOutputData%Marker2 + DstMOutputData%MemberIndx2 = SrcMOutputData%MemberIndx2 ENDIF IF (ALLOCATED(SrcMOutputData%s)) THEN i1_l = LBOUND(SrcMOutputData%s,1) @@ -2720,11 +5382,17 @@ SUBROUTINE Morison_DestroyMOutput( MOutputData, ErrStat, ErrMsg ) IF (ALLOCATED(MOutputData%NodeLocs)) THEN DEALLOCATE(MOutputData%NodeLocs) ENDIF -IF (ALLOCATED(MOutputData%Marker1)) THEN - DEALLOCATE(MOutputData%Marker1) +IF (ALLOCATED(MOutputData%MeshIndx1)) THEN + DEALLOCATE(MOutputData%MeshIndx1) ENDIF -IF (ALLOCATED(MOutputData%Marker2)) THEN - DEALLOCATE(MOutputData%Marker2) +IF (ALLOCATED(MOutputData%MeshIndx2)) THEN + DEALLOCATE(MOutputData%MeshIndx2) +ENDIF +IF (ALLOCATED(MOutputData%MemberIndx1)) THEN + DEALLOCATE(MOutputData%MemberIndx1) +ENDIF +IF (ALLOCATED(MOutputData%MemberIndx2)) THEN + DEALLOCATE(MOutputData%MemberIndx2) ENDIF IF (ALLOCATED(MOutputData%s)) THEN DEALLOCATE(MOutputData%s) @@ -2774,15 +5442,25 @@ SUBROUTINE Morison_PackMOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Re_BufSz = Re_BufSz + SIZE(InData%NodeLocs) ! NodeLocs END IF Int_BufSz = Int_BufSz + 1 ! MemberIDIndx - Int_BufSz = Int_BufSz + 1 ! Marker1 allocated yes/no - IF ( ALLOCATED(InData%Marker1) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Marker1 upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%Marker1) ! Marker1 - END IF - Int_BufSz = Int_BufSz + 1 ! Marker2 allocated yes/no - IF ( ALLOCATED(InData%Marker2) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Marker2 upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%Marker2) ! Marker2 + Int_BufSz = Int_BufSz + 1 ! MeshIndx1 allocated yes/no + IF ( ALLOCATED(InData%MeshIndx1) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MeshIndx1 upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%MeshIndx1) ! MeshIndx1 + END IF + Int_BufSz = Int_BufSz + 1 ! MeshIndx2 allocated yes/no + IF ( ALLOCATED(InData%MeshIndx2) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MeshIndx2 upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%MeshIndx2) ! MeshIndx2 + END IF + Int_BufSz = Int_BufSz + 1 ! MemberIndx1 allocated yes/no + IF ( ALLOCATED(InData%MemberIndx1) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MemberIndx1 upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%MemberIndx1) ! MemberIndx1 + END IF + Int_BufSz = Int_BufSz + 1 ! MemberIndx2 allocated yes/no + IF ( ALLOCATED(InData%MemberIndx2) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MemberIndx2 upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%MemberIndx2) ! MemberIndx2 END IF Int_BufSz = Int_BufSz + 1 ! s allocated yes/no IF ( ALLOCATED(InData%s) ) THEN @@ -2837,33 +5515,63 @@ SUBROUTINE Morison_PackMOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err END IF IntKiBuf(Int_Xferred) = InData%MemberIDIndx Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%Marker1) ) THEN + IF ( .NOT. ALLOCATED(InData%MeshIndx1) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MeshIndx1,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MeshIndx1,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MeshIndx1,1), UBOUND(InData%MeshIndx1,1) + IntKiBuf(Int_Xferred) = InData%MeshIndx1(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MeshIndx2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MeshIndx2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MeshIndx2,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MeshIndx2,1), UBOUND(InData%MeshIndx2,1) + IntKiBuf(Int_Xferred) = InData%MeshIndx2(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MemberIndx1) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Marker1,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Marker1,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%MemberIndx1,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MemberIndx1,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Marker1,1), UBOUND(InData%Marker1,1) - IntKiBuf(Int_Xferred) = InData%Marker1(i1) + DO i1 = LBOUND(InData%MemberIndx1,1), UBOUND(InData%MemberIndx1,1) + IntKiBuf(Int_Xferred) = InData%MemberIndx1(i1) Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%Marker2) ) THEN + IF ( .NOT. ALLOCATED(InData%MemberIndx2) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Marker2,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Marker2,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%MemberIndx2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MemberIndx2,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Marker2,1), UBOUND(InData%Marker2,1) - IntKiBuf(Int_Xferred) = InData%Marker2(i1) + DO i1 = LBOUND(InData%MemberIndx2,1), UBOUND(InData%MemberIndx2,1) + IntKiBuf(Int_Xferred) = InData%MemberIndx2(i1) Int_Xferred = Int_Xferred + 1 END DO END IF @@ -2935,39 +5643,75 @@ SUBROUTINE Morison_UnPackMOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, END IF OutData%MemberIDIndx = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Marker1 not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MeshIndx1 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MeshIndx1)) DEALLOCATE(OutData%MeshIndx1) + ALLOCATE(OutData%MeshIndx1(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MeshIndx1.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MeshIndx1,1), UBOUND(OutData%MeshIndx1,1) + OutData%MeshIndx1(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MeshIndx2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MeshIndx2)) DEALLOCATE(OutData%MeshIndx2) + ALLOCATE(OutData%MeshIndx2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MeshIndx2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MeshIndx2,1), UBOUND(OutData%MeshIndx2,1) + OutData%MeshIndx2(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MemberIndx1 not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Marker1)) DEALLOCATE(OutData%Marker1) - ALLOCATE(OutData%Marker1(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%MemberIndx1)) DEALLOCATE(OutData%MemberIndx1) + ALLOCATE(OutData%MemberIndx1(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Marker1.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MemberIndx1.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Marker1,1), UBOUND(OutData%Marker1,1) - OutData%Marker1(i1) = IntKiBuf(Int_Xferred) + DO i1 = LBOUND(OutData%MemberIndx1,1), UBOUND(OutData%MemberIndx1,1) + OutData%MemberIndx1(i1) = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Marker2 not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MemberIndx2 not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Marker2)) DEALLOCATE(OutData%Marker2) - ALLOCATE(OutData%Marker2(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%MemberIndx2)) DEALLOCATE(OutData%MemberIndx2) + ALLOCATE(OutData%MemberIndx2(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Marker2.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MemberIndx2.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Marker2,1), UBOUND(OutData%Marker2,1) - OutData%Marker2(i1) = IntKiBuf(Int_Xferred) + DO i1 = LBOUND(OutData%MemberIndx2,1), UBOUND(OutData%MemberIndx2,1) + OutData%MemberIndx2(i1) = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 END DO END IF @@ -2999,7 +5743,6 @@ SUBROUTINE Morison_CopyJOutput( SrcJOutputData, DstJOutputData, CtrlCode, ErrSta CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'Morison_CopyJOutput' @@ -3008,8 +5751,6 @@ SUBROUTINE Morison_CopyJOutput( SrcJOutputData, DstJOutputData, CtrlCode, ErrSta ErrMsg = "" DstJOutputData%JointID = SrcJOutputData%JointID DstJOutputData%JointIDIndx = SrcJOutputData%JointIDIndx - DstJOutputData%NumMarkers = SrcJOutputData%NumMarkers - DstJOutputData%Markers = SrcJOutputData%Markers END SUBROUTINE Morison_CopyJOutput SUBROUTINE Morison_DestroyJOutput( JOutputData, ErrStat, ErrMsg ) @@ -3060,8 +5801,6 @@ SUBROUTINE Morison_PackJOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Int_BufSz = 0 Int_BufSz = Int_BufSz + 1 ! JointID Int_BufSz = Int_BufSz + 1 ! JointIDIndx - Int_BufSz = Int_BufSz + 1 ! NumMarkers - Int_BufSz = Int_BufSz + SIZE(InData%Markers) ! Markers IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -3093,12 +5832,6 @@ SUBROUTINE Morison_PackJOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%JointIDIndx Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NumMarkers - Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%Markers,1), UBOUND(InData%Markers,1) - IntKiBuf(Int_Xferred) = InData%Markers(i1) - Int_Xferred = Int_Xferred + 1 - END DO END SUBROUTINE Morison_PackJOutput SUBROUTINE Morison_UnPackJOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -3114,7 +5847,6 @@ SUBROUTINE Morison_UnPackJOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, INTEGER(IntKi) :: Db_Xferred INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'Morison_UnPackJOutput' @@ -3132,14 +5864,6 @@ SUBROUTINE Morison_UnPackJOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Xferred = Int_Xferred + 1 OutData%JointIDIndx = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%NumMarkers = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%Markers,1) - i1_u = UBOUND(OutData%Markers,1) - DO i1 = LBOUND(OutData%Markers,1), UBOUND(OutData%Markers,1) - OutData%Markers(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO END SUBROUTINE Morison_UnPackJOutput SUBROUTINE Morison_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) @@ -3165,7 +5889,6 @@ SUBROUTINE Morison_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, DstInitInputData%MSL2SWL = SrcInitInputData%MSL2SWL DstInitInputData%NJoints = SrcInitInputData%NJoints DstInitInputData%NNodes = SrcInitInputData%NNodes - DstInitInputData%TotalPossibleSuperMembers = SrcInitInputData%TotalPossibleSuperMembers IF (ALLOCATED(SrcInitInputData%InpJoints)) THEN i1_l = LBOUND(SrcInitInputData%InpJoints,1) i1_u = UBOUND(SrcInitInputData%InpJoints,1) @@ -3197,23 +5920,6 @@ SUBROUTINE Morison_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO -ENDIF - DstInitInputData%NElements = SrcInitInputData%NElements -IF (ALLOCATED(SrcInitInputData%Elements)) THEN - i1_l = LBOUND(SrcInitInputData%Elements,1) - i1_u = UBOUND(SrcInitInputData%Elements,1) - IF (.NOT. ALLOCATED(DstInitInputData%Elements)) THEN - ALLOCATE(DstInitInputData%Elements(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%Elements.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcInitInputData%Elements,1), UBOUND(SrcInitInputData%Elements,1) - CALL Morison_Copymembertype( SrcInitInputData%Elements(i1), DstInitInputData%Elements(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO ENDIF DstInitInputData%NAxCoefs = SrcInitInputData%NAxCoefs IF (ALLOCATED(SrcInitInputData%AxialCoefs)) THEN @@ -3255,6 +5961,8 @@ SUBROUTINE Morison_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, DstInitInputData%SimplCaMG = SrcInitInputData%SimplCaMG DstInitInputData%SimplCp = SrcInitInputData%SimplCp DstInitInputData%SimplCpMG = SrcInitInputData%SimplCpMG + DstInitInputData%SimplAxCd = SrcInitInputData%SimplAxCd + DstInitInputData%SimplAxCdMG = SrcInitInputData%SimplAxCdMG DstInitInputData%SimplAxCa = SrcInitInputData%SimplAxCa DstInitInputData%SimplAxCaMG = SrcInitInputData%SimplAxCaMG DstInitInputData%SimplAxCp = SrcInitInputData%SimplAxCp @@ -3495,12 +6203,6 @@ SUBROUTINE Morison_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) ENDDO DEALLOCATE(InitInputData%Nodes) ENDIF -IF (ALLOCATED(InitInputData%Elements)) THEN -DO i1 = LBOUND(InitInputData%Elements,1), UBOUND(InitInputData%Elements,1) - CALL Morison_Destroymembertype( InitInputData%Elements(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(InitInputData%Elements) -ENDIF IF (ALLOCATED(InitInputData%AxialCoefs)) THEN DO i1 = LBOUND(InitInputData%AxialCoefs,1), UBOUND(InitInputData%AxialCoefs,1) CALL Morison_Destroyaxialcoeftype( InitInputData%AxialCoefs(i1), ErrStat, ErrMsg ) @@ -3616,7 +6318,6 @@ SUBROUTINE Morison_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Re_BufSz = Re_BufSz + 1 ! MSL2SWL Int_BufSz = Int_BufSz + 1 ! NJoints Int_BufSz = Int_BufSz + 1 ! NNodes - Int_BufSz = Int_BufSz + 1 ! TotalPossibleSuperMembers Int_BufSz = Int_BufSz + 1 ! InpJoints allocated yes/no IF ( ALLOCATED(InData%InpJoints) ) THEN Int_BufSz = Int_BufSz + 2*1 ! InpJoints upper/lower bounds for each dimension @@ -3642,47 +6343,23 @@ SUBROUTINE Morison_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E END DO END IF Int_BufSz = Int_BufSz + 1 ! Nodes allocated yes/no - IF ( ALLOCATED(InData%Nodes) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Nodes upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Nodes,1), UBOUND(InData%Nodes,1) - Int_BufSz = Int_BufSz + 3 ! Nodes: size of buffers for each call to pack subtype - CALL Morison_Packnodetype( Re_Buf, Db_Buf, Int_Buf, InData%Nodes(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Nodes - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Nodes - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Nodes - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Nodes - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO - END IF - Int_BufSz = Int_BufSz + 1 ! NElements - Int_BufSz = Int_BufSz + 1 ! Elements allocated yes/no - IF ( ALLOCATED(InData%Elements) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Elements upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Elements,1), UBOUND(InData%Elements,1) - Int_BufSz = Int_BufSz + 3 ! Elements: size of buffers for each call to pack subtype - CALL Morison_Packmembertype( Re_Buf, Db_Buf, Int_Buf, InData%Elements(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Elements + IF ( ALLOCATED(InData%Nodes) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Nodes upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Nodes,1), UBOUND(InData%Nodes,1) + Int_BufSz = Int_BufSz + 3 ! Nodes: size of buffers for each call to pack subtype + CALL Morison_Packnodetype( Re_Buf, Db_Buf, Int_Buf, InData%Nodes(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Nodes CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Elements + IF(ALLOCATED(Re_Buf)) THEN ! Nodes Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Elements + IF(ALLOCATED(Db_Buf)) THEN ! Nodes Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Elements + IF(ALLOCATED(Int_Buf)) THEN ! Nodes Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -3742,6 +6419,8 @@ SUBROUTINE Morison_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Re_BufSz = Re_BufSz + 1 ! SimplCaMG Re_BufSz = Re_BufSz + 1 ! SimplCp Re_BufSz = Re_BufSz + 1 ! SimplCpMG + Re_BufSz = Re_BufSz + 1 ! SimplAxCd + Re_BufSz = Re_BufSz + 1 ! SimplAxCdMG Re_BufSz = Re_BufSz + 1 ! SimplAxCa Re_BufSz = Re_BufSz + 1 ! SimplAxCaMG Re_BufSz = Re_BufSz + 1 ! SimplAxCp @@ -3993,8 +6672,6 @@ SUBROUTINE Morison_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NNodes Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%TotalPossibleSuperMembers - Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%InpJoints) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -4077,49 +6754,6 @@ SUBROUTINE Morison_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E ENDIF END DO END IF - IntKiBuf(Int_Xferred) = InData%NElements - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%Elements) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Elements,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Elements,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%Elements,1), UBOUND(InData%Elements,1) - CALL Morison_Packmembertype( Re_Buf, Db_Buf, Int_Buf, InData%Elements(i1), ErrStat2, ErrMsg2, OnlySize ) ! Elements - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END DO - END IF IntKiBuf(Int_Xferred) = InData%NAxCoefs Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%AxialCoefs) ) THEN @@ -4218,6 +6852,10 @@ SUBROUTINE Morison_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%SimplCpMG Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%SimplAxCd + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%SimplAxCdMG + Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%SimplAxCa Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%SimplAxCaMG @@ -4716,8 +7354,6 @@ SUBROUTINE Morison_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Int_Xferred = Int_Xferred + 1 OutData%NNodes = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%TotalPossibleSuperMembers = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InpJoints not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -4830,64 +7466,6 @@ SUBROUTINE Morison_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - OutData%NElements = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Elements not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Elements)) DEALLOCATE(OutData%Elements) - ALLOCATE(OutData%Elements(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Elements.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%Elements,1), UBOUND(OutData%Elements,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL Morison_Unpackmembertype( Re_Buf, Db_Buf, Int_Buf, OutData%Elements(i1), ErrStat2, ErrMsg2 ) ! Elements - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END DO - END IF OutData%NAxCoefs = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AxialCoefs not allocated @@ -5016,6 +7594,10 @@ SUBROUTINE Morison_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Re_Xferred = Re_Xferred + 1 OutData%SimplCpMG = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%SimplAxCd = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%SimplAxCdMG = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 OutData%SimplAxCa = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%SimplAxCaMG = ReKiBuf(Re_Xferred) @@ -5599,7 +8181,7 @@ SUBROUTINE Morison_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat END SUBROUTINE Morison_UnPackInitInput SUBROUTINE Morison_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(Morison_InitOutputType), INTENT(INOUT) :: SrcInitOutputData + TYPE(Morison_InitOutputType), INTENT(IN) :: SrcInitOutputData TYPE(Morison_InitOutputType), INTENT(INOUT) :: DstInitOutputData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat @@ -5613,24 +8195,6 @@ SUBROUTINE Morison_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCod ! ErrStat = ErrID_None ErrMsg = "" - CALL MeshCopy( SrcInitOutputData%DistribMesh, DstInitOutputData%DistribMesh, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL MeshCopy( SrcInitOutputData%LumpedMesh, DstInitOutputData%LumpedMesh, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN -IF (ALLOCATED(SrcInitOutputData%Morison_Rad)) THEN - i1_l = LBOUND(SrcInitOutputData%Morison_Rad,1) - i1_u = UBOUND(SrcInitOutputData%Morison_Rad,1) - IF (.NOT. ALLOCATED(DstInitOutputData%Morison_Rad)) THEN - ALLOCATE(DstInitOutputData%Morison_Rad(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%Morison_Rad.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInitOutputData%Morison_Rad = SrcInitOutputData%Morison_Rad -ENDIF IF (ALLOCATED(SrcInitOutputData%WriteOutputHdr)) THEN i1_l = LBOUND(SrcInitOutputData%WriteOutputHdr,1) i1_u = UBOUND(SrcInitOutputData%WriteOutputHdr,1) @@ -5666,11 +8230,6 @@ SUBROUTINE Morison_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( InitOutputData%DistribMesh, ErrStat, ErrMsg ) - CALL MeshDestroy( InitOutputData%LumpedMesh, ErrStat, ErrMsg ) -IF (ALLOCATED(InitOutputData%Morison_Rad)) THEN - DEALLOCATE(InitOutputData%Morison_Rad) -ENDIF IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF @@ -5695,173 +8254,62 @@ SUBROUTINE Morison_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, INTEGER(IntKi) :: Int_BufSz INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_PackInitOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! DistribMesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%DistribMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! DistribMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! DistribMesh - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! DistribMesh - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! DistribMesh - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! LumpedMesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%LumpedMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! LumpedMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! LumpedMesh - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! LumpedMesh - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! LumpedMesh - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 1 ! Morison_Rad allocated yes/no - IF ( ALLOCATED(InData%Morison_Rad) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Morison_Rad upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Morison_Rad) ! Morison_Rad - END IF - Int_BufSz = Int_BufSz + 1 ! WriteOutputHdr allocated yes/no - IF ( ALLOCATED(InData%WriteOutputHdr) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! WriteOutputHdr upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputHdr)*LEN(InData%WriteOutputHdr) ! WriteOutputHdr - END IF - Int_BufSz = Int_BufSz + 1 ! WriteOutputUnt allocated yes/no - IF ( ALLOCATED(InData%WriteOutputUnt) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! WriteOutputUnt upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputUnt)*LEN(InData%WriteOutputUnt) ! WriteOutputUnt - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL MeshPack( InData%DistribMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! DistribMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL MeshPack( InData%LumpedMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! LumpedMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF ( .NOT. ALLOCATED(InData%Morison_Rad) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Morison_Rad,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Morison_Rad,1) - Int_Xferred = Int_Xferred + 2 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_PackInitOutput' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - DO i1 = LBOUND(InData%Morison_Rad,1), UBOUND(InData%Morison_Rad,1) - ReKiBuf(Re_Xferred) = InData%Morison_Rad(i1) - Re_Xferred = Re_Xferred + 1 - END DO + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! WriteOutputHdr allocated yes/no + IF ( ALLOCATED(InData%WriteOutputHdr) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WriteOutputHdr upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputHdr)*LEN(InData%WriteOutputHdr) ! WriteOutputHdr + END IF + Int_BufSz = Int_BufSz + 1 ! WriteOutputUnt allocated yes/no + IF ( ALLOCATED(InData%WriteOutputUnt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WriteOutputUnt upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputUnt)*LEN(InData%WriteOutputUnt) ! WriteOutputUnt + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + IF ( .NOT. ALLOCATED(InData%WriteOutputHdr) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -5925,104 +8373,6 @@ SUBROUTINE Morison_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL MeshUnpack( OutData%DistribMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! DistribMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL MeshUnpack( OutData%LumpedMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! LumpedMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Morison_Rad not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Morison_Rad)) DEALLOCATE(OutData%Morison_Rad) - ALLOCATE(OutData%Morison_Rad(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Morison_Rad.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%Morison_Rad,1), UBOUND(OutData%Morison_Rad,1) - OutData%Morison_Rad(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputHdr not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -6581,253 +8931,171 @@ SUBROUTINE Morison_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(SrcMiscData%D_F_D)) THEN - i1_l = LBOUND(SrcMiscData%D_F_D,1) - i1_u = UBOUND(SrcMiscData%D_F_D,1) - i2_l = LBOUND(SrcMiscData%D_F_D,2) - i2_u = UBOUND(SrcMiscData%D_F_D,2) - IF (.NOT. ALLOCATED(DstMiscData%D_F_D)) THEN - ALLOCATE(DstMiscData%D_F_D(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%D_F_D.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstMiscData%D_F_D = SrcMiscData%D_F_D -ENDIF -IF (ALLOCATED(SrcMiscData%D_F_I)) THEN - i1_l = LBOUND(SrcMiscData%D_F_I,1) - i1_u = UBOUND(SrcMiscData%D_F_I,1) - i2_l = LBOUND(SrcMiscData%D_F_I,2) - i2_u = UBOUND(SrcMiscData%D_F_I,2) - IF (.NOT. ALLOCATED(DstMiscData%D_F_I)) THEN - ALLOCATE(DstMiscData%D_F_I(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%D_F_I.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstMiscData%D_F_I = SrcMiscData%D_F_I -ENDIF -IF (ALLOCATED(SrcMiscData%D_F_B)) THEN - i1_l = LBOUND(SrcMiscData%D_F_B,1) - i1_u = UBOUND(SrcMiscData%D_F_B,1) - i2_l = LBOUND(SrcMiscData%D_F_B,2) - i2_u = UBOUND(SrcMiscData%D_F_B,2) - IF (.NOT. ALLOCATED(DstMiscData%D_F_B)) THEN - ALLOCATE(DstMiscData%D_F_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%D_F_B.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstMiscData%D_F_B = SrcMiscData%D_F_B -ENDIF -IF (ALLOCATED(SrcMiscData%D_F_AM)) THEN - i1_l = LBOUND(SrcMiscData%D_F_AM,1) - i1_u = UBOUND(SrcMiscData%D_F_AM,1) - i2_l = LBOUND(SrcMiscData%D_F_AM,2) - i2_u = UBOUND(SrcMiscData%D_F_AM,2) - IF (.NOT. ALLOCATED(DstMiscData%D_F_AM)) THEN - ALLOCATE(DstMiscData%D_F_AM(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%D_F_AM.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstMiscData%D_F_AM = SrcMiscData%D_F_AM -ENDIF -IF (ALLOCATED(SrcMiscData%D_F_AM_M)) THEN - i1_l = LBOUND(SrcMiscData%D_F_AM_M,1) - i1_u = UBOUND(SrcMiscData%D_F_AM_M,1) - i2_l = LBOUND(SrcMiscData%D_F_AM_M,2) - i2_u = UBOUND(SrcMiscData%D_F_AM_M,2) - IF (.NOT. ALLOCATED(DstMiscData%D_F_AM_M)) THEN - ALLOCATE(DstMiscData%D_F_AM_M(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%D_F_AM_M.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstMiscData%D_F_AM_M = SrcMiscData%D_F_AM_M -ENDIF -IF (ALLOCATED(SrcMiscData%D_F_AM_MG)) THEN - i1_l = LBOUND(SrcMiscData%D_F_AM_MG,1) - i1_u = UBOUND(SrcMiscData%D_F_AM_MG,1) - i2_l = LBOUND(SrcMiscData%D_F_AM_MG,2) - i2_u = UBOUND(SrcMiscData%D_F_AM_MG,2) - IF (.NOT. ALLOCATED(DstMiscData%D_F_AM_MG)) THEN - ALLOCATE(DstMiscData%D_F_AM_MG(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%D_F_AM_MG.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstMiscData%D_F_AM_MG = SrcMiscData%D_F_AM_MG -ENDIF -IF (ALLOCATED(SrcMiscData%D_F_AM_F)) THEN - i1_l = LBOUND(SrcMiscData%D_F_AM_F,1) - i1_u = UBOUND(SrcMiscData%D_F_AM_F,1) - i2_l = LBOUND(SrcMiscData%D_F_AM_F,2) - i2_u = UBOUND(SrcMiscData%D_F_AM_F,2) - IF (.NOT. ALLOCATED(DstMiscData%D_F_AM_F)) THEN - ALLOCATE(DstMiscData%D_F_AM_F(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%D_F_AM_F.', ErrStat, ErrMsg,RoutineName) +IF (ALLOCATED(SrcMiscData%FV)) THEN + i1_l = LBOUND(SrcMiscData%FV,1) + i1_u = UBOUND(SrcMiscData%FV,1) + i2_l = LBOUND(SrcMiscData%FV,2) + i2_u = UBOUND(SrcMiscData%FV,2) + IF (.NOT. ALLOCATED(DstMiscData%FV)) THEN + ALLOCATE(DstMiscData%FV(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%FV.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%D_F_AM_F = SrcMiscData%D_F_AM_F + DstMiscData%FV = SrcMiscData%FV ENDIF -IF (ALLOCATED(SrcMiscData%D_FV)) THEN - i1_l = LBOUND(SrcMiscData%D_FV,1) - i1_u = UBOUND(SrcMiscData%D_FV,1) - i2_l = LBOUND(SrcMiscData%D_FV,2) - i2_u = UBOUND(SrcMiscData%D_FV,2) - IF (.NOT. ALLOCATED(DstMiscData%D_FV)) THEN - ALLOCATE(DstMiscData%D_FV(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMiscData%FA)) THEN + i1_l = LBOUND(SrcMiscData%FA,1) + i1_u = UBOUND(SrcMiscData%FA,1) + i2_l = LBOUND(SrcMiscData%FA,2) + i2_u = UBOUND(SrcMiscData%FA,2) + IF (.NOT. ALLOCATED(DstMiscData%FA)) THEN + ALLOCATE(DstMiscData%FA(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%D_FV.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%FA.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%D_FV = SrcMiscData%D_FV + DstMiscData%FA = SrcMiscData%FA ENDIF -IF (ALLOCATED(SrcMiscData%D_FA)) THEN - i1_l = LBOUND(SrcMiscData%D_FA,1) - i1_u = UBOUND(SrcMiscData%D_FA,1) - i2_l = LBOUND(SrcMiscData%D_FA,2) - i2_u = UBOUND(SrcMiscData%D_FA,2) - IF (.NOT. ALLOCATED(DstMiscData%D_FA)) THEN - ALLOCATE(DstMiscData%D_FA(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMiscData%FDynP)) THEN + i1_l = LBOUND(SrcMiscData%FDynP,1) + i1_u = UBOUND(SrcMiscData%FDynP,1) + IF (.NOT. ALLOCATED(DstMiscData%FDynP)) THEN + ALLOCATE(DstMiscData%FDynP(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%D_FA.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%FDynP.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%D_FA = SrcMiscData%D_FA + DstMiscData%FDynP = SrcMiscData%FDynP ENDIF -IF (ALLOCATED(SrcMiscData%D_FDynP)) THEN - i1_l = LBOUND(SrcMiscData%D_FDynP,1) - i1_u = UBOUND(SrcMiscData%D_FDynP,1) - IF (.NOT. ALLOCATED(DstMiscData%D_FDynP)) THEN - ALLOCATE(DstMiscData%D_FDynP(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMiscData%vrel)) THEN + i1_l = LBOUND(SrcMiscData%vrel,1) + i1_u = UBOUND(SrcMiscData%vrel,1) + i2_l = LBOUND(SrcMiscData%vrel,2) + i2_u = UBOUND(SrcMiscData%vrel,2) + IF (.NOT. ALLOCATED(DstMiscData%vrel)) THEN + ALLOCATE(DstMiscData%vrel(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%D_FDynP.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%vrel.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%D_FDynP = SrcMiscData%D_FDynP + DstMiscData%vrel = SrcMiscData%vrel ENDIF -IF (ALLOCATED(SrcMiscData%L_F_B)) THEN - i1_l = LBOUND(SrcMiscData%L_F_B,1) - i1_u = UBOUND(SrcMiscData%L_F_B,1) - i2_l = LBOUND(SrcMiscData%L_F_B,2) - i2_u = UBOUND(SrcMiscData%L_F_B,2) - IF (.NOT. ALLOCATED(DstMiscData%L_F_B)) THEN - ALLOCATE(DstMiscData%L_F_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMiscData%nodeInWater)) THEN + i1_l = LBOUND(SrcMiscData%nodeInWater,1) + i1_u = UBOUND(SrcMiscData%nodeInWater,1) + IF (.NOT. ALLOCATED(DstMiscData%nodeInWater)) THEN + ALLOCATE(DstMiscData%nodeInWater(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%L_F_B.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%nodeInWater.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%L_F_B = SrcMiscData%L_F_B + DstMiscData%nodeInWater = SrcMiscData%nodeInWater ENDIF -IF (ALLOCATED(SrcMiscData%L_F_D)) THEN - i1_l = LBOUND(SrcMiscData%L_F_D,1) - i1_u = UBOUND(SrcMiscData%L_F_D,1) - i2_l = LBOUND(SrcMiscData%L_F_D,2) - i2_u = UBOUND(SrcMiscData%L_F_D,2) - IF (.NOT. ALLOCATED(DstMiscData%L_F_D)) THEN - ALLOCATE(DstMiscData%L_F_D(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMiscData%memberLoads)) THEN + i1_l = LBOUND(SrcMiscData%memberLoads,1) + i1_u = UBOUND(SrcMiscData%memberLoads,1) + IF (.NOT. ALLOCATED(DstMiscData%memberLoads)) THEN + ALLOCATE(DstMiscData%memberLoads(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%L_F_D.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%memberLoads.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%L_F_D = SrcMiscData%L_F_D + DO i1 = LBOUND(SrcMiscData%memberLoads,1), UBOUND(SrcMiscData%memberLoads,1) + CALL Morison_Copymemberloads( SrcMiscData%memberLoads(i1), DstMiscData%memberLoads(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO ENDIF -IF (ALLOCATED(SrcMiscData%L_F_I)) THEN - i1_l = LBOUND(SrcMiscData%L_F_I,1) - i1_u = UBOUND(SrcMiscData%L_F_I,1) - i2_l = LBOUND(SrcMiscData%L_F_I,2) - i2_u = UBOUND(SrcMiscData%L_F_I,2) - IF (.NOT. ALLOCATED(DstMiscData%L_F_I)) THEN - ALLOCATE(DstMiscData%L_F_I(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMiscData%F_B_End)) THEN + i1_l = LBOUND(SrcMiscData%F_B_End,1) + i1_u = UBOUND(SrcMiscData%F_B_End,1) + i2_l = LBOUND(SrcMiscData%F_B_End,2) + i2_u = UBOUND(SrcMiscData%F_B_End,2) + IF (.NOT. ALLOCATED(DstMiscData%F_B_End)) THEN + ALLOCATE(DstMiscData%F_B_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%L_F_I.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%F_B_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%L_F_I = SrcMiscData%L_F_I + DstMiscData%F_B_End = SrcMiscData%F_B_End ENDIF -IF (ALLOCATED(SrcMiscData%L_F_DP)) THEN - i1_l = LBOUND(SrcMiscData%L_F_DP,1) - i1_u = UBOUND(SrcMiscData%L_F_DP,1) - i2_l = LBOUND(SrcMiscData%L_F_DP,2) - i2_u = UBOUND(SrcMiscData%L_F_DP,2) - IF (.NOT. ALLOCATED(DstMiscData%L_F_DP)) THEN - ALLOCATE(DstMiscData%L_F_DP(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMiscData%F_D_End)) THEN + i1_l = LBOUND(SrcMiscData%F_D_End,1) + i1_u = UBOUND(SrcMiscData%F_D_End,1) + i2_l = LBOUND(SrcMiscData%F_D_End,2) + i2_u = UBOUND(SrcMiscData%F_D_End,2) + IF (.NOT. ALLOCATED(DstMiscData%F_D_End)) THEN + ALLOCATE(DstMiscData%F_D_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%L_F_DP.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%F_D_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%L_F_DP = SrcMiscData%L_F_DP + DstMiscData%F_D_End = SrcMiscData%F_D_End ENDIF -IF (ALLOCATED(SrcMiscData%L_F_AM)) THEN - i1_l = LBOUND(SrcMiscData%L_F_AM,1) - i1_u = UBOUND(SrcMiscData%L_F_AM,1) - i2_l = LBOUND(SrcMiscData%L_F_AM,2) - i2_u = UBOUND(SrcMiscData%L_F_AM,2) - IF (.NOT. ALLOCATED(DstMiscData%L_F_AM)) THEN - ALLOCATE(DstMiscData%L_F_AM(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMiscData%F_I_End)) THEN + i1_l = LBOUND(SrcMiscData%F_I_End,1) + i1_u = UBOUND(SrcMiscData%F_I_End,1) + i2_l = LBOUND(SrcMiscData%F_I_End,2) + i2_u = UBOUND(SrcMiscData%F_I_End,2) + IF (.NOT. ALLOCATED(DstMiscData%F_I_End)) THEN + ALLOCATE(DstMiscData%F_I_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%L_F_AM.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%F_I_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%L_F_AM = SrcMiscData%L_F_AM + DstMiscData%F_I_End = SrcMiscData%F_I_End ENDIF -IF (ALLOCATED(SrcMiscData%L_FV)) THEN - i1_l = LBOUND(SrcMiscData%L_FV,1) - i1_u = UBOUND(SrcMiscData%L_FV,1) - i2_l = LBOUND(SrcMiscData%L_FV,2) - i2_u = UBOUND(SrcMiscData%L_FV,2) - IF (.NOT. ALLOCATED(DstMiscData%L_FV)) THEN - ALLOCATE(DstMiscData%L_FV(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMiscData%F_IMG_End)) THEN + i1_l = LBOUND(SrcMiscData%F_IMG_End,1) + i1_u = UBOUND(SrcMiscData%F_IMG_End,1) + i2_l = LBOUND(SrcMiscData%F_IMG_End,2) + i2_u = UBOUND(SrcMiscData%F_IMG_End,2) + IF (.NOT. ALLOCATED(DstMiscData%F_IMG_End)) THEN + ALLOCATE(DstMiscData%F_IMG_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%L_FV.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%F_IMG_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%L_FV = SrcMiscData%L_FV + DstMiscData%F_IMG_End = SrcMiscData%F_IMG_End ENDIF -IF (ALLOCATED(SrcMiscData%L_FA)) THEN - i1_l = LBOUND(SrcMiscData%L_FA,1) - i1_u = UBOUND(SrcMiscData%L_FA,1) - i2_l = LBOUND(SrcMiscData%L_FA,2) - i2_u = UBOUND(SrcMiscData%L_FA,2) - IF (.NOT. ALLOCATED(DstMiscData%L_FA)) THEN - ALLOCATE(DstMiscData%L_FA(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMiscData%F_A_End)) THEN + i1_l = LBOUND(SrcMiscData%F_A_End,1) + i1_u = UBOUND(SrcMiscData%F_A_End,1) + i2_l = LBOUND(SrcMiscData%F_A_End,2) + i2_u = UBOUND(SrcMiscData%F_A_End,2) + IF (.NOT. ALLOCATED(DstMiscData%F_A_End)) THEN + ALLOCATE(DstMiscData%F_A_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%L_FA.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%F_A_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%L_FA = SrcMiscData%L_FA + DstMiscData%F_A_End = SrcMiscData%F_A_End ENDIF -IF (ALLOCATED(SrcMiscData%L_FDynP)) THEN - i1_l = LBOUND(SrcMiscData%L_FDynP,1) - i1_u = UBOUND(SrcMiscData%L_FDynP,1) - IF (.NOT. ALLOCATED(DstMiscData%L_FDynP)) THEN - ALLOCATE(DstMiscData%L_FDynP(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMiscData%F_BF_End)) THEN + i1_l = LBOUND(SrcMiscData%F_BF_End,1) + i1_u = UBOUND(SrcMiscData%F_BF_End,1) + i2_l = LBOUND(SrcMiscData%F_BF_End,2) + i2_u = UBOUND(SrcMiscData%F_BF_End,2) + IF (.NOT. ALLOCATED(DstMiscData%F_BF_End)) THEN + ALLOCATE(DstMiscData%F_BF_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%L_FDynP.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%F_BF_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%L_FDynP = SrcMiscData%L_FDynP + DstMiscData%F_BF_End = SrcMiscData%F_BF_End ENDIF DstMiscData%LastIndWave = SrcMiscData%LastIndWave END SUBROUTINE Morison_CopyMisc @@ -6841,59 +9109,44 @@ SUBROUTINE Morison_DestroyMisc( MiscData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(MiscData%D_F_D)) THEN - DEALLOCATE(MiscData%D_F_D) -ENDIF -IF (ALLOCATED(MiscData%D_F_I)) THEN - DEALLOCATE(MiscData%D_F_I) -ENDIF -IF (ALLOCATED(MiscData%D_F_B)) THEN - DEALLOCATE(MiscData%D_F_B) -ENDIF -IF (ALLOCATED(MiscData%D_F_AM)) THEN - DEALLOCATE(MiscData%D_F_AM) -ENDIF -IF (ALLOCATED(MiscData%D_F_AM_M)) THEN - DEALLOCATE(MiscData%D_F_AM_M) -ENDIF -IF (ALLOCATED(MiscData%D_F_AM_MG)) THEN - DEALLOCATE(MiscData%D_F_AM_MG) +IF (ALLOCATED(MiscData%FV)) THEN + DEALLOCATE(MiscData%FV) ENDIF -IF (ALLOCATED(MiscData%D_F_AM_F)) THEN - DEALLOCATE(MiscData%D_F_AM_F) +IF (ALLOCATED(MiscData%FA)) THEN + DEALLOCATE(MiscData%FA) ENDIF -IF (ALLOCATED(MiscData%D_FV)) THEN - DEALLOCATE(MiscData%D_FV) +IF (ALLOCATED(MiscData%FDynP)) THEN + DEALLOCATE(MiscData%FDynP) ENDIF -IF (ALLOCATED(MiscData%D_FA)) THEN - DEALLOCATE(MiscData%D_FA) +IF (ALLOCATED(MiscData%vrel)) THEN + DEALLOCATE(MiscData%vrel) ENDIF -IF (ALLOCATED(MiscData%D_FDynP)) THEN - DEALLOCATE(MiscData%D_FDynP) +IF (ALLOCATED(MiscData%nodeInWater)) THEN + DEALLOCATE(MiscData%nodeInWater) ENDIF -IF (ALLOCATED(MiscData%L_F_B)) THEN - DEALLOCATE(MiscData%L_F_B) -ENDIF -IF (ALLOCATED(MiscData%L_F_D)) THEN - DEALLOCATE(MiscData%L_F_D) +IF (ALLOCATED(MiscData%memberLoads)) THEN +DO i1 = LBOUND(MiscData%memberLoads,1), UBOUND(MiscData%memberLoads,1) + CALL Morison_Destroymemberloads( MiscData%memberLoads(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(MiscData%memberLoads) ENDIF -IF (ALLOCATED(MiscData%L_F_I)) THEN - DEALLOCATE(MiscData%L_F_I) +IF (ALLOCATED(MiscData%F_B_End)) THEN + DEALLOCATE(MiscData%F_B_End) ENDIF -IF (ALLOCATED(MiscData%L_F_DP)) THEN - DEALLOCATE(MiscData%L_F_DP) +IF (ALLOCATED(MiscData%F_D_End)) THEN + DEALLOCATE(MiscData%F_D_End) ENDIF -IF (ALLOCATED(MiscData%L_F_AM)) THEN - DEALLOCATE(MiscData%L_F_AM) +IF (ALLOCATED(MiscData%F_I_End)) THEN + DEALLOCATE(MiscData%F_I_End) ENDIF -IF (ALLOCATED(MiscData%L_FV)) THEN - DEALLOCATE(MiscData%L_FV) +IF (ALLOCATED(MiscData%F_IMG_End)) THEN + DEALLOCATE(MiscData%F_IMG_End) ENDIF -IF (ALLOCATED(MiscData%L_FA)) THEN - DEALLOCATE(MiscData%L_FA) +IF (ALLOCATED(MiscData%F_A_End)) THEN + DEALLOCATE(MiscData%F_A_End) ENDIF -IF (ALLOCATED(MiscData%L_FDynP)) THEN - DEALLOCATE(MiscData%L_FDynP) +IF (ALLOCATED(MiscData%F_BF_End)) THEN + DEALLOCATE(MiscData%F_BF_End) ENDIF END SUBROUTINE Morison_DestroyMisc @@ -6932,95 +9185,84 @@ SUBROUTINE Morison_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! D_F_D allocated yes/no - IF ( ALLOCATED(InData%D_F_D) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! D_F_D upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_F_D) ! D_F_D - END IF - Int_BufSz = Int_BufSz + 1 ! D_F_I allocated yes/no - IF ( ALLOCATED(InData%D_F_I) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! D_F_I upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_F_I) ! D_F_I - END IF - Int_BufSz = Int_BufSz + 1 ! D_F_B allocated yes/no - IF ( ALLOCATED(InData%D_F_B) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! D_F_B upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_F_B) ! D_F_B - END IF - Int_BufSz = Int_BufSz + 1 ! D_F_AM allocated yes/no - IF ( ALLOCATED(InData%D_F_AM) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! D_F_AM upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_F_AM) ! D_F_AM - END IF - Int_BufSz = Int_BufSz + 1 ! D_F_AM_M allocated yes/no - IF ( ALLOCATED(InData%D_F_AM_M) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! D_F_AM_M upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_F_AM_M) ! D_F_AM_M - END IF - Int_BufSz = Int_BufSz + 1 ! D_F_AM_MG allocated yes/no - IF ( ALLOCATED(InData%D_F_AM_MG) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! D_F_AM_MG upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_F_AM_MG) ! D_F_AM_MG - END IF - Int_BufSz = Int_BufSz + 1 ! D_F_AM_F allocated yes/no - IF ( ALLOCATED(InData%D_F_AM_F) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! D_F_AM_F upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_F_AM_F) ! D_F_AM_F - END IF - Int_BufSz = Int_BufSz + 1 ! D_FV allocated yes/no - IF ( ALLOCATED(InData%D_FV) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! D_FV upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_FV) ! D_FV - END IF - Int_BufSz = Int_BufSz + 1 ! D_FA allocated yes/no - IF ( ALLOCATED(InData%D_FA) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! D_FA upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_FA) ! D_FA - END IF - Int_BufSz = Int_BufSz + 1 ! D_FDynP allocated yes/no - IF ( ALLOCATED(InData%D_FDynP) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! D_FDynP upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_FDynP) ! D_FDynP - END IF - Int_BufSz = Int_BufSz + 1 ! L_F_B allocated yes/no - IF ( ALLOCATED(InData%L_F_B) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! L_F_B upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%L_F_B) ! L_F_B - END IF - Int_BufSz = Int_BufSz + 1 ! L_F_D allocated yes/no - IF ( ALLOCATED(InData%L_F_D) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! L_F_D upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%L_F_D) ! L_F_D - END IF - Int_BufSz = Int_BufSz + 1 ! L_F_I allocated yes/no - IF ( ALLOCATED(InData%L_F_I) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! L_F_I upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%L_F_I) ! L_F_I - END IF - Int_BufSz = Int_BufSz + 1 ! L_F_DP allocated yes/no - IF ( ALLOCATED(InData%L_F_DP) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! L_F_DP upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%L_F_DP) ! L_F_DP - END IF - Int_BufSz = Int_BufSz + 1 ! L_F_AM allocated yes/no - IF ( ALLOCATED(InData%L_F_AM) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! L_F_AM upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%L_F_AM) ! L_F_AM - END IF - Int_BufSz = Int_BufSz + 1 ! L_FV allocated yes/no - IF ( ALLOCATED(InData%L_FV) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! L_FV upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%L_FV) ! L_FV - END IF - Int_BufSz = Int_BufSz + 1 ! L_FA allocated yes/no - IF ( ALLOCATED(InData%L_FA) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! L_FA upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%L_FA) ! L_FA - END IF - Int_BufSz = Int_BufSz + 1 ! L_FDynP allocated yes/no - IF ( ALLOCATED(InData%L_FDynP) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! L_FDynP upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%L_FDynP) ! L_FDynP + Int_BufSz = Int_BufSz + 1 ! FV allocated yes/no + IF ( ALLOCATED(InData%FV) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! FV upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%FV) ! FV + END IF + Int_BufSz = Int_BufSz + 1 ! FA allocated yes/no + IF ( ALLOCATED(InData%FA) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! FA upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%FA) ! FA + END IF + Int_BufSz = Int_BufSz + 1 ! FDynP allocated yes/no + IF ( ALLOCATED(InData%FDynP) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! FDynP upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%FDynP) ! FDynP + END IF + Int_BufSz = Int_BufSz + 1 ! vrel allocated yes/no + IF ( ALLOCATED(InData%vrel) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! vrel upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%vrel) ! vrel + END IF + Int_BufSz = Int_BufSz + 1 ! nodeInWater allocated yes/no + IF ( ALLOCATED(InData%nodeInWater) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! nodeInWater upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%nodeInWater) ! nodeInWater + END IF + Int_BufSz = Int_BufSz + 1 ! memberLoads allocated yes/no + IF ( ALLOCATED(InData%memberLoads) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! memberLoads upper/lower bounds for each dimension + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%memberLoads,1), UBOUND(InData%memberLoads,1) + Int_BufSz = Int_BufSz + 3 ! memberLoads: size of buffers for each call to pack subtype + CALL Morison_Packmemberloads( Re_Buf, Db_Buf, Int_Buf, InData%memberLoads(i1), ErrStat2, ErrMsg2, .TRUE. ) ! memberLoads + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! memberLoads + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! memberLoads + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! memberLoads + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! F_B_End allocated yes/no + IF ( ALLOCATED(InData%F_B_End) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_B_End upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_B_End) ! F_B_End + END IF + Int_BufSz = Int_BufSz + 1 ! F_D_End allocated yes/no + IF ( ALLOCATED(InData%F_D_End) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_D_End upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_D_End) ! F_D_End + END IF + Int_BufSz = Int_BufSz + 1 ! F_I_End allocated yes/no + IF ( ALLOCATED(InData%F_I_End) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_I_End upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_I_End) ! F_I_End + END IF + Int_BufSz = Int_BufSz + 1 ! F_IMG_End allocated yes/no + IF ( ALLOCATED(InData%F_IMG_End) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_IMG_End upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_IMG_End) ! F_IMG_End + END IF + Int_BufSz = Int_BufSz + 1 ! F_A_End allocated yes/no + IF ( ALLOCATED(InData%F_A_End) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_A_End upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_A_End) ! F_A_End + END IF + Int_BufSz = Int_BufSz + 1 ! F_BF_End allocated yes/no + IF ( ALLOCATED(InData%F_BF_End) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_BF_End upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_BF_End) ! F_BF_End END IF Int_BufSz = Int_BufSz + 1 ! LastIndWave IF ( Re_BufSz .GT. 0 ) THEN @@ -7040,365 +9282,266 @@ SUBROUTINE Morison_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg IF ( Int_BufSz .GT. 0 ) THEN ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IF ( .NOT. ALLOCATED(InData%D_F_D) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_D,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_D,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_D,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_D,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%D_F_D,2), UBOUND(InData%D_F_D,2) - DO i1 = LBOUND(InData%D_F_D,1), UBOUND(InData%D_F_D,1) - ReKiBuf(Re_Xferred) = InData%D_F_D(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%D_F_I) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_I,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_I,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_I,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_I,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%D_F_I,2), UBOUND(InData%D_F_I,2) - DO i1 = LBOUND(InData%D_F_I,1), UBOUND(InData%D_F_I,1) - ReKiBuf(Re_Xferred) = InData%D_F_I(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%D_F_B) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_B,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_B,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_B,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_B,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%D_F_B,2), UBOUND(InData%D_F_B,2) - DO i1 = LBOUND(InData%D_F_B,1), UBOUND(InData%D_F_B,1) - ReKiBuf(Re_Xferred) = InData%D_F_B(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF END IF - IF ( .NOT. ALLOCATED(InData%D_F_AM) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_AM,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_AM,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_AM,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_AM,2) - Int_Xferred = Int_Xferred + 2 + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - DO i2 = LBOUND(InData%D_F_AM,2), UBOUND(InData%D_F_AM,2) - DO i1 = LBOUND(InData%D_F_AM,1), UBOUND(InData%D_F_AM,1) - ReKiBuf(Re_Xferred) = InData%D_F_AM(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%D_F_AM_M) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_AM_M,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_AM_M,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_AM_M,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_AM_M,2) - Int_Xferred = Int_Xferred + 2 + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 - DO i2 = LBOUND(InData%D_F_AM_M,2), UBOUND(InData%D_F_AM_M,2) - DO i1 = LBOUND(InData%D_F_AM_M,1), UBOUND(InData%D_F_AM_M,1) - ReKiBuf(Re_Xferred) = InData%D_F_AM_M(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%D_F_AM_MG) ) THEN + IF ( .NOT. ALLOCATED(InData%FV) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_AM_MG,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_AM_MG,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%FV,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FV,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_AM_MG,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_AM_MG,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%FV,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FV,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%D_F_AM_MG,2), UBOUND(InData%D_F_AM_MG,2) - DO i1 = LBOUND(InData%D_F_AM_MG,1), UBOUND(InData%D_F_AM_MG,1) - ReKiBuf(Re_Xferred) = InData%D_F_AM_MG(i1,i2) + DO i2 = LBOUND(InData%FV,2), UBOUND(InData%FV,2) + DO i1 = LBOUND(InData%FV,1), UBOUND(InData%FV,1) + ReKiBuf(Re_Xferred) = InData%FV(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%D_F_AM_F) ) THEN + IF ( .NOT. ALLOCATED(InData%FA) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_AM_F,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_AM_F,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%FA,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FA,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_AM_F,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_AM_F,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%FA,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FA,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%D_F_AM_F,2), UBOUND(InData%D_F_AM_F,2) - DO i1 = LBOUND(InData%D_F_AM_F,1), UBOUND(InData%D_F_AM_F,1) - ReKiBuf(Re_Xferred) = InData%D_F_AM_F(i1,i2) + DO i2 = LBOUND(InData%FA,2), UBOUND(InData%FA,2) + DO i1 = LBOUND(InData%FA,1), UBOUND(InData%FA,1) + ReKiBuf(Re_Xferred) = InData%FA(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%D_FV) ) THEN + IF ( .NOT. ALLOCATED(InData%FDynP) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_FV,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_FV,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_FV,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_FV,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%FDynP,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FDynP,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%D_FV,2), UBOUND(InData%D_FV,2) - DO i1 = LBOUND(InData%D_FV,1), UBOUND(InData%D_FV,1) - ReKiBuf(Re_Xferred) = InData%D_FV(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(InData%FDynP,1), UBOUND(InData%FDynP,1) + ReKiBuf(Re_Xferred) = InData%FDynP(i1) + Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%D_FA) ) THEN + IF ( .NOT. ALLOCATED(InData%vrel) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_FA,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_FA,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%vrel,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vrel,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_FA,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_FA,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%vrel,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vrel,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%D_FA,2), UBOUND(InData%D_FA,2) - DO i1 = LBOUND(InData%D_FA,1), UBOUND(InData%D_FA,1) - ReKiBuf(Re_Xferred) = InData%D_FA(i1,i2) + DO i2 = LBOUND(InData%vrel,2), UBOUND(InData%vrel,2) + DO i1 = LBOUND(InData%vrel,1), UBOUND(InData%vrel,1) + ReKiBuf(Re_Xferred) = InData%vrel(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%D_FDynP) ) THEN + IF ( .NOT. ALLOCATED(InData%nodeInWater) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_FDynP,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_FDynP,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%nodeInWater,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nodeInWater,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%D_FDynP,1), UBOUND(InData%D_FDynP,1) - ReKiBuf(Re_Xferred) = InData%D_FDynP(i1) - Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%nodeInWater,1), UBOUND(InData%nodeInWater,1) + IntKiBuf(Int_Xferred) = InData%nodeInWater(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%L_F_B) ) THEN + IF ( .NOT. ALLOCATED(InData%memberLoads) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_B,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_B,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_B,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_B,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%memberLoads,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%memberLoads,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%L_F_B,2), UBOUND(InData%L_F_B,2) - DO i1 = LBOUND(InData%L_F_B,1), UBOUND(InData%L_F_B,1) - ReKiBuf(Re_Xferred) = InData%L_F_B(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + DO i1 = LBOUND(InData%memberLoads,1), UBOUND(InData%memberLoads,1) + CALL Morison_Packmemberloads( Re_Buf, Db_Buf, Int_Buf, InData%memberLoads(i1), ErrStat2, ErrMsg2, OnlySize ) ! memberLoads + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO END IF - IF ( .NOT. ALLOCATED(InData%L_F_D) ) THEN + IF ( .NOT. ALLOCATED(InData%F_B_End) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_D,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_D,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_B_End,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_B_End,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_D,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_D,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_B_End,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_B_End,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%L_F_D,2), UBOUND(InData%L_F_D,2) - DO i1 = LBOUND(InData%L_F_D,1), UBOUND(InData%L_F_D,1) - ReKiBuf(Re_Xferred) = InData%L_F_D(i1,i2) + DO i2 = LBOUND(InData%F_B_End,2), UBOUND(InData%F_B_End,2) + DO i1 = LBOUND(InData%F_B_End,1), UBOUND(InData%F_B_End,1) + ReKiBuf(Re_Xferred) = InData%F_B_End(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%L_F_I) ) THEN + IF ( .NOT. ALLOCATED(InData%F_D_End) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_I,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_I,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_D_End,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_D_End,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_I,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_I,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_D_End,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_D_End,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%L_F_I,2), UBOUND(InData%L_F_I,2) - DO i1 = LBOUND(InData%L_F_I,1), UBOUND(InData%L_F_I,1) - ReKiBuf(Re_Xferred) = InData%L_F_I(i1,i2) + DO i2 = LBOUND(InData%F_D_End,2), UBOUND(InData%F_D_End,2) + DO i1 = LBOUND(InData%F_D_End,1), UBOUND(InData%F_D_End,1) + ReKiBuf(Re_Xferred) = InData%F_D_End(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%L_F_DP) ) THEN + IF ( .NOT. ALLOCATED(InData%F_I_End) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_DP,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_DP,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_I_End,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_I_End,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_DP,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_DP,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_I_End,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_I_End,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%L_F_DP,2), UBOUND(InData%L_F_DP,2) - DO i1 = LBOUND(InData%L_F_DP,1), UBOUND(InData%L_F_DP,1) - ReKiBuf(Re_Xferred) = InData%L_F_DP(i1,i2) + DO i2 = LBOUND(InData%F_I_End,2), UBOUND(InData%F_I_End,2) + DO i1 = LBOUND(InData%F_I_End,1), UBOUND(InData%F_I_End,1) + ReKiBuf(Re_Xferred) = InData%F_I_End(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%L_F_AM) ) THEN + IF ( .NOT. ALLOCATED(InData%F_IMG_End) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_AM,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_AM,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_IMG_End,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_IMG_End,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_AM,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_AM,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_IMG_End,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_IMG_End,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%L_F_AM,2), UBOUND(InData%L_F_AM,2) - DO i1 = LBOUND(InData%L_F_AM,1), UBOUND(InData%L_F_AM,1) - ReKiBuf(Re_Xferred) = InData%L_F_AM(i1,i2) + DO i2 = LBOUND(InData%F_IMG_End,2), UBOUND(InData%F_IMG_End,2) + DO i1 = LBOUND(InData%F_IMG_End,1), UBOUND(InData%F_IMG_End,1) + ReKiBuf(Re_Xferred) = InData%F_IMG_End(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%L_FV) ) THEN + IF ( .NOT. ALLOCATED(InData%F_A_End) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_FV,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_FV,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_A_End,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_A_End,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_FV,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_FV,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_A_End,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_A_End,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%L_FV,2), UBOUND(InData%L_FV,2) - DO i1 = LBOUND(InData%L_FV,1), UBOUND(InData%L_FV,1) - ReKiBuf(Re_Xferred) = InData%L_FV(i1,i2) + DO i2 = LBOUND(InData%F_A_End,2), UBOUND(InData%F_A_End,2) + DO i1 = LBOUND(InData%F_A_End,1), UBOUND(InData%F_A_End,1) + ReKiBuf(Re_Xferred) = InData%F_A_End(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%L_FA) ) THEN + IF ( .NOT. ALLOCATED(InData%F_BF_End) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_FA,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_FA,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_BF_End,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_BF_End,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_FA,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_FA,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_BF_End,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_BF_End,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%L_FA,2), UBOUND(InData%L_FA,2) - DO i1 = LBOUND(InData%L_FA,1), UBOUND(InData%L_FA,1) - ReKiBuf(Re_Xferred) = InData%L_FA(i1,i2) + DO i2 = LBOUND(InData%F_BF_End,2), UBOUND(InData%F_BF_End,2) + DO i1 = LBOUND(InData%F_BF_End,1), UBOUND(InData%F_BF_End,1) + ReKiBuf(Re_Xferred) = InData%F_BF_End(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO - END IF - IF ( .NOT. ALLOCATED(InData%L_FDynP) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_FDynP,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_FDynP,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%L_FDynP,1), UBOUND(InData%L_FDynP,1) - ReKiBuf(Re_Xferred) = InData%L_FDynP(i1) - Re_Xferred = Re_Xferred + 1 - END DO END IF IntKiBuf(Int_Xferred) = InData%LastIndWave Int_Xferred = Int_Xferred + 1 @@ -7432,76 +9575,7 @@ SUBROUTINE Morison_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_F_D not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_F_D)) DEALLOCATE(OutData%D_F_D) - ALLOCATE(OutData%D_F_D(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_F_D.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%D_F_D,2), UBOUND(OutData%D_F_D,2) - DO i1 = LBOUND(OutData%D_F_D,1), UBOUND(OutData%D_F_D,1) - OutData%D_F_D(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_F_I not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_F_I)) DEALLOCATE(OutData%D_F_I) - ALLOCATE(OutData%D_F_I(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_F_I.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%D_F_I,2), UBOUND(OutData%D_F_I,2) - DO i1 = LBOUND(OutData%D_F_I,1), UBOUND(OutData%D_F_I,1) - OutData%D_F_I(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_F_B not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_F_B)) DEALLOCATE(OutData%D_F_B) - ALLOCATE(OutData%D_F_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_F_B.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%D_F_B,2), UBOUND(OutData%D_F_B,2) - DO i1 = LBOUND(OutData%D_F_B,1), UBOUND(OutData%D_F_B,1) - OutData%D_F_B(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_F_AM not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FV not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -7511,20 +9585,20 @@ SUBROUTINE Morison_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_F_AM)) DEALLOCATE(OutData%D_F_AM) - ALLOCATE(OutData%D_F_AM(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%FV)) DEALLOCATE(OutData%FV) + ALLOCATE(OutData%FV(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_F_AM.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FV.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%D_F_AM,2), UBOUND(OutData%D_F_AM,2) - DO i1 = LBOUND(OutData%D_F_AM,1), UBOUND(OutData%D_F_AM,1) - OutData%D_F_AM(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%FV,2), UBOUND(OutData%FV,2) + DO i1 = LBOUND(OutData%FV,1), UBOUND(OutData%FV,1) + OutData%FV(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_F_AM_M not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FA not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -7534,89 +9608,38 @@ SUBROUTINE Morison_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_F_AM_M)) DEALLOCATE(OutData%D_F_AM_M) - ALLOCATE(OutData%D_F_AM_M(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%FA)) DEALLOCATE(OutData%FA) + ALLOCATE(OutData%FA(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_F_AM_M.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FA.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%D_F_AM_M,2), UBOUND(OutData%D_F_AM_M,2) - DO i1 = LBOUND(OutData%D_F_AM_M,1), UBOUND(OutData%D_F_AM_M,1) - OutData%D_F_AM_M(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%FA,2), UBOUND(OutData%FA,2) + DO i1 = LBOUND(OutData%FA,1), UBOUND(OutData%FA,1) + OutData%FA(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_F_AM_MG not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FDynP not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_F_AM_MG)) DEALLOCATE(OutData%D_F_AM_MG) - ALLOCATE(OutData%D_F_AM_MG(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_F_AM_MG.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%D_F_AM_MG,2), UBOUND(OutData%D_F_AM_MG,2) - DO i1 = LBOUND(OutData%D_F_AM_MG,1), UBOUND(OutData%D_F_AM_MG,1) - OutData%D_F_AM_MG(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_F_AM_F not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_F_AM_F)) DEALLOCATE(OutData%D_F_AM_F) - ALLOCATE(OutData%D_F_AM_F(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_F_AM_F.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%D_F_AM_F,2), UBOUND(OutData%D_F_AM_F,2) - DO i1 = LBOUND(OutData%D_F_AM_F,1), UBOUND(OutData%D_F_AM_F,1) - OutData%D_F_AM_F(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_FV not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_FV)) DEALLOCATE(OutData%D_FV) - ALLOCATE(OutData%D_FV(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%FDynP)) DEALLOCATE(OutData%FDynP) + ALLOCATE(OutData%FDynP(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_FV.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FDynP.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%D_FV,2), UBOUND(OutData%D_FV,2) - DO i1 = LBOUND(OutData%D_FV,1), UBOUND(OutData%D_FV,1) - OutData%D_FV(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(OutData%FDynP,1), UBOUND(OutData%FDynP,1) + OutData%FDynP(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_FA not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! vrel not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -7626,61 +9649,94 @@ SUBROUTINE Morison_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_FA)) DEALLOCATE(OutData%D_FA) - ALLOCATE(OutData%D_FA(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%vrel)) DEALLOCATE(OutData%vrel) + ALLOCATE(OutData%vrel(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_FA.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%vrel.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%D_FA,2), UBOUND(OutData%D_FA,2) - DO i1 = LBOUND(OutData%D_FA,1), UBOUND(OutData%D_FA,1) - OutData%D_FA(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%vrel,2), UBOUND(OutData%vrel,2) + DO i1 = LBOUND(OutData%vrel,1), UBOUND(OutData%vrel,1) + OutData%vrel(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_FDynP not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nodeInWater not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_FDynP)) DEALLOCATE(OutData%D_FDynP) - ALLOCATE(OutData%D_FDynP(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%nodeInWater)) DEALLOCATE(OutData%nodeInWater) + ALLOCATE(OutData%nodeInWater(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_FDynP.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nodeInWater.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%D_FDynP,1), UBOUND(OutData%D_FDynP,1) - OutData%D_FDynP(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(OutData%nodeInWater,1), UBOUND(OutData%nodeInWater,1) + OutData%nodeInWater(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! L_F_B not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! memberLoads not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%L_F_B)) DEALLOCATE(OutData%L_F_B) - ALLOCATE(OutData%L_F_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%memberLoads)) DEALLOCATE(OutData%memberLoads) + ALLOCATE(OutData%memberLoads(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%L_F_B.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%memberLoads.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%L_F_B,2), UBOUND(OutData%L_F_B,2) - DO i1 = LBOUND(OutData%L_F_B,1), UBOUND(OutData%L_F_B,1) - OutData%L_F_B(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + DO i1 = LBOUND(OutData%memberLoads,1), UBOUND(OutData%memberLoads,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL Morison_Unpackmemberloads( Re_Buf, Db_Buf, Int_Buf, OutData%memberLoads(i1), ErrStat2, ErrMsg2 ) ! memberLoads + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! L_F_D not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_B_End not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -7690,20 +9746,20 @@ SUBROUTINE Morison_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%L_F_D)) DEALLOCATE(OutData%L_F_D) - ALLOCATE(OutData%L_F_D(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%F_B_End)) DEALLOCATE(OutData%F_B_End) + ALLOCATE(OutData%F_B_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%L_F_D.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_B_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%L_F_D,2), UBOUND(OutData%L_F_D,2) - DO i1 = LBOUND(OutData%L_F_D,1), UBOUND(OutData%L_F_D,1) - OutData%L_F_D(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%F_B_End,2), UBOUND(OutData%F_B_End,2) + DO i1 = LBOUND(OutData%F_B_End,1), UBOUND(OutData%F_B_End,1) + OutData%F_B_End(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! L_F_I not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_D_End not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -7713,20 +9769,20 @@ SUBROUTINE Morison_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%L_F_I)) DEALLOCATE(OutData%L_F_I) - ALLOCATE(OutData%L_F_I(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%F_D_End)) DEALLOCATE(OutData%F_D_End) + ALLOCATE(OutData%F_D_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%L_F_I.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_D_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%L_F_I,2), UBOUND(OutData%L_F_I,2) - DO i1 = LBOUND(OutData%L_F_I,1), UBOUND(OutData%L_F_I,1) - OutData%L_F_I(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%F_D_End,2), UBOUND(OutData%F_D_End,2) + DO i1 = LBOUND(OutData%F_D_End,1), UBOUND(OutData%F_D_End,1) + OutData%F_D_End(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! L_F_DP not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_I_End not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -7736,20 +9792,20 @@ SUBROUTINE Morison_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%L_F_DP)) DEALLOCATE(OutData%L_F_DP) - ALLOCATE(OutData%L_F_DP(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%F_I_End)) DEALLOCATE(OutData%F_I_End) + ALLOCATE(OutData%F_I_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%L_F_DP.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_I_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%L_F_DP,2), UBOUND(OutData%L_F_DP,2) - DO i1 = LBOUND(OutData%L_F_DP,1), UBOUND(OutData%L_F_DP,1) - OutData%L_F_DP(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%F_I_End,2), UBOUND(OutData%F_I_End,2) + DO i1 = LBOUND(OutData%F_I_End,1), UBOUND(OutData%F_I_End,1) + OutData%F_I_End(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! L_F_AM not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_IMG_End not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -7759,20 +9815,20 @@ SUBROUTINE Morison_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%L_F_AM)) DEALLOCATE(OutData%L_F_AM) - ALLOCATE(OutData%L_F_AM(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%F_IMG_End)) DEALLOCATE(OutData%F_IMG_End) + ALLOCATE(OutData%F_IMG_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%L_F_AM.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_IMG_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%L_F_AM,2), UBOUND(OutData%L_F_AM,2) - DO i1 = LBOUND(OutData%L_F_AM,1), UBOUND(OutData%L_F_AM,1) - OutData%L_F_AM(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%F_IMG_End,2), UBOUND(OutData%F_IMG_End,2) + DO i1 = LBOUND(OutData%F_IMG_End,1), UBOUND(OutData%F_IMG_End,1) + OutData%F_IMG_End(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! L_FV not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_A_End not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -7782,20 +9838,20 @@ SUBROUTINE Morison_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%L_FV)) DEALLOCATE(OutData%L_FV) - ALLOCATE(OutData%L_FV(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%F_A_End)) DEALLOCATE(OutData%F_A_End) + ALLOCATE(OutData%F_A_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%L_FV.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_A_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%L_FV,2), UBOUND(OutData%L_FV,2) - DO i1 = LBOUND(OutData%L_FV,1), UBOUND(OutData%L_FV,1) - OutData%L_FV(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%F_A_End,2), UBOUND(OutData%F_A_End,2) + DO i1 = LBOUND(OutData%F_A_End,1), UBOUND(OutData%F_A_End,1) + OutData%F_A_End(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! L_FA not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_BF_End not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -7805,36 +9861,18 @@ SUBROUTINE Morison_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%L_FA)) DEALLOCATE(OutData%L_FA) - ALLOCATE(OutData%L_FA(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%F_BF_End)) DEALLOCATE(OutData%F_BF_End) + ALLOCATE(OutData%F_BF_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%L_FA.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_BF_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%L_FA,2), UBOUND(OutData%L_FA,2) - DO i1 = LBOUND(OutData%L_FA,1), UBOUND(OutData%L_FA,1) - OutData%L_FA(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%F_BF_End,2), UBOUND(OutData%F_BF_End,2) + DO i1 = LBOUND(OutData%F_BF_End,1), UBOUND(OutData%F_BF_End,1) + OutData%F_BF_End(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! L_FDynP not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%L_FDynP)) DEALLOCATE(OutData%L_FDynP) - ALLOCATE(OutData%L_FDynP(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%L_FDynP.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%L_FDynP,1), UBOUND(OutData%L_FDynP,1) - OutData%L_FDynP(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO END IF OutData%LastIndWave = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 @@ -7858,195 +9896,125 @@ SUBROUTINE Morison_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, Err ErrStat = ErrID_None ErrMsg = "" DstParamData%DT = SrcParamData%DT + DstParamData%Gravity = SrcParamData%Gravity DstParamData%WtrDens = SrcParamData%WtrDens - DstParamData%NNodes = SrcParamData%NNodes -IF (ALLOCATED(SrcParamData%Nodes)) THEN - i1_l = LBOUND(SrcParamData%Nodes,1) - i1_u = UBOUND(SrcParamData%Nodes,1) - IF (.NOT. ALLOCATED(DstParamData%Nodes)) THEN - ALLOCATE(DstParamData%Nodes(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%Nodes.', ErrStat, ErrMsg,RoutineName) + DstParamData%WtrDpth = SrcParamData%WtrDpth + DstParamData%NMembers = SrcParamData%NMembers +IF (ALLOCATED(SrcParamData%Members)) THEN + i1_l = LBOUND(SrcParamData%Members,1) + i1_u = UBOUND(SrcParamData%Members,1) + IF (.NOT. ALLOCATED(DstParamData%Members)) THEN + ALLOCATE(DstParamData%Members(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%Members.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcParamData%Nodes,1), UBOUND(SrcParamData%Nodes,1) - CALL Morison_Copynodetype( SrcParamData%Nodes(i1), DstParamData%Nodes(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcParamData%Members,1), UBOUND(SrcParamData%Members,1) + CALL Morison_Copymembertype( SrcParamData%Members(i1), DstParamData%Members(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF -IF (ALLOCATED(SrcParamData%D_F_I)) THEN - i1_l = LBOUND(SrcParamData%D_F_I,1) - i1_u = UBOUND(SrcParamData%D_F_I,1) - i2_l = LBOUND(SrcParamData%D_F_I,2) - i2_u = UBOUND(SrcParamData%D_F_I,2) - i3_l = LBOUND(SrcParamData%D_F_I,3) - i3_u = UBOUND(SrcParamData%D_F_I,3) - IF (.NOT. ALLOCATED(DstParamData%D_F_I)) THEN - ALLOCATE(DstParamData%D_F_I(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%D_F_I.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%D_F_I = SrcParamData%D_F_I -ENDIF -IF (ALLOCATED(SrcParamData%D_F_DP)) THEN - i1_l = LBOUND(SrcParamData%D_F_DP,1) - i1_u = UBOUND(SrcParamData%D_F_DP,1) - i2_l = LBOUND(SrcParamData%D_F_DP,2) - i2_u = UBOUND(SrcParamData%D_F_DP,2) - i3_l = LBOUND(SrcParamData%D_F_DP,3) - i3_u = UBOUND(SrcParamData%D_F_DP,3) - IF (.NOT. ALLOCATED(DstParamData%D_F_DP)) THEN - ALLOCATE(DstParamData%D_F_DP(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%D_F_DP.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%D_F_DP = SrcParamData%D_F_DP -ENDIF -IF (ALLOCATED(SrcParamData%D_dragConst)) THEN - i1_l = LBOUND(SrcParamData%D_dragConst,1) - i1_u = UBOUND(SrcParamData%D_dragConst,1) - IF (.NOT. ALLOCATED(DstParamData%D_dragConst)) THEN - ALLOCATE(DstParamData%D_dragConst(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%D_dragConst.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%D_dragConst = SrcParamData%D_dragConst -ENDIF -IF (ALLOCATED(SrcParamData%L_An)) THEN - i1_l = LBOUND(SrcParamData%L_An,1) - i1_u = UBOUND(SrcParamData%L_An,1) - i2_l = LBOUND(SrcParamData%L_An,2) - i2_u = UBOUND(SrcParamData%L_An,2) - IF (.NOT. ALLOCATED(DstParamData%L_An)) THEN - ALLOCATE(DstParamData%L_An(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%L_An.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%L_An = SrcParamData%L_An -ENDIF -IF (ALLOCATED(SrcParamData%L_F_B)) THEN - i1_l = LBOUND(SrcParamData%L_F_B,1) - i1_u = UBOUND(SrcParamData%L_F_B,1) - i2_l = LBOUND(SrcParamData%L_F_B,2) - i2_u = UBOUND(SrcParamData%L_F_B,2) - IF (.NOT. ALLOCATED(DstParamData%L_F_B)) THEN - ALLOCATE(DstParamData%L_F_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%L_F_B.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%L_F_B = SrcParamData%L_F_B + ENDDO ENDIF -IF (ALLOCATED(SrcParamData%L_F_I)) THEN - i1_l = LBOUND(SrcParamData%L_F_I,1) - i1_u = UBOUND(SrcParamData%L_F_I,1) - i2_l = LBOUND(SrcParamData%L_F_I,2) - i2_u = UBOUND(SrcParamData%L_F_I,2) - i3_l = LBOUND(SrcParamData%L_F_I,3) - i3_u = UBOUND(SrcParamData%L_F_I,3) - IF (.NOT. ALLOCATED(DstParamData%L_F_I)) THEN - ALLOCATE(DstParamData%L_F_I(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%L_F_I.', ErrStat, ErrMsg,RoutineName) + DstParamData%NNodes = SrcParamData%NNodes + DstParamData%NJoints = SrcParamData%NJoints +IF (ALLOCATED(SrcParamData%I_MG_End)) THEN + i1_l = LBOUND(SrcParamData%I_MG_End,1) + i1_u = UBOUND(SrcParamData%I_MG_End,1) + i2_l = LBOUND(SrcParamData%I_MG_End,2) + i2_u = UBOUND(SrcParamData%I_MG_End,2) + i3_l = LBOUND(SrcParamData%I_MG_End,3) + i3_u = UBOUND(SrcParamData%I_MG_End,3) + IF (.NOT. ALLOCATED(DstParamData%I_MG_End)) THEN + ALLOCATE(DstParamData%I_MG_End(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%I_MG_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%L_F_I = SrcParamData%L_F_I + DstParamData%I_MG_End = SrcParamData%I_MG_End ENDIF -IF (ALLOCATED(SrcParamData%L_F_DP)) THEN - i1_l = LBOUND(SrcParamData%L_F_DP,1) - i1_u = UBOUND(SrcParamData%L_F_DP,1) - i2_l = LBOUND(SrcParamData%L_F_DP,2) - i2_u = UBOUND(SrcParamData%L_F_DP,2) - i3_l = LBOUND(SrcParamData%L_F_DP,3) - i3_u = UBOUND(SrcParamData%L_F_DP,3) - IF (.NOT. ALLOCATED(DstParamData%L_F_DP)) THEN - ALLOCATE(DstParamData%L_F_DP(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%An_End)) THEN + i1_l = LBOUND(SrcParamData%An_End,1) + i1_u = UBOUND(SrcParamData%An_End,1) + i2_l = LBOUND(SrcParamData%An_End,2) + i2_u = UBOUND(SrcParamData%An_End,2) + IF (.NOT. ALLOCATED(DstParamData%An_End)) THEN + ALLOCATE(DstParamData%An_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%L_F_DP.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%An_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%L_F_DP = SrcParamData%L_F_DP + DstParamData%An_End = SrcParamData%An_End ENDIF -IF (ALLOCATED(SrcParamData%L_F_BF)) THEN - i1_l = LBOUND(SrcParamData%L_F_BF,1) - i1_u = UBOUND(SrcParamData%L_F_BF,1) - i2_l = LBOUND(SrcParamData%L_F_BF,2) - i2_u = UBOUND(SrcParamData%L_F_BF,2) - IF (.NOT. ALLOCATED(DstParamData%L_F_BF)) THEN - ALLOCATE(DstParamData%L_F_BF(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%DragConst_End)) THEN + i1_l = LBOUND(SrcParamData%DragConst_End,1) + i1_u = UBOUND(SrcParamData%DragConst_End,1) + IF (.NOT. ALLOCATED(DstParamData%DragConst_End)) THEN + ALLOCATE(DstParamData%DragConst_End(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%L_F_BF.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%DragConst_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%L_F_BF = SrcParamData%L_F_BF + DstParamData%DragConst_End = SrcParamData%DragConst_End ENDIF -IF (ALLOCATED(SrcParamData%L_AM_M)) THEN - i1_l = LBOUND(SrcParamData%L_AM_M,1) - i1_u = UBOUND(SrcParamData%L_AM_M,1) - i2_l = LBOUND(SrcParamData%L_AM_M,2) - i2_u = UBOUND(SrcParamData%L_AM_M,2) - i3_l = LBOUND(SrcParamData%L_AM_M,3) - i3_u = UBOUND(SrcParamData%L_AM_M,3) - IF (.NOT. ALLOCATED(DstParamData%L_AM_M)) THEN - ALLOCATE(DstParamData%L_AM_M(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%F_WMG_End)) THEN + i1_l = LBOUND(SrcParamData%F_WMG_End,1) + i1_u = UBOUND(SrcParamData%F_WMG_End,1) + i2_l = LBOUND(SrcParamData%F_WMG_End,2) + i2_u = UBOUND(SrcParamData%F_WMG_End,2) + IF (.NOT. ALLOCATED(DstParamData%F_WMG_End)) THEN + ALLOCATE(DstParamData%F_WMG_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%L_AM_M.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%F_WMG_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%L_AM_M = SrcParamData%L_AM_M + DstParamData%F_WMG_End = SrcParamData%F_WMG_End ENDIF -IF (ALLOCATED(SrcParamData%L_dragConst)) THEN - i1_l = LBOUND(SrcParamData%L_dragConst,1) - i1_u = UBOUND(SrcParamData%L_dragConst,1) - IF (.NOT. ALLOCATED(DstParamData%L_dragConst)) THEN - ALLOCATE(DstParamData%L_dragConst(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%DP_Const_End)) THEN + i1_l = LBOUND(SrcParamData%DP_Const_End,1) + i1_u = UBOUND(SrcParamData%DP_Const_End,1) + i2_l = LBOUND(SrcParamData%DP_Const_End,2) + i2_u = UBOUND(SrcParamData%DP_Const_End,2) + IF (.NOT. ALLOCATED(DstParamData%DP_Const_End)) THEN + ALLOCATE(DstParamData%DP_Const_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%L_dragConst.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%DP_Const_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%L_dragConst = SrcParamData%L_dragConst + DstParamData%DP_Const_End = SrcParamData%DP_Const_End ENDIF - DstParamData%NDistribMarkers = SrcParamData%NDistribMarkers -IF (ALLOCATED(SrcParamData%distribToNodeIndx)) THEN - i1_l = LBOUND(SrcParamData%distribToNodeIndx,1) - i1_u = UBOUND(SrcParamData%distribToNodeIndx,1) - IF (.NOT. ALLOCATED(DstParamData%distribToNodeIndx)) THEN - ALLOCATE(DstParamData%distribToNodeIndx(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%Mass_MG_End)) THEN + i1_l = LBOUND(SrcParamData%Mass_MG_End,1) + i1_u = UBOUND(SrcParamData%Mass_MG_End,1) + IF (.NOT. ALLOCATED(DstParamData%Mass_MG_End)) THEN + ALLOCATE(DstParamData%Mass_MG_End(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%distribToNodeIndx.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%Mass_MG_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%distribToNodeIndx = SrcParamData%distribToNodeIndx + DstParamData%Mass_MG_End = SrcParamData%Mass_MG_End ENDIF - DstParamData%NLumpedMarkers = SrcParamData%NLumpedMarkers -IF (ALLOCATED(SrcParamData%lumpedToNodeIndx)) THEN - i1_l = LBOUND(SrcParamData%lumpedToNodeIndx,1) - i1_u = UBOUND(SrcParamData%lumpedToNodeIndx,1) - IF (.NOT. ALLOCATED(DstParamData%lumpedToNodeIndx)) THEN - ALLOCATE(DstParamData%lumpedToNodeIndx(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%AM_End)) THEN + i1_l = LBOUND(SrcParamData%AM_End,1) + i1_u = UBOUND(SrcParamData%AM_End,1) + i2_l = LBOUND(SrcParamData%AM_End,2) + i2_u = UBOUND(SrcParamData%AM_End,2) + i3_l = LBOUND(SrcParamData%AM_End,3) + i3_u = UBOUND(SrcParamData%AM_End,3) + IF (.NOT. ALLOCATED(DstParamData%AM_End)) THEN + ALLOCATE(DstParamData%AM_End(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%lumpedToNodeIndx.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%AM_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%lumpedToNodeIndx = SrcParamData%lumpedToNodeIndx + DstParamData%AM_End = SrcParamData%AM_End ENDIF IF (ALLOCATED(SrcParamData%WaveVel)) THEN i1_l = LBOUND(SrcParamData%WaveVel,1) @@ -8106,32 +10074,6 @@ SUBROUTINE Morison_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, Err END IF DstParamData%WaveTime = SrcParamData%WaveTime ENDIF -IF (ALLOCATED(SrcParamData%elementWaterState)) THEN - i1_l = LBOUND(SrcParamData%elementWaterState,1) - i1_u = UBOUND(SrcParamData%elementWaterState,1) - i2_l = LBOUND(SrcParamData%elementWaterState,2) - i2_u = UBOUND(SrcParamData%elementWaterState,2) - IF (.NOT. ALLOCATED(DstParamData%elementWaterState)) THEN - ALLOCATE(DstParamData%elementWaterState(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%elementWaterState.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%elementWaterState = SrcParamData%elementWaterState -ENDIF -IF (ALLOCATED(SrcParamData%elementFillState)) THEN - i1_l = LBOUND(SrcParamData%elementFillState,1) - i1_u = UBOUND(SrcParamData%elementFillState,1) - IF (.NOT. ALLOCATED(DstParamData%elementFillState)) THEN - ALLOCATE(DstParamData%elementFillState(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%elementFillState.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%elementFillState = SrcParamData%elementFillState -ENDIF IF (ALLOCATED(SrcParamData%nodeInWater)) THEN i1_l = LBOUND(SrcParamData%nodeInWater,1) i1_u = UBOUND(SrcParamData%nodeInWater,1) @@ -8145,88 +10087,6 @@ SUBROUTINE Morison_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, Err END IF END IF DstParamData%nodeInWater = SrcParamData%nodeInWater -ENDIF -IF (ALLOCATED(SrcParamData%D_F_B)) THEN - i1_l = LBOUND(SrcParamData%D_F_B,1) - i1_u = UBOUND(SrcParamData%D_F_B,1) - i2_l = LBOUND(SrcParamData%D_F_B,2) - i2_u = UBOUND(SrcParamData%D_F_B,2) - IF (.NOT. ALLOCATED(DstParamData%D_F_B)) THEN - ALLOCATE(DstParamData%D_F_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%D_F_B.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%D_F_B = SrcParamData%D_F_B -ENDIF -IF (ALLOCATED(SrcParamData%D_F_BF)) THEN - i1_l = LBOUND(SrcParamData%D_F_BF,1) - i1_u = UBOUND(SrcParamData%D_F_BF,1) - i2_l = LBOUND(SrcParamData%D_F_BF,2) - i2_u = UBOUND(SrcParamData%D_F_BF,2) - IF (.NOT. ALLOCATED(DstParamData%D_F_BF)) THEN - ALLOCATE(DstParamData%D_F_BF(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%D_F_BF.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%D_F_BF = SrcParamData%D_F_BF -ENDIF -IF (ALLOCATED(SrcParamData%D_F_MG)) THEN - i1_l = LBOUND(SrcParamData%D_F_MG,1) - i1_u = UBOUND(SrcParamData%D_F_MG,1) - i2_l = LBOUND(SrcParamData%D_F_MG,2) - i2_u = UBOUND(SrcParamData%D_F_MG,2) - IF (.NOT. ALLOCATED(DstParamData%D_F_MG)) THEN - ALLOCATE(DstParamData%D_F_MG(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%D_F_MG.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%D_F_MG = SrcParamData%D_F_MG -ENDIF -IF (ALLOCATED(SrcParamData%D_AM_M)) THEN - i1_l = LBOUND(SrcParamData%D_AM_M,1) - i1_u = UBOUND(SrcParamData%D_AM_M,1) - i2_l = LBOUND(SrcParamData%D_AM_M,2) - i2_u = UBOUND(SrcParamData%D_AM_M,2) - i3_l = LBOUND(SrcParamData%D_AM_M,3) - i3_u = UBOUND(SrcParamData%D_AM_M,3) - IF (.NOT. ALLOCATED(DstParamData%D_AM_M)) THEN - ALLOCATE(DstParamData%D_AM_M(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%D_AM_M.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%D_AM_M = SrcParamData%D_AM_M -ENDIF -IF (ALLOCATED(SrcParamData%D_AM_MG)) THEN - i1_l = LBOUND(SrcParamData%D_AM_MG,1) - i1_u = UBOUND(SrcParamData%D_AM_MG,1) - IF (.NOT. ALLOCATED(DstParamData%D_AM_MG)) THEN - ALLOCATE(DstParamData%D_AM_MG(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%D_AM_MG.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%D_AM_MG = SrcParamData%D_AM_MG -ENDIF -IF (ALLOCATED(SrcParamData%D_AM_F)) THEN - i1_l = LBOUND(SrcParamData%D_AM_F,1) - i1_u = UBOUND(SrcParamData%D_AM_F,1) - IF (.NOT. ALLOCATED(DstParamData%D_AM_F)) THEN - ALLOCATE(DstParamData%D_AM_F(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%D_AM_F.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%D_AM_F = SrcParamData%D_AM_F ENDIF DstParamData%NStepWave = SrcParamData%NStepWave DstParamData%NMOutputs = SrcParamData%NMOutputs @@ -8297,47 +10157,32 @@ SUBROUTINE Morison_DestroyParam( ParamData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(ParamData%Nodes)) THEN -DO i1 = LBOUND(ParamData%Nodes,1), UBOUND(ParamData%Nodes,1) - CALL Morison_Destroynodetype( ParamData%Nodes(i1), ErrStat, ErrMsg ) +IF (ALLOCATED(ParamData%Members)) THEN +DO i1 = LBOUND(ParamData%Members,1), UBOUND(ParamData%Members,1) + CALL Morison_Destroymembertype( ParamData%Members(i1), ErrStat, ErrMsg ) ENDDO - DEALLOCATE(ParamData%Nodes) -ENDIF -IF (ALLOCATED(ParamData%D_F_I)) THEN - DEALLOCATE(ParamData%D_F_I) -ENDIF -IF (ALLOCATED(ParamData%D_F_DP)) THEN - DEALLOCATE(ParamData%D_F_DP) -ENDIF -IF (ALLOCATED(ParamData%D_dragConst)) THEN - DEALLOCATE(ParamData%D_dragConst) -ENDIF -IF (ALLOCATED(ParamData%L_An)) THEN - DEALLOCATE(ParamData%L_An) -ENDIF -IF (ALLOCATED(ParamData%L_F_B)) THEN - DEALLOCATE(ParamData%L_F_B) + DEALLOCATE(ParamData%Members) ENDIF -IF (ALLOCATED(ParamData%L_F_I)) THEN - DEALLOCATE(ParamData%L_F_I) +IF (ALLOCATED(ParamData%I_MG_End)) THEN + DEALLOCATE(ParamData%I_MG_End) ENDIF -IF (ALLOCATED(ParamData%L_F_DP)) THEN - DEALLOCATE(ParamData%L_F_DP) +IF (ALLOCATED(ParamData%An_End)) THEN + DEALLOCATE(ParamData%An_End) ENDIF -IF (ALLOCATED(ParamData%L_F_BF)) THEN - DEALLOCATE(ParamData%L_F_BF) +IF (ALLOCATED(ParamData%DragConst_End)) THEN + DEALLOCATE(ParamData%DragConst_End) ENDIF -IF (ALLOCATED(ParamData%L_AM_M)) THEN - DEALLOCATE(ParamData%L_AM_M) +IF (ALLOCATED(ParamData%F_WMG_End)) THEN + DEALLOCATE(ParamData%F_WMG_End) ENDIF -IF (ALLOCATED(ParamData%L_dragConst)) THEN - DEALLOCATE(ParamData%L_dragConst) +IF (ALLOCATED(ParamData%DP_Const_End)) THEN + DEALLOCATE(ParamData%DP_Const_End) ENDIF -IF (ALLOCATED(ParamData%distribToNodeIndx)) THEN - DEALLOCATE(ParamData%distribToNodeIndx) +IF (ALLOCATED(ParamData%Mass_MG_End)) THEN + DEALLOCATE(ParamData%Mass_MG_End) ENDIF -IF (ALLOCATED(ParamData%lumpedToNodeIndx)) THEN - DEALLOCATE(ParamData%lumpedToNodeIndx) +IF (ALLOCATED(ParamData%AM_End)) THEN + DEALLOCATE(ParamData%AM_End) ENDIF IF (ALLOCATED(ParamData%WaveVel)) THEN DEALLOCATE(ParamData%WaveVel) @@ -8351,33 +10196,9 @@ SUBROUTINE Morison_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%WaveTime)) THEN DEALLOCATE(ParamData%WaveTime) ENDIF -IF (ALLOCATED(ParamData%elementWaterState)) THEN - DEALLOCATE(ParamData%elementWaterState) -ENDIF -IF (ALLOCATED(ParamData%elementFillState)) THEN - DEALLOCATE(ParamData%elementFillState) -ENDIF IF (ALLOCATED(ParamData%nodeInWater)) THEN DEALLOCATE(ParamData%nodeInWater) ENDIF -IF (ALLOCATED(ParamData%D_F_B)) THEN - DEALLOCATE(ParamData%D_F_B) -ENDIF -IF (ALLOCATED(ParamData%D_F_BF)) THEN - DEALLOCATE(ParamData%D_F_BF) -ENDIF -IF (ALLOCATED(ParamData%D_F_MG)) THEN - DEALLOCATE(ParamData%D_F_MG) -ENDIF -IF (ALLOCATED(ParamData%D_AM_M)) THEN - DEALLOCATE(ParamData%D_AM_M) -ENDIF -IF (ALLOCATED(ParamData%D_AM_MG)) THEN - DEALLOCATE(ParamData%D_AM_MG) -ENDIF -IF (ALLOCATED(ParamData%D_AM_F)) THEN - DEALLOCATE(ParamData%D_AM_F) -ENDIF IF (ALLOCATED(ParamData%MOutLst)) THEN DO i1 = LBOUND(ParamData%MOutLst,1), UBOUND(ParamData%MOutLst,1) CALL Morison_Destroymoutput( ParamData%MOutLst(i1), ErrStat, ErrMsg ) @@ -8434,93 +10255,70 @@ SUBROUTINE Morison_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_BufSz = 0 Int_BufSz = 0 Db_BufSz = Db_BufSz + 1 ! DT + Re_BufSz = Re_BufSz + 1 ! Gravity Re_BufSz = Re_BufSz + 1 ! WtrDens - Int_BufSz = Int_BufSz + 1 ! NNodes - Int_BufSz = Int_BufSz + 1 ! Nodes allocated yes/no - IF ( ALLOCATED(InData%Nodes) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Nodes upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + 1 ! WtrDpth + Int_BufSz = Int_BufSz + 1 ! NMembers + Int_BufSz = Int_BufSz + 1 ! Members allocated yes/no + IF ( ALLOCATED(InData%Members) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Members upper/lower bounds for each dimension ! Allocate buffers for subtypes, if any (we'll get sizes from these) - DO i1 = LBOUND(InData%Nodes,1), UBOUND(InData%Nodes,1) - Int_BufSz = Int_BufSz + 3 ! Nodes: size of buffers for each call to pack subtype - CALL Morison_Packnodetype( Re_Buf, Db_Buf, Int_Buf, InData%Nodes(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Nodes + DO i1 = LBOUND(InData%Members,1), UBOUND(InData%Members,1) + Int_BufSz = Int_BufSz + 3 ! Members: size of buffers for each call to pack subtype + CALL Morison_Packmembertype( Re_Buf, Db_Buf, Int_Buf, InData%Members(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Members CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Nodes + IF(ALLOCATED(Re_Buf)) THEN ! Members Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Nodes + IF(ALLOCATED(Db_Buf)) THEN ! Members Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Nodes + IF(ALLOCATED(Int_Buf)) THEN ! Members Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! D_F_I allocated yes/no - IF ( ALLOCATED(InData%D_F_I) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! D_F_I upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_F_I) ! D_F_I - END IF - Int_BufSz = Int_BufSz + 1 ! D_F_DP allocated yes/no - IF ( ALLOCATED(InData%D_F_DP) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! D_F_DP upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_F_DP) ! D_F_DP - END IF - Int_BufSz = Int_BufSz + 1 ! D_dragConst allocated yes/no - IF ( ALLOCATED(InData%D_dragConst) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! D_dragConst upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_dragConst) ! D_dragConst - END IF - Int_BufSz = Int_BufSz + 1 ! L_An allocated yes/no - IF ( ALLOCATED(InData%L_An) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! L_An upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%L_An) ! L_An - END IF - Int_BufSz = Int_BufSz + 1 ! L_F_B allocated yes/no - IF ( ALLOCATED(InData%L_F_B) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! L_F_B upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%L_F_B) ! L_F_B - END IF - Int_BufSz = Int_BufSz + 1 ! L_F_I allocated yes/no - IF ( ALLOCATED(InData%L_F_I) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! L_F_I upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%L_F_I) ! L_F_I - END IF - Int_BufSz = Int_BufSz + 1 ! L_F_DP allocated yes/no - IF ( ALLOCATED(InData%L_F_DP) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! L_F_DP upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%L_F_DP) ! L_F_DP - END IF - Int_BufSz = Int_BufSz + 1 ! L_F_BF allocated yes/no - IF ( ALLOCATED(InData%L_F_BF) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! L_F_BF upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%L_F_BF) ! L_F_BF - END IF - Int_BufSz = Int_BufSz + 1 ! L_AM_M allocated yes/no - IF ( ALLOCATED(InData%L_AM_M) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! L_AM_M upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%L_AM_M) ! L_AM_M - END IF - Int_BufSz = Int_BufSz + 1 ! L_dragConst allocated yes/no - IF ( ALLOCATED(InData%L_dragConst) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! L_dragConst upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%L_dragConst) ! L_dragConst - END IF - Int_BufSz = Int_BufSz + 1 ! NDistribMarkers - Int_BufSz = Int_BufSz + 1 ! distribToNodeIndx allocated yes/no - IF ( ALLOCATED(InData%distribToNodeIndx) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! distribToNodeIndx upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%distribToNodeIndx) ! distribToNodeIndx - END IF - Int_BufSz = Int_BufSz + 1 ! NLumpedMarkers - Int_BufSz = Int_BufSz + 1 ! lumpedToNodeIndx allocated yes/no - IF ( ALLOCATED(InData%lumpedToNodeIndx) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! lumpedToNodeIndx upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%lumpedToNodeIndx) ! lumpedToNodeIndx + Int_BufSz = Int_BufSz + 1 ! NNodes + Int_BufSz = Int_BufSz + 1 ! NJoints + Int_BufSz = Int_BufSz + 1 ! I_MG_End allocated yes/no + IF ( ALLOCATED(InData%I_MG_End) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! I_MG_End upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%I_MG_End) ! I_MG_End + END IF + Int_BufSz = Int_BufSz + 1 ! An_End allocated yes/no + IF ( ALLOCATED(InData%An_End) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! An_End upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%An_End) ! An_End + END IF + Int_BufSz = Int_BufSz + 1 ! DragConst_End allocated yes/no + IF ( ALLOCATED(InData%DragConst_End) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! DragConst_End upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%DragConst_End) ! DragConst_End + END IF + Int_BufSz = Int_BufSz + 1 ! F_WMG_End allocated yes/no + IF ( ALLOCATED(InData%F_WMG_End) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_WMG_End upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_WMG_End) ! F_WMG_End + END IF + Int_BufSz = Int_BufSz + 1 ! DP_Const_End allocated yes/no + IF ( ALLOCATED(InData%DP_Const_End) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! DP_Const_End upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%DP_Const_End) ! DP_Const_End + END IF + Int_BufSz = Int_BufSz + 1 ! Mass_MG_End allocated yes/no + IF ( ALLOCATED(InData%Mass_MG_End) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Mass_MG_End upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Mass_MG_End) ! Mass_MG_End + END IF + Int_BufSz = Int_BufSz + 1 ! AM_End allocated yes/no + IF ( ALLOCATED(InData%AM_End) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! AM_End upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AM_End) ! AM_End END IF Int_BufSz = Int_BufSz + 1 ! WaveVel allocated yes/no IF ( ALLOCATED(InData%WaveVel) ) THEN @@ -8542,50 +10340,10 @@ SUBROUTINE Morison_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + 2*1 ! WaveTime upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WaveTime) ! WaveTime END IF - Int_BufSz = Int_BufSz + 1 ! elementWaterState allocated yes/no - IF ( ALLOCATED(InData%elementWaterState) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! elementWaterState upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%elementWaterState) ! elementWaterState - END IF - Int_BufSz = Int_BufSz + 1 ! elementFillState allocated yes/no - IF ( ALLOCATED(InData%elementFillState) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! elementFillState upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%elementFillState) ! elementFillState - END IF Int_BufSz = Int_BufSz + 1 ! nodeInWater allocated yes/no IF ( ALLOCATED(InData%nodeInWater) ) THEN Int_BufSz = Int_BufSz + 2*2 ! nodeInWater upper/lower bounds for each dimension Int_BufSz = Int_BufSz + SIZE(InData%nodeInWater) ! nodeInWater - END IF - Int_BufSz = Int_BufSz + 1 ! D_F_B allocated yes/no - IF ( ALLOCATED(InData%D_F_B) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! D_F_B upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_F_B) ! D_F_B - END IF - Int_BufSz = Int_BufSz + 1 ! D_F_BF allocated yes/no - IF ( ALLOCATED(InData%D_F_BF) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! D_F_BF upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_F_BF) ! D_F_BF - END IF - Int_BufSz = Int_BufSz + 1 ! D_F_MG allocated yes/no - IF ( ALLOCATED(InData%D_F_MG) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! D_F_MG upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_F_MG) ! D_F_MG - END IF - Int_BufSz = Int_BufSz + 1 ! D_AM_M allocated yes/no - IF ( ALLOCATED(InData%D_AM_M) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! D_AM_M upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_AM_M) ! D_AM_M - END IF - Int_BufSz = Int_BufSz + 1 ! D_AM_MG allocated yes/no - IF ( ALLOCATED(InData%D_AM_MG) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! D_AM_MG upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_AM_MG) ! D_AM_MG - END IF - Int_BufSz = Int_BufSz + 1 ! D_AM_F allocated yes/no - IF ( ALLOCATED(InData%D_AM_F) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! D_AM_F upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D_AM_F) ! D_AM_F END IF Int_BufSz = Int_BufSz + 1 ! NStepWave Int_BufSz = Int_BufSz + 1 ! NMOutputs @@ -8695,22 +10453,26 @@ SUBROUTINE Morison_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs DbKiBuf(Db_Xferred) = InData%DT Db_Xferred = Db_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Gravity + Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%WtrDens Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NNodes + ReKiBuf(Re_Xferred) = InData%WtrDpth + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NMembers Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%Nodes) ) THEN + IF ( .NOT. ALLOCATED(InData%Members) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Nodes,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Nodes,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Members,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Members,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Nodes,1), UBOUND(InData%Nodes,1) - CALL Morison_Packnodetype( Re_Buf, Db_Buf, Int_Buf, InData%Nodes(i1), ErrStat2, ErrMsg2, OnlySize ) ! Nodes + DO i1 = LBOUND(InData%Members,1), UBOUND(InData%Members,1) + CALL Morison_Packmembertype( Re_Buf, Db_Buf, Int_Buf, InData%Members(i1), ErrStat2, ErrMsg2, OnlySize ) ! Members CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -8740,255 +10502,150 @@ SUBROUTINE Morison_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%D_F_I) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IntKiBuf(Int_Xferred) = InData%NNodes Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 + IntKiBuf(Int_Xferred) = InData%NJoints Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_I,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_I,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_I,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_I,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_I,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_I,3) - Int_Xferred = Int_Xferred + 2 - - DO i3 = LBOUND(InData%D_F_I,3), UBOUND(InData%D_F_I,3) - DO i2 = LBOUND(InData%D_F_I,2), UBOUND(InData%D_F_I,2) - DO i1 = LBOUND(InData%D_F_I,1), UBOUND(InData%D_F_I,1) - ReKiBuf(Re_Xferred) = InData%D_F_I(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%D_F_DP) ) THEN + IF ( .NOT. ALLOCATED(InData%I_MG_End) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_DP,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_DP,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%I_MG_End,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%I_MG_End,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_DP,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_DP,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%I_MG_End,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%I_MG_End,2) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_DP,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_DP,3) + IntKiBuf( Int_Xferred ) = LBOUND(InData%I_MG_End,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%I_MG_End,3) Int_Xferred = Int_Xferred + 2 - DO i3 = LBOUND(InData%D_F_DP,3), UBOUND(InData%D_F_DP,3) - DO i2 = LBOUND(InData%D_F_DP,2), UBOUND(InData%D_F_DP,2) - DO i1 = LBOUND(InData%D_F_DP,1), UBOUND(InData%D_F_DP,1) - ReKiBuf(Re_Xferred) = InData%D_F_DP(i1,i2,i3) + DO i3 = LBOUND(InData%I_MG_End,3), UBOUND(InData%I_MG_End,3) + DO i2 = LBOUND(InData%I_MG_End,2), UBOUND(InData%I_MG_End,2) + DO i1 = LBOUND(InData%I_MG_End,1), UBOUND(InData%I_MG_End,1) + ReKiBuf(Re_Xferred) = InData%I_MG_End(i1,i2,i3) Re_Xferred = Re_Xferred + 1 END DO END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%D_dragConst) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_dragConst,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_dragConst,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%D_dragConst,1), UBOUND(InData%D_dragConst,1) - ReKiBuf(Re_Xferred) = InData%D_dragConst(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%L_An) ) THEN + IF ( .NOT. ALLOCATED(InData%An_End) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_An,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_An,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%An_End,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%An_End,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_An,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_An,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%An_End,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%An_End,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%L_An,2), UBOUND(InData%L_An,2) - DO i1 = LBOUND(InData%L_An,1), UBOUND(InData%L_An,1) - ReKiBuf(Re_Xferred) = InData%L_An(i1,i2) + DO i2 = LBOUND(InData%An_End,2), UBOUND(InData%An_End,2) + DO i1 = LBOUND(InData%An_End,1), UBOUND(InData%An_End,1) + ReKiBuf(Re_Xferred) = InData%An_End(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%L_F_B) ) THEN + IF ( .NOT. ALLOCATED(InData%DragConst_End) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_B,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_B,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_B,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_B,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%DragConst_End,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DragConst_End,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%L_F_B,2), UBOUND(InData%L_F_B,2) - DO i1 = LBOUND(InData%L_F_B,1), UBOUND(InData%L_F_B,1) - ReKiBuf(Re_Xferred) = InData%L_F_B(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(InData%DragConst_End,1), UBOUND(InData%DragConst_End,1) + ReKiBuf(Re_Xferred) = InData%DragConst_End(i1) + Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%L_F_I) ) THEN + IF ( .NOT. ALLOCATED(InData%F_WMG_End) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_I,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_I,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_WMG_End,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_WMG_End,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_I,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_I,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_I,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_I,3) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_WMG_End,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_WMG_End,2) Int_Xferred = Int_Xferred + 2 - DO i3 = LBOUND(InData%L_F_I,3), UBOUND(InData%L_F_I,3) - DO i2 = LBOUND(InData%L_F_I,2), UBOUND(InData%L_F_I,2) - DO i1 = LBOUND(InData%L_F_I,1), UBOUND(InData%L_F_I,1) - ReKiBuf(Re_Xferred) = InData%L_F_I(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 - END DO + DO i2 = LBOUND(InData%F_WMG_End,2), UBOUND(InData%F_WMG_End,2) + DO i1 = LBOUND(InData%F_WMG_End,1), UBOUND(InData%F_WMG_End,1) + ReKiBuf(Re_Xferred) = InData%F_WMG_End(i1,i2) + Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%L_F_DP) ) THEN + IF ( .NOT. ALLOCATED(InData%DP_Const_End) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_DP,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_DP,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%DP_Const_End,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DP_Const_End,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_DP,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_DP,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_DP,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_DP,3) + IntKiBuf( Int_Xferred ) = LBOUND(InData%DP_Const_End,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DP_Const_End,2) Int_Xferred = Int_Xferred + 2 - DO i3 = LBOUND(InData%L_F_DP,3), UBOUND(InData%L_F_DP,3) - DO i2 = LBOUND(InData%L_F_DP,2), UBOUND(InData%L_F_DP,2) - DO i1 = LBOUND(InData%L_F_DP,1), UBOUND(InData%L_F_DP,1) - ReKiBuf(Re_Xferred) = InData%L_F_DP(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 - END DO + DO i2 = LBOUND(InData%DP_Const_End,2), UBOUND(InData%DP_Const_End,2) + DO i1 = LBOUND(InData%DP_Const_End,1), UBOUND(InData%DP_Const_End,1) + ReKiBuf(Re_Xferred) = InData%DP_Const_End(i1,i2) + Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%L_F_BF) ) THEN + IF ( .NOT. ALLOCATED(InData%Mass_MG_End) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_BF,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_BF,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_F_BF,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_F_BF,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Mass_MG_End,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Mass_MG_End,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%L_F_BF,2), UBOUND(InData%L_F_BF,2) - DO i1 = LBOUND(InData%L_F_BF,1), UBOUND(InData%L_F_BF,1) - ReKiBuf(Re_Xferred) = InData%L_F_BF(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(InData%Mass_MG_End,1), UBOUND(InData%Mass_MG_End,1) + ReKiBuf(Re_Xferred) = InData%Mass_MG_End(i1) + Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%L_AM_M) ) THEN + IF ( .NOT. ALLOCATED(InData%AM_End) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_AM_M,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_AM_M,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%AM_End,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AM_End,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_AM_M,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_AM_M,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%AM_End,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AM_End,2) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_AM_M,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_AM_M,3) + IntKiBuf( Int_Xferred ) = LBOUND(InData%AM_End,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AM_End,3) Int_Xferred = Int_Xferred + 2 - DO i3 = LBOUND(InData%L_AM_M,3), UBOUND(InData%L_AM_M,3) - DO i2 = LBOUND(InData%L_AM_M,2), UBOUND(InData%L_AM_M,2) - DO i1 = LBOUND(InData%L_AM_M,1), UBOUND(InData%L_AM_M,1) - ReKiBuf(Re_Xferred) = InData%L_AM_M(i1,i2,i3) + DO i3 = LBOUND(InData%AM_End,3), UBOUND(InData%AM_End,3) + DO i2 = LBOUND(InData%AM_End,2), UBOUND(InData%AM_End,2) + DO i1 = LBOUND(InData%AM_End,1), UBOUND(InData%AM_End,1) + ReKiBuf(Re_Xferred) = InData%AM_End(i1,i2,i3) Re_Xferred = Re_Xferred + 1 END DO END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%L_dragConst) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%L_dragConst,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%L_dragConst,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%L_dragConst,1), UBOUND(InData%L_dragConst,1) - ReKiBuf(Re_Xferred) = InData%L_dragConst(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IntKiBuf(Int_Xferred) = InData%NDistribMarkers - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%distribToNodeIndx) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%distribToNodeIndx,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%distribToNodeIndx,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%distribToNodeIndx,1), UBOUND(InData%distribToNodeIndx,1) - IntKiBuf(Int_Xferred) = InData%distribToNodeIndx(i1) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - IntKiBuf(Int_Xferred) = InData%NLumpedMarkers - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%lumpedToNodeIndx) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%lumpedToNodeIndx,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%lumpedToNodeIndx,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%lumpedToNodeIndx,1), UBOUND(InData%lumpedToNodeIndx,1) - IntKiBuf(Int_Xferred) = InData%lumpedToNodeIndx(i1) - Int_Xferred = Int_Xferred + 1 - END DO - END IF IF ( .NOT. ALLOCATED(InData%WaveVel) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -9074,41 +10731,6 @@ SUBROUTINE Morison_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%elementWaterState) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%elementWaterState,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%elementWaterState,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%elementWaterState,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%elementWaterState,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%elementWaterState,2), UBOUND(InData%elementWaterState,2) - DO i1 = LBOUND(InData%elementWaterState,1), UBOUND(InData%elementWaterState,1) - IntKiBuf(Int_Xferred) = InData%elementWaterState(i1,i2) - Int_Xferred = Int_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%elementFillState) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%elementFillState,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%elementFillState,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%elementFillState,1), UBOUND(InData%elementFillState,1) - IntKiBuf(Int_Xferred) = InData%elementFillState(i1) - Int_Xferred = Int_Xferred + 1 - END DO - END IF IF ( .NOT. ALLOCATED(InData%nodeInWater) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -9125,123 +10747,8 @@ SUBROUTINE Morison_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs DO i2 = LBOUND(InData%nodeInWater,2), UBOUND(InData%nodeInWater,2) DO i1 = LBOUND(InData%nodeInWater,1), UBOUND(InData%nodeInWater,1) IntKiBuf(Int_Xferred) = InData%nodeInWater(i1,i2) - Int_Xferred = Int_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%D_F_B) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_B,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_B,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_B,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_B,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%D_F_B,2), UBOUND(InData%D_F_B,2) - DO i1 = LBOUND(InData%D_F_B,1), UBOUND(InData%D_F_B,1) - ReKiBuf(Re_Xferred) = InData%D_F_B(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%D_F_BF) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_BF,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_BF,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_BF,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_BF,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%D_F_BF,2), UBOUND(InData%D_F_BF,2) - DO i1 = LBOUND(InData%D_F_BF,1), UBOUND(InData%D_F_BF,1) - ReKiBuf(Re_Xferred) = InData%D_F_BF(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%D_F_MG) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_MG,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_MG,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_F_MG,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_F_MG,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%D_F_MG,2), UBOUND(InData%D_F_MG,2) - DO i1 = LBOUND(InData%D_F_MG,1), UBOUND(InData%D_F_MG,1) - ReKiBuf(Re_Xferred) = InData%D_F_MG(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%D_AM_M) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_AM_M,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_AM_M,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_AM_M,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_AM_M,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_AM_M,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_AM_M,3) - Int_Xferred = Int_Xferred + 2 - - DO i3 = LBOUND(InData%D_AM_M,3), UBOUND(InData%D_AM_M,3) - DO i2 = LBOUND(InData%D_AM_M,2), UBOUND(InData%D_AM_M,2) - DO i1 = LBOUND(InData%D_AM_M,1), UBOUND(InData%D_AM_M,1) - ReKiBuf(Re_Xferred) = InData%D_AM_M(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%D_AM_MG) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_AM_MG,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_AM_MG,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%D_AM_MG,1), UBOUND(InData%D_AM_MG,1) - ReKiBuf(Re_Xferred) = InData%D_AM_MG(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%D_AM_F) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D_AM_F,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D_AM_F,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%D_AM_F,1), UBOUND(InData%D_AM_F,1) - ReKiBuf(Re_Xferred) = InData%D_AM_F(i1) - Re_Xferred = Re_Xferred + 1 + Int_Xferred = Int_Xferred + 1 + END DO END DO END IF IntKiBuf(Int_Xferred) = InData%NStepWave @@ -9426,24 +10933,28 @@ SUBROUTINE Morison_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Int_Xferred = 1 OutData%DT = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 + OutData%Gravity = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 OutData%WtrDens = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%NNodes = IntKiBuf(Int_Xferred) + OutData%WtrDpth = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%NMembers = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Nodes not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Members not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Nodes)) DEALLOCATE(OutData%Nodes) - ALLOCATE(OutData%Nodes(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Members)) DEALLOCATE(OutData%Members) + ALLOCATE(OutData%Members(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Nodes.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Members.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Nodes,1), UBOUND(OutData%Nodes,1) + DO i1 = LBOUND(OutData%Members,1), UBOUND(OutData%Members,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -9477,7 +10988,7 @@ SUBROUTINE Morison_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL Morison_Unpacknodetype( Re_Buf, Db_Buf, Int_Buf, OutData%Nodes(i1), ErrStat2, ErrMsg2 ) ! Nodes + CALL Morison_Unpackmembertype( Re_Buf, Db_Buf, Int_Buf, OutData%Members(i1), ErrStat2, ErrMsg2 ) ! Members CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -9486,320 +10997,11 @@ SUBROUTINE Morison_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_F_I not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_F_I)) DEALLOCATE(OutData%D_F_I) - ALLOCATE(OutData%D_F_I(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_F_I.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i3 = LBOUND(OutData%D_F_I,3), UBOUND(OutData%D_F_I,3) - DO i2 = LBOUND(OutData%D_F_I,2), UBOUND(OutData%D_F_I,2) - DO i1 = LBOUND(OutData%D_F_I,1), UBOUND(OutData%D_F_I,1) - OutData%D_F_I(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_F_DP not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_F_DP)) DEALLOCATE(OutData%D_F_DP) - ALLOCATE(OutData%D_F_DP(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_F_DP.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i3 = LBOUND(OutData%D_F_DP,3), UBOUND(OutData%D_F_DP,3) - DO i2 = LBOUND(OutData%D_F_DP,2), UBOUND(OutData%D_F_DP,2) - DO i1 = LBOUND(OutData%D_F_DP,1), UBOUND(OutData%D_F_DP,1) - OutData%D_F_DP(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_dragConst not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_dragConst)) DEALLOCATE(OutData%D_dragConst) - ALLOCATE(OutData%D_dragConst(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_dragConst.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%D_dragConst,1), UBOUND(OutData%D_dragConst,1) - OutData%D_dragConst(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! L_An not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%L_An)) DEALLOCATE(OutData%L_An) - ALLOCATE(OutData%L_An(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%L_An.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%L_An,2), UBOUND(OutData%L_An,2) - DO i1 = LBOUND(OutData%L_An,1), UBOUND(OutData%L_An,1) - OutData%L_An(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! L_F_B not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%L_F_B)) DEALLOCATE(OutData%L_F_B) - ALLOCATE(OutData%L_F_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%L_F_B.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%L_F_B,2), UBOUND(OutData%L_F_B,2) - DO i1 = LBOUND(OutData%L_F_B,1), UBOUND(OutData%L_F_B,1) - OutData%L_F_B(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! L_F_I not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%L_F_I)) DEALLOCATE(OutData%L_F_I) - ALLOCATE(OutData%L_F_I(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%L_F_I.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i3 = LBOUND(OutData%L_F_I,3), UBOUND(OutData%L_F_I,3) - DO i2 = LBOUND(OutData%L_F_I,2), UBOUND(OutData%L_F_I,2) - DO i1 = LBOUND(OutData%L_F_I,1), UBOUND(OutData%L_F_I,1) - OutData%L_F_I(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! L_F_DP not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%L_F_DP)) DEALLOCATE(OutData%L_F_DP) - ALLOCATE(OutData%L_F_DP(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%L_F_DP.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i3 = LBOUND(OutData%L_F_DP,3), UBOUND(OutData%L_F_DP,3) - DO i2 = LBOUND(OutData%L_F_DP,2), UBOUND(OutData%L_F_DP,2) - DO i1 = LBOUND(OutData%L_F_DP,1), UBOUND(OutData%L_F_DP,1) - OutData%L_F_DP(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! L_F_BF not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%L_F_BF)) DEALLOCATE(OutData%L_F_BF) - ALLOCATE(OutData%L_F_BF(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%L_F_BF.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%L_F_BF,2), UBOUND(OutData%L_F_BF,2) - DO i1 = LBOUND(OutData%L_F_BF,1), UBOUND(OutData%L_F_BF,1) - OutData%L_F_BF(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! L_AM_M not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%L_AM_M)) DEALLOCATE(OutData%L_AM_M) - ALLOCATE(OutData%L_AM_M(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%L_AM_M.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i3 = LBOUND(OutData%L_AM_M,3), UBOUND(OutData%L_AM_M,3) - DO i2 = LBOUND(OutData%L_AM_M,2), UBOUND(OutData%L_AM_M,2) - DO i1 = LBOUND(OutData%L_AM_M,1), UBOUND(OutData%L_AM_M,1) - OutData%L_AM_M(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! L_dragConst not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%L_dragConst)) DEALLOCATE(OutData%L_dragConst) - ALLOCATE(OutData%L_dragConst(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%L_dragConst.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%L_dragConst,1), UBOUND(OutData%L_dragConst,1) - OutData%L_dragConst(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - OutData%NDistribMarkers = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! distribToNodeIndx not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%distribToNodeIndx)) DEALLOCATE(OutData%distribToNodeIndx) - ALLOCATE(OutData%distribToNodeIndx(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%distribToNodeIndx.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%distribToNodeIndx,1), UBOUND(OutData%distribToNodeIndx,1) - OutData%distribToNodeIndx(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - OutData%NLumpedMarkers = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! lumpedToNodeIndx not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%lumpedToNodeIndx)) DEALLOCATE(OutData%lumpedToNodeIndx) - ALLOCATE(OutData%lumpedToNodeIndx(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%lumpedToNodeIndx.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%lumpedToNodeIndx,1), UBOUND(OutData%lumpedToNodeIndx,1) - OutData%lumpedToNodeIndx(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveVel not allocated + OutData%NNodes = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - ELSE + OutData%NJoints = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%WaveVel)) DEALLOCATE(OutData%WaveVel) - ALLOCATE(OutData%WaveVel(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveVel.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i3 = LBOUND(OutData%WaveVel,3), UBOUND(OutData%WaveVel,3) - DO i2 = LBOUND(OutData%WaveVel,2), UBOUND(OutData%WaveVel,2) - DO i1 = LBOUND(OutData%WaveVel,1), UBOUND(OutData%WaveVel,1) - OutData%WaveVel(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveAcc not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! I_MG_End not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -9812,22 +11014,22 @@ SUBROUTINE Morison_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er i3_l = IntKiBuf( Int_Xferred ) i3_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%WaveAcc)) DEALLOCATE(OutData%WaveAcc) - ALLOCATE(OutData%WaveAcc(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%I_MG_End)) DEALLOCATE(OutData%I_MG_End) + ALLOCATE(OutData%I_MG_End(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveAcc.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%I_MG_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i3 = LBOUND(OutData%WaveAcc,3), UBOUND(OutData%WaveAcc,3) - DO i2 = LBOUND(OutData%WaveAcc,2), UBOUND(OutData%WaveAcc,2) - DO i1 = LBOUND(OutData%WaveAcc,1), UBOUND(OutData%WaveAcc,1) - OutData%WaveAcc(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) + DO i3 = LBOUND(OutData%I_MG_End,3), UBOUND(OutData%I_MG_End,3) + DO i2 = LBOUND(OutData%I_MG_End,2), UBOUND(OutData%I_MG_End,2) + DO i1 = LBOUND(OutData%I_MG_End,1), UBOUND(OutData%I_MG_End,1) + OutData%I_MG_End(i1,i2,i3) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveDynP not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! An_End not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -9837,38 +11039,38 @@ SUBROUTINE Morison_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%WaveDynP)) DEALLOCATE(OutData%WaveDynP) - ALLOCATE(OutData%WaveDynP(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%An_End)) DEALLOCATE(OutData%An_End) + ALLOCATE(OutData%An_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveDynP.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%An_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%WaveDynP,2), UBOUND(OutData%WaveDynP,2) - DO i1 = LBOUND(OutData%WaveDynP,1), UBOUND(OutData%WaveDynP,1) - OutData%WaveDynP(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) + DO i2 = LBOUND(OutData%An_End,2), UBOUND(OutData%An_End,2) + DO i1 = LBOUND(OutData%An_End,1), UBOUND(OutData%An_End,1) + OutData%An_End(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveTime not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! DragConst_End not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%WaveTime)) DEALLOCATE(OutData%WaveTime) - ALLOCATE(OutData%WaveTime(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%DragConst_End)) DEALLOCATE(OutData%DragConst_End) + ALLOCATE(OutData%DragConst_End(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveTime.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%DragConst_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%WaveTime,1), UBOUND(OutData%WaveTime,1) - OutData%WaveTime(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) + DO i1 = LBOUND(OutData%DragConst_End,1), UBOUND(OutData%DragConst_End,1) + OutData%DragConst_End(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! elementWaterState not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_WMG_End not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -9878,61 +11080,61 @@ SUBROUTINE Morison_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%elementWaterState)) DEALLOCATE(OutData%elementWaterState) - ALLOCATE(OutData%elementWaterState(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%F_WMG_End)) DEALLOCATE(OutData%F_WMG_End) + ALLOCATE(OutData%F_WMG_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%elementWaterState.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_WMG_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%elementWaterState,2), UBOUND(OutData%elementWaterState,2) - DO i1 = LBOUND(OutData%elementWaterState,1), UBOUND(OutData%elementWaterState,1) - OutData%elementWaterState(i1,i2) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + DO i2 = LBOUND(OutData%F_WMG_End,2), UBOUND(OutData%F_WMG_End,2) + DO i1 = LBOUND(OutData%F_WMG_End,1), UBOUND(OutData%F_WMG_End,1) + OutData%F_WMG_End(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! elementFillState not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! DP_Const_End not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%elementFillState)) DEALLOCATE(OutData%elementFillState) - ALLOCATE(OutData%elementFillState(i1_l:i1_u),STAT=ErrStat2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%DP_Const_End)) DEALLOCATE(OutData%DP_Const_End) + ALLOCATE(OutData%DP_Const_End(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%elementFillState.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%DP_Const_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%elementFillState,1), UBOUND(OutData%elementFillState,1) - OutData%elementFillState(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + DO i2 = LBOUND(OutData%DP_Const_End,2), UBOUND(OutData%DP_Const_End,2) + DO i1 = LBOUND(OutData%DP_Const_End,1), UBOUND(OutData%DP_Const_End,1) + OutData%DP_Const_End(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nodeInWater not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Mass_MG_End not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%nodeInWater)) DEALLOCATE(OutData%nodeInWater) - ALLOCATE(OutData%nodeInWater(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Mass_MG_End)) DEALLOCATE(OutData%Mass_MG_End) + ALLOCATE(OutData%Mass_MG_End(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nodeInWater.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Mass_MG_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%nodeInWater,2), UBOUND(OutData%nodeInWater,2) - DO i1 = LBOUND(OutData%nodeInWater,1), UBOUND(OutData%nodeInWater,1) - OutData%nodeInWater(i1,i2) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO + DO i1 = LBOUND(OutData%Mass_MG_End,1), UBOUND(OutData%Mass_MG_End,1) + OutData%Mass_MG_End(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_F_B not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AM_End not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -9942,20 +11144,25 @@ SUBROUTINE Morison_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_F_B)) DEALLOCATE(OutData%D_F_B) - ALLOCATE(OutData%D_F_B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AM_End)) DEALLOCATE(OutData%AM_End) + ALLOCATE(OutData%AM_End(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_F_B.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AM_End.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%D_F_B,2), UBOUND(OutData%D_F_B,2) - DO i1 = LBOUND(OutData%D_F_B,1), UBOUND(OutData%D_F_B,1) - OutData%D_F_B(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(OutData%AM_End,3), UBOUND(OutData%AM_End,3) + DO i2 = LBOUND(OutData%AM_End,2), UBOUND(OutData%AM_End,2) + DO i1 = LBOUND(OutData%AM_End,1), UBOUND(OutData%AM_End,1) + OutData%AM_End(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_F_BF not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveVel not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -9965,20 +11172,25 @@ SUBROUTINE Morison_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_F_BF)) DEALLOCATE(OutData%D_F_BF) - ALLOCATE(OutData%D_F_BF(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WaveVel)) DEALLOCATE(OutData%WaveVel) + ALLOCATE(OutData%WaveVel(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_F_BF.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveVel.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%D_F_BF,2), UBOUND(OutData%D_F_BF,2) - DO i1 = LBOUND(OutData%D_F_BF,1), UBOUND(OutData%D_F_BF,1) - OutData%D_F_BF(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(OutData%WaveVel,3), UBOUND(OutData%WaveVel,3) + DO i2 = LBOUND(OutData%WaveVel,2), UBOUND(OutData%WaveVel,2) + DO i1 = LBOUND(OutData%WaveVel,1), UBOUND(OutData%WaveVel,1) + OutData%WaveVel(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_F_MG not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveAcc not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -9988,20 +11200,25 @@ SUBROUTINE Morison_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_F_MG)) DEALLOCATE(OutData%D_F_MG) - ALLOCATE(OutData%D_F_MG(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WaveAcc)) DEALLOCATE(OutData%WaveAcc) + ALLOCATE(OutData%WaveAcc(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_F_MG.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveAcc.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%D_F_MG,2), UBOUND(OutData%D_F_MG,2) - DO i1 = LBOUND(OutData%D_F_MG,1), UBOUND(OutData%D_F_MG,1) - OutData%D_F_MG(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(OutData%WaveAcc,3), UBOUND(OutData%WaveAcc,3) + DO i2 = LBOUND(OutData%WaveAcc,2), UBOUND(OutData%WaveAcc,2) + DO i1 = LBOUND(OutData%WaveAcc,1), UBOUND(OutData%WaveAcc,1) + OutData%WaveAcc(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_AM_M not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveDynP not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -10011,58 +11228,58 @@ SUBROUTINE Morison_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_AM_M)) DEALLOCATE(OutData%D_AM_M) - ALLOCATE(OutData%D_AM_M(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%WaveDynP)) DEALLOCATE(OutData%WaveDynP) + ALLOCATE(OutData%WaveDynP(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_AM_M.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveDynP.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i3 = LBOUND(OutData%D_AM_M,3), UBOUND(OutData%D_AM_M,3) - DO i2 = LBOUND(OutData%D_AM_M,2), UBOUND(OutData%D_AM_M,2) - DO i1 = LBOUND(OutData%D_AM_M,1), UBOUND(OutData%D_AM_M,1) - OutData%D_AM_M(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + DO i2 = LBOUND(OutData%WaveDynP,2), UBOUND(OutData%WaveDynP,2) + DO i1 = LBOUND(OutData%WaveDynP,1), UBOUND(OutData%WaveDynP,1) + OutData%WaveDynP(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_AM_MG not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveTime not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_AM_MG)) DEALLOCATE(OutData%D_AM_MG) - ALLOCATE(OutData%D_AM_MG(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%WaveTime)) DEALLOCATE(OutData%WaveTime) + ALLOCATE(OutData%WaveTime(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_AM_MG.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveTime.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%D_AM_MG,1), UBOUND(OutData%D_AM_MG,1) - OutData%D_AM_MG(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%WaveTime,1), UBOUND(OutData%WaveTime,1) + OutData%WaveTime(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_AM_F not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nodeInWater not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D_AM_F)) DEALLOCATE(OutData%D_AM_F) - ALLOCATE(OutData%D_AM_F(i1_l:i1_u),STAT=ErrStat2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%nodeInWater)) DEALLOCATE(OutData%nodeInWater) + ALLOCATE(OutData%nodeInWater(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D_AM_F.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nodeInWater.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%D_AM_F,1), UBOUND(OutData%D_AM_F,1) - OutData%D_AM_F(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(OutData%nodeInWater,2), UBOUND(OutData%nodeInWater,2) + DO i1 = LBOUND(OutData%nodeInWater,1), UBOUND(OutData%nodeInWater,1) + OutData%nodeInWater(i1,i2) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO END DO END IF OutData%NStepWave = IntKiBuf(Int_Xferred) @@ -10275,10 +11492,7 @@ SUBROUTINE Morison_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, Err ! ErrStat = ErrID_None ErrMsg = "" - CALL MeshCopy( SrcInputData%DistribMesh, DstInputData%DistribMesh, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL MeshCopy( SrcInputData%LumpedMesh, DstInputData%LumpedMesh, CtrlCode, ErrStat2, ErrMsg2 ) + CALL MeshCopy( SrcInputData%Mesh, DstInputData%Mesh, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE Morison_CopyInput @@ -10292,8 +11506,7 @@ SUBROUTINE Morison_DestroyInput( InputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( InputData%DistribMesh, ErrStat, ErrMsg ) - CALL MeshDestroy( InputData%LumpedMesh, ErrStat, ErrMsg ) + CALL MeshDestroy( InputData%Mesh, ErrStat, ErrMsg ) END SUBROUTINE Morison_DestroyInput SUBROUTINE Morison_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -10332,37 +11545,20 @@ SUBROUTINE Morison_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_BufSz = 0 Int_BufSz = 0 ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! DistribMesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%DistribMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! DistribMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! DistribMesh - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! DistribMesh - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! DistribMesh - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! LumpedMesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%LumpedMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! LumpedMesh + Int_BufSz = Int_BufSz + 3 ! Mesh: size of buffers for each call to pack subtype + CALL MeshPack( InData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! Mesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! LumpedMesh + IF(ALLOCATED(Re_Buf)) THEN ! Mesh Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! LumpedMesh + IF(ALLOCATED(Db_Buf)) THEN ! Mesh Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! LumpedMesh + IF(ALLOCATED(Int_Buf)) THEN ! Mesh Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -10393,35 +11589,7 @@ SUBROUTINE Morison_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_Xferred = 1 Int_Xferred = 1 - CALL MeshPack( InData%DistribMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! DistribMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL MeshPack( InData%LumpedMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! LumpedMesh + CALL MeshPack( InData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! Mesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -10510,47 +11678,7 @@ SUBROUTINE Morison_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL MeshUnpack( OutData%DistribMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! DistribMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL MeshUnpack( OutData%LumpedMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! LumpedMesh + CALL MeshUnpack( OutData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! Mesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -10574,10 +11702,7 @@ SUBROUTINE Morison_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ! ErrStat = ErrID_None ErrMsg = "" - CALL MeshCopy( SrcOutputData%DistribMesh, DstOutputData%DistribMesh, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL MeshCopy( SrcOutputData%LumpedMesh, DstOutputData%LumpedMesh, CtrlCode, ErrStat2, ErrMsg2 ) + CALL MeshCopy( SrcOutputData%Mesh, DstOutputData%Mesh, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN IF (ALLOCATED(SrcOutputData%WriteOutput)) THEN @@ -10603,8 +11728,7 @@ SUBROUTINE Morison_DestroyOutput( OutputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( OutputData%DistribMesh, ErrStat, ErrMsg ) - CALL MeshDestroy( OutputData%LumpedMesh, ErrStat, ErrMsg ) + CALL MeshDestroy( OutputData%Mesh, ErrStat, ErrMsg ) IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF @@ -10646,37 +11770,20 @@ SUBROUTINE Morison_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Db_BufSz = 0 Int_BufSz = 0 ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! DistribMesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%DistribMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! DistribMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! DistribMesh - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! DistribMesh - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! DistribMesh - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! LumpedMesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%LumpedMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! LumpedMesh + Int_BufSz = Int_BufSz + 3 ! Mesh: size of buffers for each call to pack subtype + CALL MeshPack( InData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! Mesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! LumpedMesh + IF(ALLOCATED(Re_Buf)) THEN ! Mesh Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! LumpedMesh + IF(ALLOCATED(Db_Buf)) THEN ! Mesh Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! LumpedMesh + IF(ALLOCATED(Int_Buf)) THEN ! Mesh Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -10712,35 +11819,7 @@ SUBROUTINE Morison_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Db_Xferred = 1 Int_Xferred = 1 - CALL MeshPack( InData%DistribMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! DistribMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL MeshPack( InData%LumpedMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! LumpedMesh + CALL MeshPack( InData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! Mesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -10845,47 +11924,7 @@ SUBROUTINE Morison_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL MeshUnpack( OutData%DistribMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! DistribMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL MeshUnpack( OutData%LumpedMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! LumpedMesh + CALL MeshUnpack( OutData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! Mesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -11005,9 +12044,7 @@ SUBROUTINE Morison_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, Err END IF ScaleFactor = t_out / t(2) - CALL MeshExtrapInterp1(u1%DistribMesh, u2%DistribMesh, tin, u_out%DistribMesh, tin_out, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - CALL MeshExtrapInterp1(u1%LumpedMesh, u2%LumpedMesh, tin, u_out%LumpedMesh, tin_out, ErrStat2, ErrMsg2 ) + CALL MeshExtrapInterp1(u1%Mesh, u2%Mesh, tin, u_out%Mesh, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) END SUBROUTINE Morison_Input_ExtrapInterp1 @@ -11064,9 +12101,7 @@ SUBROUTINE Morison_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, END IF ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) - CALL MeshExtrapInterp2(u1%DistribMesh, u2%DistribMesh, u3%DistribMesh, tin, u_out%DistribMesh, tin_out, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - CALL MeshExtrapInterp2(u1%LumpedMesh, u2%LumpedMesh, u3%LumpedMesh, tin, u_out%LumpedMesh, tin_out, ErrStat2, ErrMsg2 ) + CALL MeshExtrapInterp2(u1%Mesh, u2%Mesh, u3%Mesh, tin, u_out%Mesh, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) END SUBROUTINE Morison_Input_ExtrapInterp2 @@ -11165,9 +12200,7 @@ SUBROUTINE Morison_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, Er END IF ScaleFactor = t_out / t(2) - CALL MeshExtrapInterp1(y1%DistribMesh, y2%DistribMesh, tin, y_out%DistribMesh, tin_out, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - CALL MeshExtrapInterp1(y1%LumpedMesh, y2%LumpedMesh, tin, y_out%LumpedMesh, tin_out, ErrStat2, ErrMsg2 ) + CALL MeshExtrapInterp1(y1%Mesh, y2%Mesh, tin, y_out%Mesh, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) @@ -11232,9 +12265,7 @@ SUBROUTINE Morison_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat END IF ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) - CALL MeshExtrapInterp2(y1%DistribMesh, y2%DistribMesh, y3%DistribMesh, tin, y_out%DistribMesh, tin_out, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - CALL MeshExtrapInterp2(y1%LumpedMesh, y2%LumpedMesh, y3%LumpedMesh, tin, y_out%LumpedMesh, tin_out, ErrStat2, ErrMsg2 ) + CALL MeshExtrapInterp2(y1%Mesh, y2%Mesh, y3%Mesh, tin, y_out%Mesh, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) diff --git a/modules/hydrodyn/src/SS_Excitation.f90 b/modules/hydrodyn/src/SS_Excitation.f90 index f2071c1db1..5af0dd457c 100644 --- a/modules/hydrodyn/src/SS_Excitation.f90 +++ b/modules/hydrodyn/src/SS_Excitation.f90 @@ -46,6 +46,38 @@ MODULE SS_Excitation CONTAINS + +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine transforms the State Space input file data from a local (heading-angle, based) coordinate system to the global system. +!> NOTE: This routine ONLY works if all the DOFs are enabled!!!!!!!!!! +subroutine TransformStateSpaceMatrices( NBody, RotZ, C ) +!.................................................................................................................................. + integer(IntKi), intent( in ) :: NBody ! Number of WAMIT bodies in this WAMIT object ( = 1 if NBodyMod > 1) + real(R8Ki), intent( in ) :: RotZ(:) ! NBody heading angles (radians) + real(ReKi), intent( inout ) :: C(:,:) ! Matrix data to be transformed, if NBodyMOD = 1 and NBody > 1 then we will be transforming the individual sub 6x6 matrices + + integer(IntKi) :: i,j,indx + real(R8Ki) :: R(3,3) + real(R8Ki) :: Rt(3,3) + + do i = 1, NBody + if ( .not. EqualRealNos(RotZ(i), 0.0_R8Ki) ) then + R(1,:) = (/ cos(RotZ(i)), sin(RotZ(i)), 0.0_R8Ki/) + R(2,:) = (/-sin(RotZ(i)), cos(RotZ(i)), 0.0_R8Ki/) + R(3,:) = (/ 0.0_R8Ki , 0.0_R8Ki , 1.0_R8Ki/) + Rt = transpose(R) + + do j = 1,2 ! Need to do this twice, since a single R (3x3) matrix is used to transform all 6 DOFs associated with the ith Body data + indx = (i-1)*6 + (j-1)*3 + 1 + + ! Create sub matrix which is all columns of C but only necessary rows for transformation work, NOTE: c is (6*NBody) X numStates + C(indx:indx+2,:) = matmul( Rt, C(indx:indx+2,:) ) + end do + end if + end do + +end subroutine TransformStateSpaceMatrices + !---------------------------------------------------------------------------------------------------------------------------------- !> This routine is called at the start of the simulation to perform initialization steps. !! The parameters are set here and not changed during the simulation. @@ -76,13 +108,11 @@ SUBROUTINE SS_Exc_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini ! Local Variables: INTEGER :: I ! Generic index -! INTEGER :: J ! Generic index - INTEGER :: xx (1,6) ! Active DOF's on the input file .ss INTEGER :: Nlines ! Number of lines in the input file, used to determine N INTEGER :: UnSS ! I/O unit number for the WAMIT output file with the .ss extension; this file contains the state-space matrices. INTEGER :: Sttus ! Error in reading .ssexctn file - !CHARACTER :: Line ! Temp line of file real(ReKi) :: WaveDir ! Temp wave direction angle (deg) + character(3) :: bodystr integer :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 @@ -93,8 +123,9 @@ SUBROUTINE SS_Exc_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini u%DummyInput = 0.0_ReKi UnSS = -1 - p%N = 0 - + p%numStates = 0 + p%NBody = InitInp%NBody ! Number of WAMIT bodies: =1 if WAMIT is using NBodyMod > 1, >=1 if NBodyMod=1 + ! Open the .ss input file! CALL GetNewUnit( UnSS ) CALL OpenFInpFile ( UnSS, TRIM(InitInp%InputFile)//'.ssexctn', ErrStat2, ErrMsg2 ) ! Open file. @@ -119,10 +150,10 @@ SUBROUTINE SS_Exc_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini CALL ReadVar( UnSS,TRIM(InitInp%InputFile)//'.ssexctn', p%Tc, 'p%Tc', 'Time offset (s)',ErrStat2, ErrMsg2) ! Reads in the third line, containing the number of states CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Exc_Init') - CALL ReadVar( UnSS,TRIM(InitInp%InputFile)//'.ssexctn', p%N, 'p%N', 'Number of states',ErrStat2, ErrMsg2) ! Reads in the third line, containing the number of states + CALL ReadVar( UnSS,TRIM(InitInp%InputFile)//'.ssexctn', p%numStates, 'p%numStates', 'Number of states',ErrStat2, ErrMsg2) ! Reads in the third line, containing the number of states CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Exc_Init') - CALL ReadAry( UnSS,TRIM(InitInp%InputFile)//'.ssexctn', p%spDOF, 6, 'p%spDOF', 'States per DOF',ErrStat2, ErrMsg2) + CALL ReadAry( UnSS,TRIM(InitInp%InputFile)//'.ssexctn', p%spDOF, 6*p%NBody, 'p%spDOF', 'States per DOF',ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Exc_Init') IF (ErrStat >= AbortErrLev) THEN @@ -139,11 +170,10 @@ SUBROUTINE SS_Exc_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini END IF END DO - ! The input file contains the matrices A [NxN], B [Nx1] and C [6xN], so - !p%N = ( Nlines - 1 ) / 2 ! this is the number of states + ! The input file contains the matrices A [NxN], B [Nx1] and C [6*NBodyxN], so !Verifications on the input file - IF ( ( Nlines - 6 ) / 2 /= p%N) THEN + IF ( ( Nlines - 6*p%NBody ) / 2 /= p%numStates) THEN CALL SetErrStat(ErrID_Severe,'Error in the input file .ssexctn: The size of the matrices does not correspond to the number of states!',ErrStat,ErrMsg,'SS_Exc_Init') END IF @@ -155,9 +185,9 @@ SUBROUTINE SS_Exc_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini ! Now we can allocate the temporary matrices A, B and C - CALL AllocAry( p%A, p%N, p%N, 'p%A', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Exc_Init') - CALL AllocAry( p%B, p%N, 'p%B', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Exc_Init') - CALL AllocAry( p%C, 6, p%N, 'p%C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Exc_Init') + CALL AllocAry( p%A, p%numStates, p%numStates, 'p%A', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Exc_Init') + CALL AllocAry( p%B, p%numStates, 'p%B', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Exc_Init') + CALL AllocAry( p%C, 6*p%NBody, p%numStates, 'p%C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Exc_Init') IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() @@ -174,25 +204,27 @@ SUBROUTINE SS_Exc_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini CALL ReadCom ( UnSS, TRIM(InitInp%InputFile)//'.ssexctn', 'Number of Excitation States', ErrStat2, ErrMsg2 )! Reads the first entire line (Title header) CALL ReadCom ( UnSS, TRIM(InitInp%InputFile)//'.ssexctn', 'Number of states per dofs', ErrStat2, ErrMsg2 )! Reads the first entire line (Title header) - DO I = 1,p%N !Read A MatriX - CALL ReadAry( UnSS,TRIM(InitInp%InputFile)//'.ssexctn', p%A(I,:), p%N, 'p%A', 'A_Matrix',ErrStat2, ErrMsg2) + DO I = 1,p%numStates !Read A MatriX + CALL ReadAry( UnSS,TRIM(InitInp%InputFile)//'.ssexctn', p%A(I,:), p%numStates, 'p%A', 'A_Matrix',ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Exc_Init') END DO - DO I = 1,p%N !Read B Matrix + DO I = 1,p%numStates !Read B Matrix CALL ReadVar( UnSS, TRIM(InitInp%InputFile)//'.ssexctn', p%B(I), 'p%B', 'B_Matrix',ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Exc_Init') END DO - DO I = 1,6 !Read C Matrix - CALL ReadAry( UnSS, TRIM(InitInp%InputFile)//'.ssexctn', p%C(I,:), p%N, 'p%C', 'C_Matrix',ErrStat2, ErrMsg2) + DO I = 1,6*p%NBody !Read C Matrix + CALL ReadAry( UnSS, TRIM(InitInp%InputFile)//'.ssexctn', p%C(I,:), p%numStates, 'p%C', 'C_Matrix',ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Exc_Init') END DO - CLOSE ( UnSS ) !Close .ss input file - UnSS = -1 ! Indicate the file is closed - + CLOSE ( UnSS ) !Close .ss input file + UnSS = -1 ! Indicate the file is closed - CALL WrScr1 ( 'Using SS_Excitation Module, with '//TRIM( Num2LStr(p%N ))//' excitation states' ) + ! Transform the SS c matriX using the heading angles + call TransformStateSpaceMatrices( p%NBody, InitInp%PtfmRefztRot, p%C ) + + CALL WrScr1 ( 'Using SS_Excitation Module, with '//TRIM( Num2LStr(p%numStates ))//' excitation states' ) ! Define parameters here: @@ -201,17 +233,25 @@ SUBROUTINE SS_Exc_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini ! Allocate Wave-elevation related arrays p%NStepWave = InitInp%NStepWave allocate ( p%WaveElev0(0:p%NStepWave) , STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,'Error allocating p%WaveElev0 array',ErrStat,ErrMsg,'SS_Exc_Init') + end if allocate ( p%WaveTime (0:p%NStepWave) , STAT=ErrStat2 ) -!TODO: Error Handling + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,'Error allocating p%WaveTime array',ErrStat,ErrMsg,'SS_Exc_Init') + end if + IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() RETURN END IF - p%WaveTime = InitInp%WaveTime + + p%WaveTime = InitInp%WaveTime p%WaveElev0 = InitInp%WaveElev0 - + + ! Define initial system states here: - CALL AllocAry( x%x, p%N, 'x%x', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Exc_Init') + CALL AllocAry( x%x, p%numStates, 'x%x', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Exc_Init') IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() RETURN @@ -231,21 +271,28 @@ SUBROUTINE SS_Exc_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini ! misc vars: - ! Inputs - ! no inputs + ! Inputs + ! no inputs - ! Define system output initializations (set up mesh) here: - - y%y = 0 - y%WriteOutput = 0 + ! Define system output initializations (set up mesh) here: + call AllocAry( y%y, p%NBody*6, 'y%y', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Exc_Init') + y%y = 0 + call AllocAry( y%WriteOutput, 6*p%NBody+1, 'y%WriteOutput', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + y%WriteOutput = 0 - ! Define initialization-routine output here: - - InitOut%WriteOutputHdr = (/ 'Time', 'FX ' , 'FY ' , 'FZ ' , 'MX ' , 'MY ' , 'MZ ' /) - InitOut%WriteOutputUnt = (/ '(s) ', '(N) ' , '(N) ' , '(N) ' , '(Nm)' , '(Nm)' , '(Nm)' /) - - + ! Define initialization-routine output here: + + ! For OpenFAST, these outputs are attached (via HydroDyn) to the Radiation Force/Moment channels within HydroDyn + call AllocAry( InitOut%WriteOutputHdr, 6*p%NBody+1, 'InitOut%WriteOutputHdr', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + call AllocAry( InitOut%WriteOutputUnt, 6*p%NBody+1, 'InitOut%WriteOutputUnt', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + InitOut%WriteOutputHdr(1) = 'Time' + InitOut%WriteOutputUnt(1) = '(s) ' + do i = 1, p%NBody + bodystr = 'B'//trim(num2lstr(i)) + InitOut%WriteOutputHdr( (i-1)*6+2: (i-1)*6+7 ) = (/ trim(bodystr)//'FX ' , trim(bodystr)//'FY ' , trim(bodystr)//'FZ ' , trim(bodystr)//'MX ' , trim(bodystr)//'MY ' , trim(bodystr)//'MZ ' /) + InitOut%WriteOutputUnt( (i-1)*6+2: (i-1)*6+7 ) = (/ '(N) ' , '(N) ' , '(N) ' , '(Nm)' , '(Nm)' , '(Nm)' /) + end do CALL CleanUp() ! deallocate local arrays CONTAINS @@ -377,8 +424,7 @@ SUBROUTINE SS_Exc_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, E TYPE(SS_Exc_MiscVarType), INTENT(INOUT) :: m !< Initial misc/optimization variables INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None -! REAL(DbKi) :: test(6,1) - + ! Initialize ErrStat ErrStat = ErrID_None ErrMsg = "" @@ -391,7 +437,7 @@ SUBROUTINE SS_Exc_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, E ! Compute outputs here: y%WriteOutput(1) = REAL(Time,ReKi) - y%WriteOutput(2:7) = y%y + y%WriteOutput(2:6*p%NBody+1) = y%y END SUBROUTINE SS_Exc_CalcOutput !---------------------------------------------------------------------------------------------------------------------------------- @@ -417,7 +463,7 @@ SUBROUTINE SS_Exc_CalcContStateDeriv( Time, waveElev0, p, x, xd, z, OtherState, ErrMsg = "" - CALL AllocAry( dxdt%x, p%N, 'SS_Exc_CalcContStateDeriv:dxdt%x', ErrStat, ErrMsg) + CALL AllocAry( dxdt%x, p%numStates, 'SS_Exc_CalcContStateDeriv:dxdt%x', ErrStat, ErrMsg) IF ( ErrStat >= AbortErrLev) RETURN ! Compute the first time derivatives of the continuous states here: diff --git a/modules/hydrodyn/src/SS_Excitation.txt b/modules/hydrodyn/src/SS_Excitation.txt index 1c98d4948b..251d863d7a 100644 --- a/modules/hydrodyn/src/SS_Excitation.txt +++ b/modules/hydrodyn/src/SS_Excitation.txt @@ -15,56 +15,59 @@ # URL: $HeadURL$ ################################################################################################################################### -typedef SS_Excitation/SS_Exc InitInputType CHARACTER(1024) InputFile - - - "Name of the input file" - -typedef ^ ^ ReKi WaveDir - - - "Wave direction" rad -typedef ^ ^ INTEGER NStepWave - - - "Number of timesteps in the WaveTime array" - -typedef ^ ^ SiKi WaveElev0 {:} - - "Wave elevation time history at origin" m -typedef ^ ^ SiKi WaveTime {:} - - "Times where wave elevation is known" s - -typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {7} - - "Header of the output" - -typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputUnt {7} - - "Units of the output" - - -typedef ^ ContinuousStateType R8Ki x {:} - - "Continuous States" - - -typedef ^ DiscreteStateType SiKi DummyDiscState - - - "" - - -# Define constraint states here: -typedef ^ ConstraintStateType SiKi DummyConstrState - - - "" - +typedef SS_Excitation/SS_Exc InitInputType CHARACTER(1024) InputFile - - - "Name of the input file" - +typedef ^ ^ IntKi NBody - - - "Number of WAMIT bodies for this State Space model" - +typedef ^ ^ ReKi WaveDir - - - "Wave direction" rad +typedef ^ ^ INTEGER NStepWave - - - "Number of timesteps in the WaveTime array" - +typedef ^ ^ R8Ki PtfmRefztRot {:} - - "The rotation about zt of the body reference frame(s) from xt/yt" radians +typedef ^ ^ SiKi WaveElev0 {:} - - "Wave elevation time history at origin" m +typedef ^ ^ SiKi WaveTime {:} - - "Times where wave elevation is known" s + +typedef ^ InitOutputType CHARACTER(10) WriteOutputHdr {:} - - "Header of the output" - +typedef ^ InitOutputType CHARACTER(10) WriteOutputUnt {:} - - "Units of the output" - + +typedef ^ ContinuousStateType R8Ki x {:} - - "Continuous States" - + +typedef ^ DiscreteStateType SiKi DummyDiscState - - - "" - + +# Define constraint states here: +typedef ^ ConstraintStateType SiKi DummyConstrState - - - "" - # Define any data that are other states, including integer or logical states here: -typedef ^ OtherStateType IntKi n - - - "Current Time step" - -typedef ^ ^ SS_Exc_ContinuousStateType xdot {4} - - "Old Values of dxdt to used by the solver (multistep method)" - +typedef ^ OtherStateType IntKi n - - - "Current Time step" - +typedef ^ ^ SS_Exc_ContinuousStateType xdot {4} - - "Old Values of dxdt to used by the solver (multistep method)" - # ..... 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 INTEGER LastIndWave - 1 - "last used index in the WaveTime array" - +typedef ^ MiscVarType INTEGER LastIndWave - 1 - "last used index in the WaveTime array" - # ..... Parameters ......................... # Define parameters here: # Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType DbKi DT - - - "Time step" s -typedef ^ ^ INTEGER NStepWave - - - "Number of timesteps in the WaveTime array" - -typedef ^ ^ IntKi spDOF {6} - - "States per DOF" - -typedef ^ ^ ReKi A {:}{:} - - "A matrix" - -typedef ^ ^ ReKi B {:} - - "B matrix" - -typedef ^ ^ ReKi C {:}{:} - - "C matrix" - -typedef ^ ^ INTEGER N - - - "Number of states" - -typedef ^ ^ DbKi Tc - - - "Time shift" s -typedef ^ ^ SiKi WaveElev0 {:} - - "Wave elevation time history at origin" m -typedef ^ ^ SiKi WaveTime {:} - - "Times where wave elevation is known" s +typedef ^ ParameterType DbKi DT - - - "Time step" s +typedef ^ ^ IntKi NBody - - - "Number of WAMIT bodies for this State Space model" - +typedef ^ ^ INTEGER NStepWave - - - "Number of timesteps in the WaveTime array" - +typedef ^ ^ IntKi spDOF {6} - - "States per DOF" - +typedef ^ ^ ReKi A {:}{:} - - "A matrix" - +typedef ^ ^ ReKi B {:} - - "B matrix" - +typedef ^ ^ ReKi C {:}{:} - - "C matrix" - +typedef ^ ^ INTEGER numStates - 0 - "Number of states" - +typedef ^ ^ DbKi Tc - - - "Time shift" s +typedef ^ ^ SiKi WaveElev0 {:} - - "Wave elevation time history at origin" m +typedef ^ ^ SiKi WaveTime {:} - - "Times where wave elevation is known" s # ..... Inputs ............................. # Define inputs that are contained on the mesh here: -typedef ^ InputType ReKi DummyInput - - - "Remove this variable if you have input variables" - +typedef ^ InputType ReKi DummyInput - - - "Remove this variable if you have input variables" - # ..... Outputs ............................ -typedef ^ OutputType ReKi y {6} - - "Force/Moments" - -typedef ^ ^ ReKi WriteOutput {7} - - "output Data" "kN" - +typedef ^ OutputType ReKi y {:} - - "Force/Moments" - +typedef ^ ^ ReKi WriteOutput {:} - - "output Data" "kN" - diff --git a/modules/hydrodyn/src/SS_Excitation_Types.f90 b/modules/hydrodyn/src/SS_Excitation_Types.f90 index 10966b9c6e..1dbef8c916 100644 --- a/modules/hydrodyn/src/SS_Excitation_Types.f90 +++ b/modules/hydrodyn/src/SS_Excitation_Types.f90 @@ -36,16 +36,18 @@ MODULE SS_Excitation_Types ! ========= SS_Exc_InitInputType ======= TYPE, PUBLIC :: SS_Exc_InitInputType CHARACTER(1024) :: InputFile !< Name of the input file [-] + INTEGER(IntKi) :: NBody !< Number of WAMIT bodies for this State Space model [-] REAL(ReKi) :: WaveDir !< Wave direction [rad] INTEGER(IntKi) :: NStepWave !< Number of timesteps in the WaveTime array [-] + REAL(R8Ki) , DIMENSION(:), ALLOCATABLE :: PtfmRefztRot !< The rotation about zt of the body reference frame(s) from xt/yt [radians] REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveElev0 !< Wave elevation time history at origin [m] REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveTime !< Times where wave elevation is known [s] END TYPE SS_Exc_InitInputType ! ======================= ! ========= SS_Exc_InitOutputType ======= TYPE, PUBLIC :: SS_Exc_InitOutputType - CHARACTER(ChanLen) , DIMENSION(1:7) :: WriteOutputHdr !< Header of the output [-] - CHARACTER(ChanLen) , DIMENSION(1:7) :: WriteOutputUnt !< Units of the output [-] + CHARACTER(10) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< Header of the output [-] + CHARACTER(10) , DIMENSION(:), ALLOCATABLE :: WriteOutputUnt !< Units of the output [-] END TYPE SS_Exc_InitOutputType ! ======================= ! ========= SS_Exc_ContinuousStateType ======= @@ -77,12 +79,13 @@ MODULE SS_Excitation_Types ! ========= SS_Exc_ParameterType ======= TYPE, PUBLIC :: SS_Exc_ParameterType REAL(DbKi) :: DT !< Time step [s] + INTEGER(IntKi) :: NBody !< Number of WAMIT bodies for this State Space model [-] INTEGER(IntKi) :: NStepWave !< Number of timesteps in the WaveTime array [-] INTEGER(IntKi) , DIMENSION(1:6) :: spDOF !< States per DOF [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: A !< A matrix [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: B !< B matrix [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: C !< C matrix [-] - INTEGER(IntKi) :: N !< Number of states [-] + INTEGER(IntKi) :: numStates = 0 !< Number of states [-] REAL(DbKi) :: Tc !< Time shift [s] REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveElev0 !< Wave elevation time history at origin [m] REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveTime !< Times where wave elevation is known [s] @@ -95,8 +98,8 @@ MODULE SS_Excitation_Types ! ======================= ! ========= SS_Exc_OutputType ======= TYPE, PUBLIC :: SS_Exc_OutputType - REAL(ReKi) , DIMENSION(1:6) :: y !< Force/Moments [-] - REAL(ReKi) , DIMENSION(1:7) :: WriteOutput !< output Data [kN] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: y !< Force/Moments [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WriteOutput !< output Data [kN] END TYPE SS_Exc_OutputType ! ======================= CONTAINS @@ -117,8 +120,21 @@ SUBROUTINE SS_Exc_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, E ErrStat = ErrID_None ErrMsg = "" DstInitInputData%InputFile = SrcInitInputData%InputFile + DstInitInputData%NBody = SrcInitInputData%NBody DstInitInputData%WaveDir = SrcInitInputData%WaveDir DstInitInputData%NStepWave = SrcInitInputData%NStepWave +IF (ALLOCATED(SrcInitInputData%PtfmRefztRot)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmRefztRot,1) + i1_u = UBOUND(SrcInitInputData%PtfmRefztRot,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmRefztRot)) THEN + ALLOCATE(DstInitInputData%PtfmRefztRot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmRefztRot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmRefztRot = SrcInitInputData%PtfmRefztRot +ENDIF IF (ALLOCATED(SrcInitInputData%WaveElev0)) THEN i1_l = LBOUND(SrcInitInputData%WaveElev0,1) i1_u = UBOUND(SrcInitInputData%WaveElev0,1) @@ -154,6 +170,9 @@ SUBROUTINE SS_Exc_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(InitInputData%PtfmRefztRot)) THEN + DEALLOCATE(InitInputData%PtfmRefztRot) +ENDIF IF (ALLOCATED(InitInputData%WaveElev0)) THEN DEALLOCATE(InitInputData%WaveElev0) ENDIF @@ -198,8 +217,14 @@ SUBROUTINE SS_Exc_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Db_BufSz = 0 Int_BufSz = 0 Int_BufSz = Int_BufSz + 1*LEN(InData%InputFile) ! InputFile + Int_BufSz = Int_BufSz + 1 ! NBody Re_BufSz = Re_BufSz + 1 ! WaveDir Int_BufSz = Int_BufSz + 1 ! NStepWave + Int_BufSz = Int_BufSz + 1 ! PtfmRefztRot allocated yes/no + IF ( ALLOCATED(InData%PtfmRefztRot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmRefztRot upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%PtfmRefztRot) ! PtfmRefztRot + END IF Int_BufSz = Int_BufSz + 1 ! WaveElev0 allocated yes/no IF ( ALLOCATED(InData%WaveElev0) ) THEN Int_BufSz = Int_BufSz + 2*1 ! WaveElev0 upper/lower bounds for each dimension @@ -241,10 +266,27 @@ SUBROUTINE SS_Exc_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er IntKiBuf(Int_Xferred) = ICHAR(InData%InputFile(I:I), IntKi) Int_Xferred = Int_Xferred + 1 END DO ! I + IntKiBuf(Int_Xferred) = InData%NBody + Int_Xferred = Int_Xferred + 1 ReKiBuf(Re_Xferred) = InData%WaveDir Re_Xferred = Re_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NStepWave Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%PtfmRefztRot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmRefztRot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmRefztRot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmRefztRot,1), UBOUND(InData%PtfmRefztRot,1) + DbKiBuf(Db_Xferred) = InData%PtfmRefztRot(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF IF ( .NOT. ALLOCATED(InData%WaveElev0) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -309,10 +351,30 @@ SUBROUTINE SS_Exc_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, OutData%InputFile(I:I) = CHAR(IntKiBuf(Int_Xferred)) Int_Xferred = Int_Xferred + 1 END DO ! I + OutData%NBody = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%WaveDir = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%NStepWave = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmRefztRot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmRefztRot)) DEALLOCATE(OutData%PtfmRefztRot) + ALLOCATE(OutData%PtfmRefztRot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmRefztRot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmRefztRot,1), UBOUND(OutData%PtfmRefztRot,1) + OutData%PtfmRefztRot(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveElev0 not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -366,8 +428,30 @@ SUBROUTINE SS_Exc_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(SrcInitOutputData%WriteOutputHdr)) THEN + i1_l = LBOUND(SrcInitOutputData%WriteOutputHdr,1) + i1_u = UBOUND(SrcInitOutputData%WriteOutputHdr,1) + IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputHdr)) THEN + ALLOCATE(DstInitOutputData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInitOutputData%WriteOutputHdr = SrcInitOutputData%WriteOutputHdr +ENDIF +IF (ALLOCATED(SrcInitOutputData%WriteOutputUnt)) THEN + i1_l = LBOUND(SrcInitOutputData%WriteOutputUnt,1) + i1_u = UBOUND(SrcInitOutputData%WriteOutputUnt,1) + IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputUnt)) THEN + ALLOCATE(DstInitOutputData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInitOutputData%WriteOutputUnt = SrcInitOutputData%WriteOutputUnt +ENDIF END SUBROUTINE SS_Exc_CopyInitOutput SUBROUTINE SS_Exc_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) @@ -379,6 +463,12 @@ SUBROUTINE SS_Exc_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN + DEALLOCATE(InitOutputData%WriteOutputHdr) +ENDIF +IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN + DEALLOCATE(InitOutputData%WriteOutputUnt) +ENDIF END SUBROUTINE SS_Exc_DestroyInitOutput SUBROUTINE SS_Exc_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -416,8 +506,16 @@ SUBROUTINE SS_Exc_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! WriteOutputHdr allocated yes/no + IF ( ALLOCATED(InData%WriteOutputHdr) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WriteOutputHdr upper/lower bounds for each dimension Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputHdr)*LEN(InData%WriteOutputHdr) ! WriteOutputHdr + END IF + Int_BufSz = Int_BufSz + 1 ! WriteOutputUnt allocated yes/no + IF ( ALLOCATED(InData%WriteOutputUnt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WriteOutputUnt upper/lower bounds for each dimension Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputUnt)*LEN(InData%WriteOutputUnt) ! WriteOutputUnt + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -445,18 +543,40 @@ SUBROUTINE SS_Exc_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Db_Xferred = 1 Int_Xferred = 1 - DO i1 = LBOUND(InData%WriteOutputHdr,1), UBOUND(InData%WriteOutputHdr,1) - DO I = 1, LEN(InData%WriteOutputHdr) - IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputHdr(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - DO i1 = LBOUND(InData%WriteOutputUnt,1), UBOUND(InData%WriteOutputUnt,1) - DO I = 1, LEN(InData%WriteOutputUnt) - IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputUnt(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO + IF ( .NOT. ALLOCATED(InData%WriteOutputHdr) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutputHdr,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputHdr,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WriteOutputHdr,1), UBOUND(InData%WriteOutputHdr,1) + DO I = 1, LEN(InData%WriteOutputHdr) + IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputHdr(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WriteOutputUnt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutputUnt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputUnt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WriteOutputUnt,1), UBOUND(InData%WriteOutputUnt,1) + DO I = 1, LEN(InData%WriteOutputUnt) + IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputUnt(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF END SUBROUTINE SS_Exc_PackInitOutput SUBROUTINE SS_Exc_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -486,22 +606,46 @@ SUBROUTINE SS_Exc_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - i1_l = LBOUND(OutData%WriteOutputHdr,1) - i1_u = UBOUND(OutData%WriteOutputHdr,1) - DO i1 = LBOUND(OutData%WriteOutputHdr,1), UBOUND(OutData%WriteOutputHdr,1) - DO I = 1, LEN(OutData%WriteOutputHdr) - OutData%WriteOutputHdr(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - i1_l = LBOUND(OutData%WriteOutputUnt,1) - i1_u = UBOUND(OutData%WriteOutputUnt,1) - DO i1 = LBOUND(OutData%WriteOutputUnt,1), UBOUND(OutData%WriteOutputUnt,1) - DO I = 1, LEN(OutData%WriteOutputUnt) - OutData%WriteOutputUnt(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputHdr not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WriteOutputHdr)) DEALLOCATE(OutData%WriteOutputHdr) + ALLOCATE(OutData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WriteOutputHdr,1), UBOUND(OutData%WriteOutputHdr,1) + DO I = 1, LEN(OutData%WriteOutputHdr) + OutData%WriteOutputHdr(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputUnt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WriteOutputUnt)) DEALLOCATE(OutData%WriteOutputUnt) + ALLOCATE(OutData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WriteOutputUnt,1), UBOUND(OutData%WriteOutputUnt,1) + DO I = 1, LEN(OutData%WriteOutputUnt) + OutData%WriteOutputUnt(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF END SUBROUTINE SS_Exc_UnPackInitOutput SUBROUTINE SS_Exc_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg ) @@ -1299,6 +1443,7 @@ SUBROUTINE SS_Exc_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrM ErrStat = ErrID_None ErrMsg = "" DstParamData%DT = SrcParamData%DT + DstParamData%NBody = SrcParamData%NBody DstParamData%NStepWave = SrcParamData%NStepWave DstParamData%spDOF = SrcParamData%spDOF IF (ALLOCATED(SrcParamData%A)) THEN @@ -1341,7 +1486,7 @@ SUBROUTINE SS_Exc_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrM END IF DstParamData%C = SrcParamData%C ENDIF - DstParamData%N = SrcParamData%N + DstParamData%numStates = SrcParamData%numStates DstParamData%Tc = SrcParamData%Tc IF (ALLOCATED(SrcParamData%WaveElev0)) THEN i1_l = LBOUND(SrcParamData%WaveElev0,1) @@ -1431,6 +1576,7 @@ SUBROUTINE SS_Exc_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Db_BufSz = 0 Int_BufSz = 0 Db_BufSz = Db_BufSz + 1 ! DT + Int_BufSz = Int_BufSz + 1 ! NBody Int_BufSz = Int_BufSz + 1 ! NStepWave Int_BufSz = Int_BufSz + SIZE(InData%spDOF) ! spDOF Int_BufSz = Int_BufSz + 1 ! A allocated yes/no @@ -1448,7 +1594,7 @@ SUBROUTINE SS_Exc_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 2*2 ! C upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%C) ! C END IF - Int_BufSz = Int_BufSz + 1 ! N + Int_BufSz = Int_BufSz + 1 ! numStates Db_BufSz = Db_BufSz + 1 ! Tc Int_BufSz = Int_BufSz + 1 ! WaveElev0 allocated yes/no IF ( ALLOCATED(InData%WaveElev0) ) THEN @@ -1489,6 +1635,8 @@ SUBROUTINE SS_Exc_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg DbKiBuf(Db_Xferred) = InData%DT Db_Xferred = Db_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NBody + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NStepWave Int_Xferred = Int_Xferred + 1 DO i1 = LBOUND(InData%spDOF,1), UBOUND(InData%spDOF,1) @@ -1550,7 +1698,7 @@ SUBROUTINE SS_Exc_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg END DO END DO END IF - IntKiBuf(Int_Xferred) = InData%N + IntKiBuf(Int_Xferred) = InData%numStates Int_Xferred = Int_Xferred + 1 DbKiBuf(Db_Xferred) = InData%Tc Db_Xferred = Db_Xferred + 1 @@ -1616,6 +1764,8 @@ SUBROUTINE SS_Exc_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Int_Xferred = 1 OutData%DT = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 + OutData%NBody = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%NStepWave = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 i1_l = LBOUND(OutData%spDOF,1) @@ -1688,7 +1838,7 @@ SUBROUTINE SS_Exc_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err END DO END DO END IF - OutData%N = IntKiBuf(Int_Xferred) + OutData%numStates = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%Tc = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 @@ -1870,8 +2020,30 @@ SUBROUTINE SS_Exc_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, E ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(SrcOutputData%y)) THEN + i1_l = LBOUND(SrcOutputData%y,1) + i1_u = UBOUND(SrcOutputData%y,1) + IF (.NOT. ALLOCATED(DstOutputData%y)) THEN + ALLOCATE(DstOutputData%y(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%y.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstOutputData%y = SrcOutputData%y +ENDIF +IF (ALLOCATED(SrcOutputData%WriteOutput)) THEN + i1_l = LBOUND(SrcOutputData%WriteOutput,1) + i1_u = UBOUND(SrcOutputData%WriteOutput,1) + IF (.NOT. ALLOCATED(DstOutputData%WriteOutput)) THEN + ALLOCATE(DstOutputData%WriteOutput(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%WriteOutput.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstOutputData%WriteOutput = SrcOutputData%WriteOutput +ENDIF END SUBROUTINE SS_Exc_CopyOutput SUBROUTINE SS_Exc_DestroyOutput( OutputData, ErrStat, ErrMsg ) @@ -1883,6 +2055,12 @@ SUBROUTINE SS_Exc_DestroyOutput( OutputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(OutputData%y)) THEN + DEALLOCATE(OutputData%y) +ENDIF +IF (ALLOCATED(OutputData%WriteOutput)) THEN + DEALLOCATE(OutputData%WriteOutput) +ENDIF END SUBROUTINE SS_Exc_DestroyOutput SUBROUTINE SS_Exc_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1920,8 +2098,16 @@ SUBROUTINE SS_Exc_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! y allocated yes/no + IF ( ALLOCATED(InData%y) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! y upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%y) ! y + END IF + Int_BufSz = Int_BufSz + 1 ! WriteOutput allocated yes/no + IF ( ALLOCATED(InData%WriteOutput) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WriteOutput upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WriteOutput) ! WriteOutput + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1949,14 +2135,36 @@ SUBROUTINE SS_Exc_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_Xferred = 1 Int_Xferred = 1 - DO i1 = LBOUND(InData%y,1), UBOUND(InData%y,1) - ReKiBuf(Re_Xferred) = InData%y(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%WriteOutput,1), UBOUND(InData%WriteOutput,1) - ReKiBuf(Re_Xferred) = InData%WriteOutput(i1) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( .NOT. ALLOCATED(InData%y) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%y,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%y,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%y,1), UBOUND(InData%y,1) + ReKiBuf(Re_Xferred) = InData%y(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WriteOutput) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutput,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutput,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WriteOutput,1), UBOUND(InData%WriteOutput,1) + ReKiBuf(Re_Xferred) = InData%WriteOutput(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE SS_Exc_PackOutput SUBROUTINE SS_Exc_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1986,18 +2194,42 @@ SUBROUTINE SS_Exc_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - i1_l = LBOUND(OutData%y,1) - i1_u = UBOUND(OutData%y,1) - DO i1 = LBOUND(OutData%y,1), UBOUND(OutData%y,1) - OutData%y(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%WriteOutput,1) - i1_u = UBOUND(OutData%WriteOutput,1) - DO i1 = LBOUND(OutData%WriteOutput,1), UBOUND(OutData%WriteOutput,1) - OutData%WriteOutput(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! y not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%y)) DEALLOCATE(OutData%y) + ALLOCATE(OutData%y(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%y.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%y,1), UBOUND(OutData%y,1) + OutData%y(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutput not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WriteOutput)) DEALLOCATE(OutData%WriteOutput) + ALLOCATE(OutData%WriteOutput(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutput.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WriteOutput,1), UBOUND(OutData%WriteOutput,1) + OutData%WriteOutput(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE SS_Exc_UnPackOutput @@ -2250,14 +2482,18 @@ SUBROUTINE SS_Exc_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, Err END IF ScaleFactor = t_out / t(2) +IF (ALLOCATED(y_out%y) .AND. ALLOCATED(y1%y)) THEN DO i1 = LBOUND(y_out%y,1),UBOUND(y_out%y,1) b = -(y1%y(i1) - y2%y(i1)) y_out%y(i1) = y1%y(i1) + b * ScaleFactor END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) b = -(y1%WriteOutput(i1) - y2%WriteOutput(i1)) y_out%WriteOutput(i1) = y1%WriteOutput(i1) + b * ScaleFactor END DO +END IF ! check if allocated END SUBROUTINE SS_Exc_Output_ExtrapInterp1 @@ -2315,16 +2551,20 @@ SUBROUTINE SS_Exc_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, END IF ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) +IF (ALLOCATED(y_out%y) .AND. ALLOCATED(y1%y)) THEN DO i1 = LBOUND(y_out%y,1),UBOUND(y_out%y,1) b = (t(3)**2*(y1%y(i1) - y2%y(i1)) + t(2)**2*(-y1%y(i1) + y3%y(i1)))* scaleFactor c = ( (t(2)-t(3))*y1%y(i1) + t(3)*y2%y(i1) - t(2)*y3%y(i1) ) * scaleFactor y_out%y(i1) = y1%y(i1) + b + c * t_out END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) b = (t(3)**2*(y1%WriteOutput(i1) - y2%WriteOutput(i1)) + t(2)**2*(-y1%WriteOutput(i1) + y3%WriteOutput(i1)))* scaleFactor c = ( (t(2)-t(3))*y1%WriteOutput(i1) + t(3)*y2%WriteOutput(i1) - t(2)*y3%WriteOutput(i1) ) * scaleFactor y_out%WriteOutput(i1) = y1%WriteOutput(i1) + b + c * t_out END DO +END IF ! check if allocated END SUBROUTINE SS_Exc_Output_ExtrapInterp2 END MODULE SS_Excitation_Types diff --git a/modules/hydrodyn/src/SS_Radiation.f90 b/modules/hydrodyn/src/SS_Radiation.f90 index 62a9b873d1..d7635499dd 100644 --- a/modules/hydrodyn/src/SS_Radiation.f90 +++ b/modules/hydrodyn/src/SS_Radiation.f90 @@ -45,7 +45,45 @@ MODULE SS_Radiation PUBLIC :: SS_Rad_UpdateDiscState ! Tight coupling routine for updating discrete states -CONTAINS + CONTAINS + +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine transforms the State Space input file data from a local (heading-angle, based) coordinate system to the global system. +!> NOTE: This routine ONLY works if all the DOFs are enabled!!!!!!!!!! +subroutine TransformStateSpaceMatrices( NBody, RotZ, B, C ) +!.................................................................................................................................. + integer(IntKi), intent( in ) :: NBody ! Number of WAMIT bodies in this WAMIT object ( = 1 if NBodyMod > 1) + real(R8Ki), intent( in ) :: RotZ(:) ! NBody heading angles (radians) + real(ReKi), intent( inout ) :: B(:,:) ! Matrix data to be transformed, if NBodyMOD = 1 and NBody > 1 then we will be transforming the individual sub 6x6 matrices + real(ReKi), intent( inout ) :: C(:,:) ! Matrix data to be transformed, if NBodyMOD = 1 and NBody > 1 then we will be transforming the individual sub 6x6 matrices + + integer(IntKi) :: i,j,indx + real(R8Ki) :: R(3,3) + real(R8Ki) :: Rt(3,3) + + !do j = 1, NBody + ! Rj(1,:) = (/ cos(RotZ(j)), sin(RotZ(j)), 0.0_R8Ki/) + ! Rj(2,:) = (/-sin(RotZ(j)), cos(RotZ(j)), 0.0_R8Ki/) + ! Rj(3,:) = (/ 0.0_R8Ki , 0.0_R8Ki , 1.0_R8Ki/) + do i = 1, NBody + if ( .not. EqualRealNos(RotZ(i), 0.0_R8Ki) ) then + R(1,:) = (/ cos(RotZ(i)), sin(RotZ(i)), 0.0_R8Ki/) + R(2,:) = (/-sin(RotZ(i)), cos(RotZ(i)), 0.0_R8Ki/) + R(3,:) = (/ 0.0_R8Ki , 0.0_R8Ki , 1.0_R8Ki/) + Rt = transpose(R) + do j = 1,2 ! Need to do this twice, since a single R (3x3) matrix is used to transform all 6 DOFs associated with the ith Body data + indx = (i-1)*6 + (j-1)*3 + 1 + ! Create sub matrix which is all rows of B but only necessary columns for transformation work, NOTE: B is numStates X (6*NBody) + B(:,indx:indx+2) = matmul( B(:,indx:indx+2), R ) + ! Create sub matrix which is all columns of C but only necessary rows for transformation work, NOTE: c is (6*NBody) X numStates + C(indx:indx+2,:) = matmul( Rt, C(indx:indx+2,:) ) + end do + end if + end do + + ! end do +end subroutine TransformStateSpaceMatrices + !---------------------------------------------------------------------------------------------------------------------------------- !> This routine is called at the start of the simulation to perform initialization steps. !! The parameters are set here and not changed during the simulation. @@ -80,15 +118,14 @@ SUBROUTINE SS_Rad_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini REAL(ReKi), ALLOCATABLE :: Rad_C (:,:) ! C matrix of the radiation state-space system on the input file ss INTEGER :: I ! Generic index -! INTEGER :: J ! Generic index - INTEGER :: xx (1,6) ! Active DOF's on the input file .ss - INTEGER :: DOFs ! Number of DOFS - INTEGER :: N ! Number of states + INTEGER, allocatable :: xx (:) ! Active DOF's on the input file .ss + INTEGER :: numDOFs ! Number of DOFS + INTEGER :: numStates ! Number of states + integer(IntKi) :: N ! Counter INTEGER :: Nlines ! Number of lines in the input file, used to determine N INTEGER :: UnSS ! I/O unit number for the WAMIT output file with the .ss extension; this file contains the state-space matrices. INTEGER :: Sttus ! Error in reading .ss file - !CHARACTER :: Line ! Temp line of file - + character(3) :: bodystr integer :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 @@ -98,7 +135,9 @@ SUBROUTINE SS_Rad_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini UnSS = -1 N = 0 - + numStates = 0 + p%NBody = InitInp%NBody ! Number of WAMIT bodies: =1 if WAMIT is using NBodyMod > 1, >=1 if NBodyMod=1 + ! Open the .ss input file! CALL GetNewUnit( UnSS ) CALL OpenFInpFile ( UnSS, TRIM(InitInp%InputFile)//'.ss', ErrStat2, ErrMsg2 ) ! Open file. @@ -112,12 +151,14 @@ SUBROUTINE SS_Rad_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini Nlines = 1 CALL ReadCom ( UnSS, TRIM(InitInp%InputFile)//'.ss', 'Header',ErrStat2, ErrMsg2 )! Reads the first entire line (Title header) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') - CALL ReadAry( UnSS,TRIM(InitInp%InputFile)//'.ss', xx(1,:), 6, 'xx', 'xx vector containing the enabled dofs',ErrStat2, ErrMsg2) ! Reads in the second line, containing the active dofs vector + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + call AllocAry( xx, 6*p%NBody, 'xx', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + CALL ReadAry( UnSS,TRIM(InitInp%InputFile)//'.ss', xx(:), 6*p%NBody, 'xx', 'xx vector containing the enabled dofs',ErrStat2, ErrMsg2) ! Reads in the second line, containing the active dofs vector CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') - CALL ReadVar( UnSS,TRIM(InitInp%InputFile)//'.ss', N, 'N', 'Number of Dofs',ErrStat2, ErrMsg2) ! Reads in the third line, containing the number of states + CALL ReadVar( UnSS,TRIM(InitInp%InputFile)//'.ss', numStates, 'numStates', 'Number of States',ErrStat2, ErrMsg2) ! Reads in the third line, containing the number of states CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') - CALL ReadAry( UnSS,TRIM(InitInp%InputFile)//'.ss', p%spdof, 6, 'spdof', 'spdof vector containing the number of states per dofs',ErrStat2, ErrMsg2) ! Reads in the forth line, containing the state per dofs vector + call AllocAry( p%spdof, 6*p%NBody, 'p%spdof', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + CALL ReadAry( UnSS,TRIM(InitInp%InputFile)//'.ss', p%spdof, 6*p%NBody, 'spdof', 'spdof vector containing the number of states per dofs',ErrStat2, ErrMsg2) ! Reads in the forth line, containing the state per dofs vector CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() @@ -133,28 +174,28 @@ SUBROUTINE SS_Rad_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini END IF END DO - ! The input file contains the matrices A [NxN], B [Nx6] and C [6xN], so - !p%N = ( Nlines - 6 ) / 2 ! this is the number of states + ! The input file contains the matrices A [NxN], B [N x 6*NBody] and C [6*NBody x N], so + !p%numStates = ( Nlines - 6*p%NBody ) / 2 ! this is the number of states !Verifications on the input file - IF ( ( Nlines - 6 ) / 2 /= N) THEN + IF ( ( Nlines - 6*p%NBody ) / 2 /= numStates) THEN CALL SetErrStat(ErrID_Severe,'Error in the input file .ss: The size of the matrices does not correspond to the number of states!',ErrStat,ErrMsg,'SS_Rad_Init') END IF - IF ( N /= SUM(p%spdof)) THEN + IF ( numStates /= SUM(p%spdof)) THEN CALL SetErrStat(ErrID_Severe,'Error in the input file .ss: The size of the matrices does not correspond to the number of states!',ErrStat,ErrMsg,'SS_Rad_Init') END IF !Verify if the DOFs active in the input file correspond to the ones active by FAST in this run - DO I=1,6 !Loop through all 6 DOFs - IF ( InitInp%DOFs (1,I) == 1) THEN ! True when the current DOF is active in FAST - IF ( xx (1,I) /= 1) THEN ! True if a DOF enabled by FAST is not available in the INPUT File + DO I=1,6*p%NBody !Loop through all 6 DOFs + IF ( InitInp%enabledDOFs (I) == 1) THEN ! True when the current DOF is active in FAST + IF ( xx (I) /= 1) THEN ! True if a DOF enabled by FAST is not available in the INPUT File CALL SetErrStat(ErrID_Severe,'Error in the input file .ss: The enabled DOFs in the current FAST Simulation don`t match the ones on the input file .ss!',ErrStat,ErrMsg,'SS_Rad_Init') END IF END IF END DO - DOFs = SUM (xx) !Number of DOFS in the input file + numDOFs = SUM (xx) !Number of DOFS in the input file IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() @@ -163,9 +204,9 @@ SUBROUTINE SS_Rad_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini ! Now we can allocate the temporary matrices A, B and C - CALL AllocAry( Rad_A, N, N, 'Rad_A', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') - CALL AllocAry( Rad_B, N, DOFs, 'Rad_B', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') - CALL AllocAry( Rad_C, DOFs, N, 'Rad_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + CALL AllocAry( Rad_A, numStates, numStates, 'Rad_A', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + CALL AllocAry( Rad_B, numStates, numDOFs, 'Rad_B', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + CALL AllocAry( Rad_C, numDOFs, numStates, 'Rad_C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() @@ -178,41 +219,45 @@ SUBROUTINE SS_Rad_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini ! Skip the first 4 lines: (NOTE: no error handling here because we would have caught it the first time through) CALL ReadCom ( UnSS, TRIM(InitInp%InputFile)//'.ss', 'Header', ErrStat2, ErrMsg2 )! Reads the first entire line (Title header) CALL ReadCom ( UnSS, TRIM(InitInp%InputFile)//'.ss', 'Enabled dofs', ErrStat2, ErrMsg2 )! Reads the first entire line (Title header) - CALL ReadCom ( UnSS, TRIM(InitInp%InputFile)//'.ss', 'N', ErrStat2, ErrMsg2 )! Reads the first entire line (Title header) - CALL ReadCom ( UnSS, TRIM(InitInp%InputFile)//'.ss', 'N per dofs', ErrStat2, ErrMsg2 )! Reads the first entire line (Title header) + CALL ReadCom ( UnSS, TRIM(InitInp%InputFile)//'.ss', 'numStates', ErrStat2, ErrMsg2 )! Reads the first entire line (Title header) + CALL ReadCom ( UnSS, TRIM(InitInp%InputFile)//'.ss', 'numStates per dofs', ErrStat2, ErrMsg2 )! Reads the first entire line (Title header) - DO I = 1,N !Read A MatriX - CALL ReadAry( UnSS,TRIM(InitInp%InputFile)//'.ss', Rad_A(I,:), N, 'Rad_A', 'A_Matrix',ErrStat2, ErrMsg2) + DO I = 1,numStates !Read A MatriX + CALL ReadAry( UnSS,TRIM(InitInp%InputFile)//'.ss', Rad_A(I,:), numStates, 'Rad_A', 'A_Matrix',ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') END DO - DO I = 1,N !Read B Matrix - CALL ReadAry( UnSS, TRIM(InitInp%InputFile)//'.ss', Rad_B(I,:), 6, 'Rad_B', 'B_Matrix',ErrStat2, ErrMsg2) + DO I = 1,numStates !Read B Matrix + CALL ReadAry( UnSS, TRIM(InitInp%InputFile)//'.ss', Rad_B(I,:), 6*p%NBody, 'Rad_B', 'B_Matrix',ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') END DO - DO I = 1,6 !Read C Matrix - CALL ReadAry( UnSS, TRIM(InitInp%InputFile)//'.ss', Rad_C(I,:), N, 'Rad_C', 'C_Matrix',ErrStat2, ErrMsg2) + DO I = 1,6*p%NBody !Read C Matrix + CALL ReadAry( UnSS, TRIM(InitInp%InputFile)//'.ss', Rad_C(I,:), numStates, 'Rad_C', 'C_Matrix',ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') END DO CLOSE ( UnSS ) !Close .ss input file UnSS = -1 ! Indicate the file is closed + ! Transform the SS matrices using the heading angles + ! NOTE: This transformation routine ONLY works if all the DOFs are enabled so we will do it on Rad_B and Rad_C which have all DOFs !!!!!!!!!! + call TransformStateSpaceMatrices( p%NBody, InitInp%PtfmRefztRot, Rad_B, Rad_C ) + !Now we are ready to reduce the matrices to the correspondent active dofs in FAST - p%N=0 - DO I=1,6 !For each state - IF ( InitInp%DOFs (1,I) == 1) THEN ! True when the current DOF is active in FAST - p%N = p%N + p%spdof(I) !Add the correspondent number of states to the vector + p%numStates=0 + DO I=1,6*p%NBody !For each state + IF ( InitInp%enabledDOFs (I) == 1) THEN ! True when the current DOF is active in FAST + p%numStates = p%numStates + p%spdof(I) !Add the correspondent number of states to the vector END IF END DO - CALL WrScr1 ( 'Using SS_Radiation Module, with '//TRIM( Num2LStr(p%N ))//' of '//TRIM( Num2LStr(N ))// ' radiation states' ) + CALL WrScr1 ( 'Using SS_Radiation Module, with '//TRIM( Num2LStr(p%numStates ))//' of '//TRIM( Num2LStr(numStates ))// ' radiation states' ) !Now we can allocate the final size of the SS matrices - CALL AllocAry( p%A, p%N, p%N, 'p%A', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') - CALL AllocAry( p%B, p%N, 6, 'p%B', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') - CALL AllocAry( p%c, 6, p%N, 'p%C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + CALL AllocAry( p%A, p%numStates, p%numStates, 'p%A', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + CALL AllocAry( p%B, p%numStates, 6*p%NBody, 'p%B', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + CALL AllocAry( p%C, 6*p%NBody, p%numStates, 'p%C', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') ! if these arrays weren't allocated, return before a seg fault occurs: IF (ErrStat >= AbortErrLev) THEN @@ -223,12 +268,12 @@ SUBROUTINE SS_Rad_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini !Finaly we write the ss matrices, based on the ones on the input file and on the active dofs - IF ( p%N == N ) THEN !The matrices are the same + IF ( p%numStates == numStates ) THEN !The matrices are the same p%A = Rad_A p%B = Rad_B p%C = Rad_C - + ELSE !We need to cut some of the lines and columns p%A = 0 @@ -238,8 +283,8 @@ SUBROUTINE SS_Rad_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini N=1 !Use as number of active states introduced - DO I=1,6 !For each dof... - IF ( InitInp%DOFs (1,I) == 1 .AND. sum(p%spdof(1:I))= AbortErrLev) THEN CALL CleanUp() RETURN END IF - x%x = 0 + x%x = 0 - xd%DummyDiscState = 0 !TD: SS doesn't have disc states - z%DummyConstrState = 0 !TD: SS doesn't have constr states + xd%DummyDiscState = 0 !TD: SS doesn't have disc states + z%DummyConstrState = 0 !TD: SS doesn't have constr states - ! Define other States: - DO I=1,SIZE(OtherState%xdot) - CALL SS_Rad_CopyContState( x, OtherState%xdot(i), MESH_NEWCOPY, ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') - END DO - OtherState%n = -1 - - ! misc vars: - m%DummyMiscVar = 0 + ! Define other States: + DO I=1,SIZE(OtherState%xdot) + CALL SS_Rad_CopyContState( x, OtherState%xdot(i), MESH_NEWCOPY, ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + END DO + OtherState%n = -1 + +! misc vars: + m%DummyMiscVar = 0 - !Inputs - u%dq = 0 !6 DoF's velocities - - ! Define system output initializations (set up mesh) here: - - y%y = 0 - y%WriteOutput = 0 + !Inputs + call AllocAry( u%dq, 6*p%NBody, 'u%dq', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + u%dq = 0 !All DoF's velocities + + ! Define system output initializations (set up mesh) here: + call AllocAry( y%y, 6*p%NBody+1, 'y%y', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + call AllocAry( y%WriteOutput, 6*p%NBody+1, 'y%WriteOutput', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + y%y = 0 + y%WriteOutput = 0 - ! Define initialization-routine output here: - - InitOut%WriteOutputHdr = (/ 'Time', 'F1 ' , 'F2 ' , 'F3 ' , 'F4 ' , 'F5 ' , 'F6 ' /) - InitOut%WriteOutputUnt = (/ '(s) ', '(N) ' , '(N) ' , '(N) ' , '(Nm)' , '(Nm)' , '(Nm)' /) - - ! If you want to choose your own rate instead of using what the glue code suggests, tell the glue code the rate at which - ! this module must be called here: + ! Define initialization-routine output here: + + ! This output channels are only used by the stand-alone driver program and not by the OpenFAST coupled version. + ! For OpenFAST, these outputs are attached (via HydroDyn) to the Radiation Force/Moment channels within HydroDyn + + call AllocAry( InitOut%WriteOutputHdr, 6*p%NBody+1, 'InitOut%WriteOutputHdr', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + call AllocAry( InitOut%WriteOutputUnt, 6*p%NBody+1, 'InitOut%WriteOutputUnt', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SS_Rad_Init') + + InitOut%WriteOutputHdr(1) = 'Time' + InitOut%WriteOutputUnt(1) = '(s) ' + do i = 1, p%NBody + bodystr = 'B'//trim(num2lstr(i)) + InitOut%WriteOutputHdr( (i-1)*6+2: (i-1)*6+7 ) = (/ trim(bodystr)//'FX ' , trim(bodystr)//'FY ' , trim(bodystr)//'FZ ' , trim(bodystr)//'MX ' , trim(bodystr)//'MY ' , trim(bodystr)//'MZ ' /) + InitOut%WriteOutputUnt( (i-1)*6+2: (i-1)*6+7 ) = (/ '(N) ' , '(N) ' , '(N) ' , '(Nm)' , '(Nm)' , '(Nm)' /) + end do + ! If you want to choose your own rate instead of using what the glue code suggests, tell the glue code the rate at which + ! this module must be called here: - !p%DT=Interval - + !p%DT=Interval + CALL CleanUp() ! deallocate local arrays CONTAINS @@ -443,7 +500,7 @@ SUBROUTINE SS_Rad_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, E ! Compute outputs here: y%WriteOutput(1) = REAL(Time,ReKi) - y%WriteOutput(2:7) = y%y + y%WriteOutput(2:6*p%NBody+1) = y%y END SUBROUTINE SS_Rad_CalcOutput !---------------------------------------------------------------------------------------------------------------------------------- @@ -468,8 +525,8 @@ SUBROUTINE SS_Rad_CalcContStateDeriv( Time, u, p, x, xd, z, OtherState, m, dxdt, ErrStat = ErrID_None ErrMsg = "" - - CALL AllocAry( dxdt%x, p%N, 'SS_Rad_CalcContStateDeriv:dxdt%x', ErrStat, ErrMsg) + + CALL AllocAry( dxdt%x, p%numStates, 'SS_Rad_CalcContStateDeriv:dxdt%x', ErrStat, ErrMsg) IF ( ErrStat >= AbortErrLev) RETURN ! Compute the first time derivatives of the continuous states here: diff --git a/modules/hydrodyn/src/SS_Radiation.txt b/modules/hydrodyn/src/SS_Radiation.txt index 1d8866dea8..07e6d29ab7 100644 --- a/modules/hydrodyn/src/SS_Radiation.txt +++ b/modules/hydrodyn/src/SS_Radiation.txt @@ -11,23 +11,24 @@ # column 10: Units ################################################################################################################################### -typedef SS_Radiation/SS_Rad InitInputType CHARACTER(1024) InputFile - - - "Name of the input file" - -typedef ^ ^ ReKi DOFs {1}{6} - - "Vector with enable platf. DOFs" "m/s or rad/s" +typedef SS_Radiation/SS_Rad InitInputType CHARACTER(1024) InputFile - - - "Name of the input file" - +typedef ^ ^ ReKi enabledDOFs {:} - - "Vector with enable platf. DOFs" (m/s or rad/s) +typedef ^ ^ IntKi NBody - - - "Number of WAMIT bodies for this State Space model" - +typedef ^ ^ R8Ki PtfmRefztRot {:} - - "The rotation about zt of the body reference frame(s) from xt/yt" radians -typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {7} - - "Header of the output" - -typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputUnt {7} - - "Units of the output" - +typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {:} - - "Header of the output" - +typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputUnt {:} - - "Units of the output" - typedef ^ ContinuousStateType R8Ki x {:} - - "Continuous States" - - -typedef ^ DiscreteStateType SiKi DummyDiscState - - - "" - +typedef ^ DiscreteStateType SiKi DummyDiscState - - - "" - # Define constraint states here: -typedef ^ ConstraintStateType SiKi DummyConstrState - - - "" - +typedef ^ ConstraintStateType SiKi DummyConstrState - - - "" - # Define any data that are other states, including integer or logical states here: -typedef ^ OtherStateType IntKi n - - - "Current Time step" - -typedef ^ ^ SS_Rad_ContinuousStateType xdot {4} - - "Old Values of dxdt to used by the solver (multistep method)" - +typedef ^ OtherStateType IntKi n - - - "Current Time step" - +typedef ^ ^ SS_Rad_ContinuousStateType xdot {4} - - "Old Values of dxdt to used by the solver (multistep method)" - # ..... Misc/Optimization variables................................................................................................. @@ -40,21 +41,22 @@ typedef ^ MiscVarType SiKi DummyMiscVar - - - "Rem # Define parameters here: # Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType DbKi DT - - - "Time step" seconds -typedef ^ ^ ReKi A {:}{:} - - "A matrix" - -typedef ^ ^ ReKi B {:}{:} - - "B matrix" - -typedef ^ ^ ReKi C {:}{:} - - "C matrix" - -typedef ^ ^ INTEGER N - - - "Number of states" - -typedef ^ ^ INTEGER spdof {6} - - "States per dof" - +typedef ^ ParameterType DbKi DT - - - "Time step" (s) +typedef ^ ^ ReKi A {:}{:} - - "A matrix" - +typedef ^ ^ ReKi B {:}{:} - - "B matrix" - +typedef ^ ^ ReKi C {:}{:} - - "C matrix" - +typedef ^ ^ INTEGER numStates - 0 - "Number of states" - +typedef ^ ^ INTEGER spdof {:} - - "States per dof" - +typedef ^ ^ IntKi NBody - - - "Number of WAMIT bodies for this State Space model" - # ..... Inputs ............................. # Define inputs that are contained on the mesh here: -typedef ^ InputType ReKi dq {6} - - "Body velocities" - +typedef ^ InputType ReKi dq {:} - - "Body velocities" - # ..... Outputs ............................ -typedef ^ OutputType ReKi y {6} - - "Force" - -typedef ^ ^ ReKi WriteOutput {7} - - "output Data" "kN" - +typedef ^ OutputType ReKi y {:} - - "Force" - +typedef ^ ^ ReKi WriteOutput {:} - - "output Data" (kN) diff --git a/modules/hydrodyn/src/SS_Radiation_Types.f90 b/modules/hydrodyn/src/SS_Radiation_Types.f90 index 39cd178705..9b26c59a72 100644 --- a/modules/hydrodyn/src/SS_Radiation_Types.f90 +++ b/modules/hydrodyn/src/SS_Radiation_Types.f90 @@ -36,13 +36,15 @@ MODULE SS_Radiation_Types ! ========= SS_Rad_InitInputType ======= TYPE, PUBLIC :: SS_Rad_InitInputType CHARACTER(1024) :: InputFile !< Name of the input file [-] - REAL(ReKi) , DIMENSION(1:1,1:6) :: DOFs !< Vector with enable platf. DOFs [m/s or rad/s] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: enabledDOFs !< Vector with enable platf. DOFs [(m/s] + INTEGER(IntKi) :: NBody !< Number of WAMIT bodies for this State Space model [-] + REAL(R8Ki) , DIMENSION(:), ALLOCATABLE :: PtfmRefztRot !< The rotation about zt of the body reference frame(s) from xt/yt [radians] END TYPE SS_Rad_InitInputType ! ======================= ! ========= SS_Rad_InitOutputType ======= TYPE, PUBLIC :: SS_Rad_InitOutputType - CHARACTER(ChanLen) , DIMENSION(1:7) :: WriteOutputHdr !< Header of the output [-] - CHARACTER(ChanLen) , DIMENSION(1:7) :: WriteOutputUnt !< Units of the output [-] + CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< Header of the output [-] + CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputUnt !< Units of the output [-] END TYPE SS_Rad_InitOutputType ! ======================= ! ========= SS_Rad_ContinuousStateType ======= @@ -73,23 +75,24 @@ MODULE SS_Radiation_Types ! ======================= ! ========= SS_Rad_ParameterType ======= TYPE, PUBLIC :: SS_Rad_ParameterType - REAL(DbKi) :: DT !< Time step [seconds] + REAL(DbKi) :: DT !< Time step [(s)] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: A !< A matrix [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: B !< B matrix [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: C !< C matrix [-] - INTEGER(IntKi) :: N !< Number of states [-] - INTEGER(IntKi) , DIMENSION(1:6) :: spdof !< States per dof [-] + INTEGER(IntKi) :: numStates = 0 !< Number of states [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: spdof !< States per dof [-] + INTEGER(IntKi) :: NBody !< Number of WAMIT bodies for this State Space model [-] END TYPE SS_Rad_ParameterType ! ======================= ! ========= SS_Rad_InputType ======= TYPE, PUBLIC :: SS_Rad_InputType - REAL(ReKi) , DIMENSION(1:6) :: dq !< Body velocities [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: dq !< Body velocities [-] END TYPE SS_Rad_InputType ! ======================= ! ========= SS_Rad_OutputType ======= TYPE, PUBLIC :: SS_Rad_OutputType - REAL(ReKi) , DIMENSION(1:6) :: y !< Force [-] - REAL(ReKi) , DIMENSION(1:7) :: WriteOutput !< output Data [kN] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: y !< Force [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WriteOutput !< output Data [(kN)] END TYPE SS_Rad_OutputType ! ======================= CONTAINS @@ -110,7 +113,31 @@ SUBROUTINE SS_Rad_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, E ErrStat = ErrID_None ErrMsg = "" DstInitInputData%InputFile = SrcInitInputData%InputFile - DstInitInputData%DOFs = SrcInitInputData%DOFs +IF (ALLOCATED(SrcInitInputData%enabledDOFs)) THEN + i1_l = LBOUND(SrcInitInputData%enabledDOFs,1) + i1_u = UBOUND(SrcInitInputData%enabledDOFs,1) + IF (.NOT. ALLOCATED(DstInitInputData%enabledDOFs)) THEN + ALLOCATE(DstInitInputData%enabledDOFs(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%enabledDOFs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%enabledDOFs = SrcInitInputData%enabledDOFs +ENDIF + DstInitInputData%NBody = SrcInitInputData%NBody +IF (ALLOCATED(SrcInitInputData%PtfmRefztRot)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmRefztRot,1) + i1_u = UBOUND(SrcInitInputData%PtfmRefztRot,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmRefztRot)) THEN + ALLOCATE(DstInitInputData%PtfmRefztRot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmRefztRot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmRefztRot = SrcInitInputData%PtfmRefztRot +ENDIF END SUBROUTINE SS_Rad_CopyInitInput SUBROUTINE SS_Rad_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) @@ -122,6 +149,12 @@ SUBROUTINE SS_Rad_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(InitInputData%enabledDOFs)) THEN + DEALLOCATE(InitInputData%enabledDOFs) +ENDIF +IF (ALLOCATED(InitInputData%PtfmRefztRot)) THEN + DEALLOCATE(InitInputData%PtfmRefztRot) +ENDIF END SUBROUTINE SS_Rad_DestroyInitInput SUBROUTINE SS_Rad_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -160,7 +193,17 @@ SUBROUTINE SS_Rad_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Db_BufSz = 0 Int_BufSz = 0 Int_BufSz = Int_BufSz + 1*LEN(InData%InputFile) ! InputFile - Re_BufSz = Re_BufSz + SIZE(InData%DOFs) ! DOFs + Int_BufSz = Int_BufSz + 1 ! enabledDOFs allocated yes/no + IF ( ALLOCATED(InData%enabledDOFs) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! enabledDOFs upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%enabledDOFs) ! enabledDOFs + END IF + Int_BufSz = Int_BufSz + 1 ! NBody + Int_BufSz = Int_BufSz + 1 ! PtfmRefztRot allocated yes/no + IF ( ALLOCATED(InData%PtfmRefztRot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmRefztRot upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%PtfmRefztRot) ! PtfmRefztRot + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -192,12 +235,38 @@ SUBROUTINE SS_Rad_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er IntKiBuf(Int_Xferred) = ICHAR(InData%InputFile(I:I), IntKi) Int_Xferred = Int_Xferred + 1 END DO ! I - DO i2 = LBOUND(InData%DOFs,2), UBOUND(InData%DOFs,2) - DO i1 = LBOUND(InData%DOFs,1), UBOUND(InData%DOFs,1) - ReKiBuf(Re_Xferred) = InData%DOFs(i1,i2) + IF ( .NOT. ALLOCATED(InData%enabledDOFs) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%enabledDOFs,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%enabledDOFs,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%enabledDOFs,1), UBOUND(InData%enabledDOFs,1) + ReKiBuf(Re_Xferred) = InData%enabledDOFs(i1) Re_Xferred = Re_Xferred + 1 END DO - END DO + END IF + IntKiBuf(Int_Xferred) = InData%NBody + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%PtfmRefztRot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmRefztRot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmRefztRot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmRefztRot,1), UBOUND(InData%PtfmRefztRot,1) + DbKiBuf(Db_Xferred) = InData%PtfmRefztRot(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE SS_Rad_PackInitInput SUBROUTINE SS_Rad_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -232,16 +301,44 @@ SUBROUTINE SS_Rad_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, OutData%InputFile(I:I) = CHAR(IntKiBuf(Int_Xferred)) Int_Xferred = Int_Xferred + 1 END DO ! I - i1_l = LBOUND(OutData%DOFs,1) - i1_u = UBOUND(OutData%DOFs,1) - i2_l = LBOUND(OutData%DOFs,2) - i2_u = UBOUND(OutData%DOFs,2) - DO i2 = LBOUND(OutData%DOFs,2), UBOUND(OutData%DOFs,2) - DO i1 = LBOUND(OutData%DOFs,1), UBOUND(OutData%DOFs,1) - OutData%DOFs(i1,i2) = ReKiBuf(Re_Xferred) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! enabledDOFs not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%enabledDOFs)) DEALLOCATE(OutData%enabledDOFs) + ALLOCATE(OutData%enabledDOFs(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%enabledDOFs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%enabledDOFs,1), UBOUND(OutData%enabledDOFs,1) + OutData%enabledDOFs(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO - END DO + END IF + OutData%NBody = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmRefztRot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmRefztRot)) DEALLOCATE(OutData%PtfmRefztRot) + ALLOCATE(OutData%PtfmRefztRot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmRefztRot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmRefztRot,1), UBOUND(OutData%PtfmRefztRot,1) + OutData%PtfmRefztRot(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END IF END SUBROUTINE SS_Rad_UnPackInitInput SUBROUTINE SS_Rad_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -259,8 +356,30 @@ SUBROUTINE SS_Rad_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(SrcInitOutputData%WriteOutputHdr)) THEN + i1_l = LBOUND(SrcInitOutputData%WriteOutputHdr,1) + i1_u = UBOUND(SrcInitOutputData%WriteOutputHdr,1) + IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputHdr)) THEN + ALLOCATE(DstInitOutputData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInitOutputData%WriteOutputHdr = SrcInitOutputData%WriteOutputHdr +ENDIF +IF (ALLOCATED(SrcInitOutputData%WriteOutputUnt)) THEN + i1_l = LBOUND(SrcInitOutputData%WriteOutputUnt,1) + i1_u = UBOUND(SrcInitOutputData%WriteOutputUnt,1) + IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputUnt)) THEN + ALLOCATE(DstInitOutputData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInitOutputData%WriteOutputUnt = SrcInitOutputData%WriteOutputUnt +ENDIF END SUBROUTINE SS_Rad_CopyInitOutput SUBROUTINE SS_Rad_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) @@ -272,6 +391,12 @@ SUBROUTINE SS_Rad_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN + DEALLOCATE(InitOutputData%WriteOutputHdr) +ENDIF +IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN + DEALLOCATE(InitOutputData%WriteOutputUnt) +ENDIF END SUBROUTINE SS_Rad_DestroyInitOutput SUBROUTINE SS_Rad_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -309,8 +434,16 @@ SUBROUTINE SS_Rad_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! WriteOutputHdr allocated yes/no + IF ( ALLOCATED(InData%WriteOutputHdr) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WriteOutputHdr upper/lower bounds for each dimension Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputHdr)*LEN(InData%WriteOutputHdr) ! WriteOutputHdr + END IF + Int_BufSz = Int_BufSz + 1 ! WriteOutputUnt allocated yes/no + IF ( ALLOCATED(InData%WriteOutputUnt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WriteOutputUnt upper/lower bounds for each dimension Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputUnt)*LEN(InData%WriteOutputUnt) ! WriteOutputUnt + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -338,18 +471,40 @@ SUBROUTINE SS_Rad_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Db_Xferred = 1 Int_Xferred = 1 - DO i1 = LBOUND(InData%WriteOutputHdr,1), UBOUND(InData%WriteOutputHdr,1) - DO I = 1, LEN(InData%WriteOutputHdr) - IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputHdr(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - DO i1 = LBOUND(InData%WriteOutputUnt,1), UBOUND(InData%WriteOutputUnt,1) - DO I = 1, LEN(InData%WriteOutputUnt) - IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputUnt(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO + IF ( .NOT. ALLOCATED(InData%WriteOutputHdr) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutputHdr,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputHdr,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WriteOutputHdr,1), UBOUND(InData%WriteOutputHdr,1) + DO I = 1, LEN(InData%WriteOutputHdr) + IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputHdr(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WriteOutputUnt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutputUnt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputUnt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WriteOutputUnt,1), UBOUND(InData%WriteOutputUnt,1) + DO I = 1, LEN(InData%WriteOutputUnt) + IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputUnt(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF END SUBROUTINE SS_Rad_PackInitOutput SUBROUTINE SS_Rad_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -379,22 +534,46 @@ SUBROUTINE SS_Rad_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - i1_l = LBOUND(OutData%WriteOutputHdr,1) - i1_u = UBOUND(OutData%WriteOutputHdr,1) - DO i1 = LBOUND(OutData%WriteOutputHdr,1), UBOUND(OutData%WriteOutputHdr,1) - DO I = 1, LEN(OutData%WriteOutputHdr) - OutData%WriteOutputHdr(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - i1_l = LBOUND(OutData%WriteOutputUnt,1) - i1_u = UBOUND(OutData%WriteOutputUnt,1) - DO i1 = LBOUND(OutData%WriteOutputUnt,1), UBOUND(OutData%WriteOutputUnt,1) - DO I = 1, LEN(OutData%WriteOutputUnt) - OutData%WriteOutputUnt(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputHdr not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WriteOutputHdr)) DEALLOCATE(OutData%WriteOutputHdr) + ALLOCATE(OutData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WriteOutputHdr,1), UBOUND(OutData%WriteOutputHdr,1) + DO I = 1, LEN(OutData%WriteOutputHdr) + OutData%WriteOutputHdr(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputUnt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WriteOutputUnt)) DEALLOCATE(OutData%WriteOutputUnt) + ALLOCATE(OutData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WriteOutputUnt,1), UBOUND(OutData%WriteOutputUnt,1) + DO I = 1, LEN(OutData%WriteOutputUnt) + OutData%WriteOutputUnt(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF END SUBROUTINE SS_Rad_UnPackInitOutput SUBROUTINE SS_Rad_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg ) @@ -1234,8 +1413,20 @@ SUBROUTINE SS_Rad_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrM END IF DstParamData%C = SrcParamData%C ENDIF - DstParamData%N = SrcParamData%N + DstParamData%numStates = SrcParamData%numStates +IF (ALLOCATED(SrcParamData%spdof)) THEN + i1_l = LBOUND(SrcParamData%spdof,1) + i1_u = UBOUND(SrcParamData%spdof,1) + IF (.NOT. ALLOCATED(DstParamData%spdof)) THEN + ALLOCATE(DstParamData%spdof(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%spdof.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstParamData%spdof = SrcParamData%spdof +ENDIF + DstParamData%NBody = SrcParamData%NBody END SUBROUTINE SS_Rad_CopyParam SUBROUTINE SS_Rad_DestroyParam( ParamData, ErrStat, ErrMsg ) @@ -1255,6 +1446,9 @@ SUBROUTINE SS_Rad_DestroyParam( ParamData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(ParamData%C)) THEN DEALLOCATE(ParamData%C) +ENDIF +IF (ALLOCATED(ParamData%spdof)) THEN + DEALLOCATE(ParamData%spdof) ENDIF END SUBROUTINE SS_Rad_DestroyParam @@ -1309,8 +1503,13 @@ SUBROUTINE SS_Rad_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 2*2 ! C upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%C) ! C END IF - Int_BufSz = Int_BufSz + 1 ! N + Int_BufSz = Int_BufSz + 1 ! numStates + Int_BufSz = Int_BufSz + 1 ! spdof allocated yes/no + IF ( ALLOCATED(InData%spdof) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! spdof upper/lower bounds for each dimension Int_BufSz = Int_BufSz + SIZE(InData%spdof) ! spdof + END IF + Int_BufSz = Int_BufSz + 1 ! NBody IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1400,12 +1599,25 @@ SUBROUTINE SS_Rad_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg END DO END DO END IF - IntKiBuf(Int_Xferred) = InData%N + IntKiBuf(Int_Xferred) = InData%numStates + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%spdof) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%spdof,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%spdof,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%spdof,1), UBOUND(InData%spdof,1) + IntKiBuf(Int_Xferred) = InData%spdof(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IntKiBuf(Int_Xferred) = InData%NBody Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%spdof,1), UBOUND(InData%spdof,1) - IntKiBuf(Int_Xferred) = InData%spdof(i1) - Int_Xferred = Int_Xferred + 1 - END DO END SUBROUTINE SS_Rad_PackParam SUBROUTINE SS_Rad_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1507,14 +1719,28 @@ SUBROUTINE SS_Rad_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err END DO END DO END IF - OutData%N = IntKiBuf(Int_Xferred) + OutData%numStates = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! spdof not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%spdof)) DEALLOCATE(OutData%spdof) + ALLOCATE(OutData%spdof(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%spdof.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%spdof,1), UBOUND(OutData%spdof,1) + OutData%spdof(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + OutData%NBody = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%spdof,1) - i1_u = UBOUND(OutData%spdof,1) - DO i1 = LBOUND(OutData%spdof,1), UBOUND(OutData%spdof,1) - OutData%spdof(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO END SUBROUTINE SS_Rad_UnPackParam SUBROUTINE SS_Rad_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) @@ -1532,7 +1758,18 @@ SUBROUTINE SS_Rad_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrM ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(SrcInputData%dq)) THEN + i1_l = LBOUND(SrcInputData%dq,1) + i1_u = UBOUND(SrcInputData%dq,1) + IF (.NOT. ALLOCATED(DstInputData%dq)) THEN + ALLOCATE(DstInputData%dq(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%dq.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInputData%dq = SrcInputData%dq +ENDIF END SUBROUTINE SS_Rad_CopyInput SUBROUTINE SS_Rad_DestroyInput( InputData, ErrStat, ErrMsg ) @@ -1544,6 +1781,9 @@ SUBROUTINE SS_Rad_DestroyInput( InputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(InputData%dq)) THEN + DEALLOCATE(InputData%dq) +ENDIF END SUBROUTINE SS_Rad_DestroyInput SUBROUTINE SS_Rad_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1581,7 +1821,11 @@ SUBROUTINE SS_Rad_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! dq allocated yes/no + IF ( ALLOCATED(InData%dq) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! dq upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%dq) ! dq + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1609,10 +1853,21 @@ SUBROUTINE SS_Rad_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Db_Xferred = 1 Int_Xferred = 1 - DO i1 = LBOUND(InData%dq,1), UBOUND(InData%dq,1) - ReKiBuf(Re_Xferred) = InData%dq(i1) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( .NOT. ALLOCATED(InData%dq) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dq,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dq,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%dq,1), UBOUND(InData%dq,1) + ReKiBuf(Re_Xferred) = InData%dq(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE SS_Rad_PackInput SUBROUTINE SS_Rad_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1642,12 +1897,24 @@ SUBROUTINE SS_Rad_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - i1_l = LBOUND(OutData%dq,1) - i1_u = UBOUND(OutData%dq,1) - DO i1 = LBOUND(OutData%dq,1), UBOUND(OutData%dq,1) - OutData%dq(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! dq not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%dq)) DEALLOCATE(OutData%dq) + ALLOCATE(OutData%dq(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%dq.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%dq,1), UBOUND(OutData%dq,1) + OutData%dq(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE SS_Rad_UnPackInput SUBROUTINE SS_Rad_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -1665,8 +1932,30 @@ SUBROUTINE SS_Rad_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, E ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(SrcOutputData%y)) THEN + i1_l = LBOUND(SrcOutputData%y,1) + i1_u = UBOUND(SrcOutputData%y,1) + IF (.NOT. ALLOCATED(DstOutputData%y)) THEN + ALLOCATE(DstOutputData%y(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%y.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstOutputData%y = SrcOutputData%y +ENDIF +IF (ALLOCATED(SrcOutputData%WriteOutput)) THEN + i1_l = LBOUND(SrcOutputData%WriteOutput,1) + i1_u = UBOUND(SrcOutputData%WriteOutput,1) + IF (.NOT. ALLOCATED(DstOutputData%WriteOutput)) THEN + ALLOCATE(DstOutputData%WriteOutput(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%WriteOutput.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstOutputData%WriteOutput = SrcOutputData%WriteOutput +ENDIF END SUBROUTINE SS_Rad_CopyOutput SUBROUTINE SS_Rad_DestroyOutput( OutputData, ErrStat, ErrMsg ) @@ -1678,6 +1967,12 @@ SUBROUTINE SS_Rad_DestroyOutput( OutputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(OutputData%y)) THEN + DEALLOCATE(OutputData%y) +ENDIF +IF (ALLOCATED(OutputData%WriteOutput)) THEN + DEALLOCATE(OutputData%WriteOutput) +ENDIF END SUBROUTINE SS_Rad_DestroyOutput SUBROUTINE SS_Rad_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1715,8 +2010,16 @@ SUBROUTINE SS_Rad_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! y allocated yes/no + IF ( ALLOCATED(InData%y) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! y upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%y) ! y + END IF + Int_BufSz = Int_BufSz + 1 ! WriteOutput allocated yes/no + IF ( ALLOCATED(InData%WriteOutput) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WriteOutput upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WriteOutput) ! WriteOutput + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1744,14 +2047,36 @@ SUBROUTINE SS_Rad_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_Xferred = 1 Int_Xferred = 1 - DO i1 = LBOUND(InData%y,1), UBOUND(InData%y,1) - ReKiBuf(Re_Xferred) = InData%y(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%WriteOutput,1), UBOUND(InData%WriteOutput,1) - ReKiBuf(Re_Xferred) = InData%WriteOutput(i1) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( .NOT. ALLOCATED(InData%y) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%y,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%y,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%y,1), UBOUND(InData%y,1) + ReKiBuf(Re_Xferred) = InData%y(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WriteOutput) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutput,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutput,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WriteOutput,1), UBOUND(InData%WriteOutput,1) + ReKiBuf(Re_Xferred) = InData%WriteOutput(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE SS_Rad_PackOutput SUBROUTINE SS_Rad_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1781,18 +2106,42 @@ SUBROUTINE SS_Rad_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - i1_l = LBOUND(OutData%y,1) - i1_u = UBOUND(OutData%y,1) - DO i1 = LBOUND(OutData%y,1), UBOUND(OutData%y,1) - OutData%y(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%WriteOutput,1) - i1_u = UBOUND(OutData%WriteOutput,1) - DO i1 = LBOUND(OutData%WriteOutput,1), UBOUND(OutData%WriteOutput,1) - OutData%WriteOutput(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! y not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%y)) DEALLOCATE(OutData%y) + ALLOCATE(OutData%y(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%y.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%y,1), UBOUND(OutData%y,1) + OutData%y(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutput not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WriteOutput)) DEALLOCATE(OutData%WriteOutput) + ALLOCATE(OutData%WriteOutput(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutput.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WriteOutput,1), UBOUND(OutData%WriteOutput,1) + OutData%WriteOutput(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE SS_Rad_UnPackOutput @@ -1890,10 +2239,12 @@ SUBROUTINE SS_Rad_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrM END IF ScaleFactor = t_out / t(2) +IF (ALLOCATED(u_out%dq) .AND. ALLOCATED(u1%dq)) THEN DO i1 = LBOUND(u_out%dq,1),UBOUND(u_out%dq,1) b = -(u1%dq(i1) - u2%dq(i1)) u_out%dq(i1) = u1%dq(i1) + b * ScaleFactor END DO +END IF ! check if allocated END SUBROUTINE SS_Rad_Input_ExtrapInterp1 @@ -1951,11 +2302,13 @@ SUBROUTINE SS_Rad_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, END IF ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) +IF (ALLOCATED(u_out%dq) .AND. ALLOCATED(u1%dq)) THEN DO i1 = LBOUND(u_out%dq,1),UBOUND(u_out%dq,1) b = (t(3)**2*(u1%dq(i1) - u2%dq(i1)) + t(2)**2*(-u1%dq(i1) + u3%dq(i1)))* scaleFactor c = ( (t(2)-t(3))*u1%dq(i1) + t(3)*u2%dq(i1) - t(2)*u3%dq(i1) ) * scaleFactor u_out%dq(i1) = u1%dq(i1) + b + c * t_out END DO +END IF ! check if allocated END SUBROUTINE SS_Rad_Input_ExtrapInterp2 @@ -2053,14 +2406,18 @@ SUBROUTINE SS_Rad_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, Err END IF ScaleFactor = t_out / t(2) +IF (ALLOCATED(y_out%y) .AND. ALLOCATED(y1%y)) THEN DO i1 = LBOUND(y_out%y,1),UBOUND(y_out%y,1) b = -(y1%y(i1) - y2%y(i1)) y_out%y(i1) = y1%y(i1) + b * ScaleFactor END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) b = -(y1%WriteOutput(i1) - y2%WriteOutput(i1)) y_out%WriteOutput(i1) = y1%WriteOutput(i1) + b * ScaleFactor END DO +END IF ! check if allocated END SUBROUTINE SS_Rad_Output_ExtrapInterp1 @@ -2118,16 +2475,20 @@ SUBROUTINE SS_Rad_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, END IF ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) +IF (ALLOCATED(y_out%y) .AND. ALLOCATED(y1%y)) THEN DO i1 = LBOUND(y_out%y,1),UBOUND(y_out%y,1) b = (t(3)**2*(y1%y(i1) - y2%y(i1)) + t(2)**2*(-y1%y(i1) + y3%y(i1)))* scaleFactor c = ( (t(2)-t(3))*y1%y(i1) + t(3)*y2%y(i1) - t(2)*y3%y(i1) ) * scaleFactor y_out%y(i1) = y1%y(i1) + b + c * t_out END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) b = (t(3)**2*(y1%WriteOutput(i1) - y2%WriteOutput(i1)) + t(2)**2*(-y1%WriteOutput(i1) + y3%WriteOutput(i1)))* scaleFactor c = ( (t(2)-t(3))*y1%WriteOutput(i1) + t(3)*y2%WriteOutput(i1) - t(2)*y3%WriteOutput(i1) ) * scaleFactor y_out%WriteOutput(i1) = y1%WriteOutput(i1) + b + c * t_out END DO +END IF ! check if allocated END SUBROUTINE SS_Rad_Output_ExtrapInterp2 END MODULE SS_Radiation_Types diff --git a/modules/hydrodyn/src/WAMIT.f90 b/modules/hydrodyn/src/WAMIT.f90 index d807b4a84e..ef7e9c4f7b 100644 --- a/modules/hydrodyn/src/WAMIT.f90 +++ b/modules/hydrodyn/src/WAMIT.f90 @@ -23,7 +23,6 @@ MODULE WAMIT USE Waves USE WAMIT_Types - USE WAMIT_Output USE WAMIT_Interp USE NWTC_Library ! USE Waves_Types @@ -56,6 +55,42 @@ MODULE WAMIT CONTAINS + +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine transforms WAMIT input file data from a local (heading-angle, based) coordinate system to the global system. + subroutine TransformWAMITMatrices( NBody, RotZ, M ) +!.................................................................................................................................. + integer(IntKi), intent( in ) :: NBody ! Number of WAMIT bodies in this WAMIT object ( = 1 if NBodyMod > 1) + real(R8Ki), intent( in ) :: RotZ(:) ! NBody heading angles (radians) + real(SiKi), intent( inout ) :: M(:,:) ! Matrix data to be transformed, if NBodyMOD = 1 and NBody > 1 then we will be transforming the individual sub 6x6 matrices + + integer(IntKi) :: i,j,ii,jj,iSub,jSub + real(R8Ki) :: Rj(3,3) + real(R8Ki) :: Ri(3,3) + + do j = 1, NBody + Rj(1,:) = (/ cos(RotZ(j)), sin(RotZ(j)), 0.0_R8Ki/) + Rj(2,:) = (/-sin(RotZ(j)), cos(RotZ(j)), 0.0_R8Ki/) + Rj(3,:) = (/ 0.0_R8Ki , 0.0_R8Ki , 1.0_R8Ki/) + do i = 1, NBody + if ( (.not. EqualRealNos(RotZ(i), 0.0_R8Ki)) .or. (.not. EqualRealNos(RotZ(j), 0.0_R8Ki)) ) then + Ri(1,:) = (/ cos(RotZ(i)), sin(RotZ(i)), 0.0_R8Ki/) + Ri(2,:) = (/-sin(RotZ(i)), cos(RotZ(i)), 0.0_R8Ki/) + Ri(3,:) = (/ 0.0_R8Ki , 0.0_R8Ki , 1.0_R8Ki/) + do jj = 1,2 + jSub = (j-1)*6 + (jj-1)*3 + 1 + do ii = 1,2 + iSub = (i-1)*6 + (ii-1)*3 + 1 + M(iSub:iSub+2,jSub:jSub+2) = matmul( transpose(Ri), matmul( M(iSub:iSub+2,jSub:jSub+2), Rj ) ) + end do + end do + end if + end do + + end do + end subroutine TransformWAMITMatrices + + !---------------------------------------------------------------------------------------------------------------------------------- !> This routine is called at the start of the simulation to perform initialization steps. !! The parameters are set here and not changed during the simulation. @@ -102,12 +137,12 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init COMPLEX(SiKi), ALLOCATABLE :: HdroExctn (:,:,:) ! Frequency- and direction-dependent complex hydrodynamic wave excitation force per unit wave amplitude vector (kg/s^2, kg-m/s^2) COMPLEX(SiKi), ALLOCATABLE :: WaveExctnC(:,:) ! Discrete Fourier transform of the instantaneous value of the total excitation force on the support platfrom from incident waves (N, N-m) REAL(ReKi) :: DffrctDim (6) ! Matrix used to redimensionalize WAMIT hydrodynamic wave excitation force output (kg/s^2, kg-m/s^2 ) - REAL(SiKi), ALLOCATABLE :: HdroAddMs (:,:) ! The upper-triangular portion (diagonal and above) of the frequency-dependent hydrodynamic added mass matrix from the radiation problem (kg , kg-m , kg-m^2 ) - REAL(SiKi), ALLOCATABLE :: HdroDmpng (:,:) ! The upper-triangular portion (diagonal and above) of the frequency-dependent hydrodynamic damping matrix from the radiation problem (kg/s, kg-m/s, kg-m^2/s) + REAL(SiKi), ALLOCATABLE :: HdroAddMs (:,:,:) ! The frequency-dependent hydrodynamic added mass matrix from the radiation problem (kg , kg-m , kg-m^2 ) + REAL(SiKi), ALLOCATABLE :: HdroDmpng (:,:,:) ! The frequency-dependent hydrodynamic damping matrix from the radiation problem (kg/s, kg-m/s, kg-m^2/s) REAL(SiKi), ALLOCATABLE :: HdroFreq (:) ! Frequency components inherent in the hydrodynamic added mass matrix, hydrodynamic daming matrix, and complex wave excitation force per unit wave amplitude vector (rad/s) REAL(SiKi), ALLOCATABLE :: HdroWvDir (:) ! Incident wave propagation heading direction components inherent in the complex wave excitation force per unit wave amplitude vector (degrees) REAL(ReKi) :: HighFreq ! The highest frequency component in the WAMIT file, not counting infinity. - REAL(ReKi) :: Omega ! Wave frequency (rad/s) + REAL(SiKi) :: Omega ! Wave frequency (rad/s) REAL(ReKi) :: PrvDir ! The value of TmpDir from the previous line (degrees) REAL(ReKi) :: PrvPer ! The value of TmpPer from the previous line (sec ) REAL(ReKi) :: SttcDim (6,6) ! Matrix used to redimensionalize WAMIT hydrostatic restoring output (kg/s^2, kg-m/s^2, kg-m^2/s^2) @@ -119,6 +154,7 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init REAL(ReKi) :: TmpPer ! A temporary period read in from a WAMIT file (sec ) REAL(ReKi) :: TmpRe ! A temporary real value read in from a WAMIT file (- ) REAL(SiKi) :: TmpCoord(2) ! A temporary real array to hold the (Omega,WaveDir) pair for interpolation + COMPLEX(SiKi),ALLOCATABLE :: tmpComplexArr(:) ! A temporary array (0:NStepWave2-1) for FFT use. REAL(ReKi), ALLOCATABLE :: WAMITFreq (:) ! Frequency components as ordered in the WAMIT output files (rad/s ) REAL(ReKi), ALLOCATABLE :: WAMITPer (:) ! Period components as ordered in the WAMIT output files (sec ) REAL(ReKi), ALLOCATABLE :: WAMITWvDir(:) ! Wave direction components as ordered in the WAMIT output files (degrees) @@ -148,11 +184,18 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init CHARACTER(1024) :: Line ! String to temporarily hold the value of a line within a WAMIT output file. TYPE(FFT_DataType) :: FFT_Data ! the instance of the FFT module we're using - + integer(IntKi) :: iSub, jSub ! indices into the 6x6 sub-matrices used to redimensionalize the WAMIT data (Needed because NBodyMod=1 could have WAMIT matrices which are 6N x 6N) + integer(IntKi) :: iBody ! WAMIT body index + real(R8Ki) :: orientation(3,3) ! Initial orientation of the WAMIT body + real(R8Ki) :: theta(3) ! Euler angle rotations of the WAMIT body + real(ReKi) :: WaveNmbr ! Frequency-dependent wave number + COMPLEX(SiKi) :: Fxy ! Phase correction term for Wave excitation forces + real(ReKi) :: tmpAngle ! Frequency and heading and platform offset dependent phase shift angle for Euler's Equation e^(-j*tmpAngle) + COMPLEX(SiKi), ALLOCATABLE :: HdroExctn_Local (:,:,:) ! Temporary Frequency- and direction-dependent complex hydrodynamic wave excitation force per unit wave amplitude vector (kg/s^2, kg-m/s^2) ! Error handling CHARACTER(ErrMsgLen) :: ErrMsg2 ! Temporary error message for calls INTEGER(IntKi) :: ErrStat2 ! Temporary error status for calls - + COMPLEX(SiKi) :: Ctmp1, Ctmp2, Ctmp4, Ctmp5 ! Temporary COMPLEX transformation terms ! Initialize data @@ -179,77 +222,57 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init ! Copy Output Init data from Waves Module Init call - p%RhoXg = InitInp%RhoXg p%NStepWave = InitInp%NStepWave p%NumOuts = InitInp%NumOuts p%ExctnMod = InitInp%ExctnMod - - ! For now, we are forcing WAMIT to use the glue-code time-step. If the Convolution-based radiation module was requesting a different timestep (RdtnDT) - ! Then HydroDyn will have already thrown an error. - - p%DT = Interval - - !IF ( InitInp%HasWAMIT ) THEN - ! p%NumOuts = InitInp%NumOuts - !ELSE - ! p%NumOuts = 0 ! Need to set this so the when a call uses generic output writing code, there will be no WAMIT outputs - ! - ! RETURN ! We don't need to do any further initialization work because we are not using WAMIT - - ! Need to allocate and copy data and then destroy the original ??? - ALLOCATE ( p%WaveTime (0:p%NStepWave ) , STAT=ErrStat2 ) - IF ( ErrStat2 /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, 'Error allocating memory for the WaveTime array.', ErrStat, ErrMsg, 'WAMIT_Init') - CALL Cleanup() - RETURN - END IF - p%WaveTime = InitInp%WaveTime - - ! Copy Input Init data into parameters - - p%PtfmVol0 = InitInp%PtfmVol0 - p%PtfmCOBxt = InitInp%PtfmCOBxt - p%PtfmCOByt = InitInp%PtfmCOByt - - - - - - - - - - - - - - - - - + p%NBodyMod = InitInp%NBodyMod + p%NBody = InitInp%NBody ! In the context of this WAMIT object NBody is 1 if NBodyMod > 1 [there are NBody different WAMIT objects in this case] + + ! This module's implementation requires that if NBodyMod = 2 or 3, then there is one instance of a WAMIT module for each body, therefore, HydroDyn may have NBody > 1, but this WAMIT module will have NBody = 1 + if ( (p%NBodyMod > 1) .and. (p%NBody > 1) ) then + CALL SetErrStat( ErrID_Fatal, "DEVELOPER ERROR: If NBodyMod = 2 or 3, then NBody for the a WAMIT object must be equal to 1", ErrStat, ErrMsg, 'WAMIT_Init') + return + end if + + ! Allocate misc var and parameter vectors/matrices + call AllocAry( p%F_HS_Moment_Offset, 6, p%NBody, 'p%F_HS_Moment_Offset', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') + call AllocAry( m%F_HS , 6*p%NBody, 'm%F_HS' , ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') + call AllocAry( m%F_Waves1 , 6*p%NBody, 'm%F_Waves1' , ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') + call AllocAry( m%F_Rdtn , 6*p%NBody, 'm%F_Rdtn' , ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') + call AllocAry( m%F_PtfmAM , 6*p%NBody, 'm%F_PtfmAM' , ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') + call AllocAry( p%HdroAdMsI, 6*p%NBody,6*p%NBody, 'p%HdroAdMsI' , ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') + call AllocAry( p%HdroSttc , 6*p%NBody,6*p%NBody, 'p%HdroSttc' , ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') + + + do iBody = 1, p%NBody + p%F_HS_Moment_Offset(1,iBody) = 0.0_ReKi + p%F_HS_Moment_Offset(2,iBody) = 0.0_ReKi + p%F_HS_Moment_Offset(3,iBody) = InitInp%RhoXg*InitInp%PtfmVol0(iBody) ! except for the hydrostatic buoyancy force from Archimede's Principle when the support platform is in its undisplaced position + p%F_HS_Moment_Offset(4,iBody) = InitInp%RhoXg*InitInp%PtfmVol0(iBody)*( InitInp%PtfmCOByt(iBody) - InitInp%PtfmRefyt(iBody) ) ! and the moment about X due to the COB being offset from the local WAMIT reference point + p%F_HS_Moment_Offset(5,iBody) = -InitInp%RhoXg*InitInp%PtfmVol0(iBody)*( InitInp%PtfmCOBxt(iBody) - InitInp%PtfmRefxt(iBody) ) ! and the moment about Y due to the COB being offset from the localWAMIT reference point + p%F_HS_Moment_Offset(6,iBody) = 0.0_ReKi + end do ! Tell our nice users what is about to happen that may take a while: CALL WrScr ( ' Reading in WAMIT output with root name "'//TRIM(InitInp%WAMITFile)//'".' ) - - ! Let's set up the matrices used to redimensionalize the hydrodynamic data ! from WAMIT; all these matrices are symmetric and need to be used with ! element-by-element multiplication, instead of matrix-by-matrix ! multiplication: - SttcDim(1,1) = p%RhoXg *InitInp%WAMITULEN**2 ! Force-translation - SttcDim(1,4) = p%RhoXg *InitInp%WAMITULEN**3 ! Force-rotation/Moment-translation - Hydrostatic restoring - SttcDim(4,4) = p%RhoXg *InitInp%WAMITULEN**4 ! Moment-rotation + SttcDim(1,1) = InitInp%RhoXg *InitInp%WAMITULEN**2 ! Force-translation + SttcDim(1,4) = InitInp%RhoXg *InitInp%WAMITULEN**3 ! Force-rotation/Moment-translation - Hydrostatic restoring + SttcDim(4,4) = InitInp%RhoXg *InitInp%WAMITULEN**4 ! Moment-rotation RdtnDim(1,1) = InitInp%WtrDens*InitInp%WAMITULEN**3 ! Force-translation RdtnDim(1,4) = InitInp%WtrDens*InitInp%WAMITULEN**4 ! Force-rotation/Moment-translation - Hydrodynamic added mass and damping RdtnDim(4,4) = InitInp%WtrDens*InitInp%WAMITULEN**5 ! Moment-rotation - DffrctDim(1) = p%RhoXg *InitInp%WAMITULEN**2 ! Force-translation - Hydrodynamic wave excitation force - DffrctDim(4) = p%RhoXg *InitInp%WAMITULEN**3 ! Moment-rotation + DffrctDim(1) = InitInp%RhoXg *InitInp%WAMITULEN**2 ! Force-translation - Hydrodynamic wave excitation force + DffrctDim(4) = InitInp%RhoXg *InitInp%WAMITULEN**3 ! Moment-rotation DO I = 1,3 ! Loop through all force-translation elements (rows) @@ -317,10 +340,16 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init READ (UnWh,*,IOSTAT=Sttus) I, J, TmpData1 ! Read in the row index, column index, and nondimensional data from the WAMIT file IF ( Sttus == 0 ) THEN ! .TRUE. when data is read in successfully -!bjj: TODO verify that I and J are valid values - p%HdroSttc (I,J) = TmpData1*SttcDim(I,J) ! Redimensionalize the data and place it at the appropriate location within the array - ELSE ! We must have reached the end of the file, so stop reading in data + ! In case NBodyMod = 1, we now have WAMIT matrices which are potentially larger than 6x6, so we need to determine how the SttcDim multiplier matrix (a 6x6) + ! should be applied to the larger WAMIT matrix. + + iSub = mod(I-1,6)+1 ! Finds the 6x6 sub-matrix indexing for the SttcDim multiplier matrix + jSub = mod(J-1,6)+1 + + p%HdroSttc (I,J) = TmpData1*SttcDim(iSub,jSub) ! Redimensionalize the data and place it at the appropriate location within the array + + ELSE ! We must have reached the end of the file, so stop reading in data EXIT @@ -331,7 +360,8 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init CLOSE ( UnWh ) ! Close file. - + ! need to transform p%HdroSttc when PtfmRefztRot is nonzero per plan + call TransformWAMITMatrices( p%NBody, InitInp%PtfmRefztRot, p%HdroSttc ) ! Linear, frequency-dependent hydrodynamic added mass and damping from the ! radiation problem: @@ -386,8 +416,8 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init CALL AllocAry( WAMITPer, NInpFreq, 'WAMITPer', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') CALL AllocAry( SortFreqInd, NInpFreq, 'SortFreqInd', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') CALL AllocAry( HdroFreq, NInpFreq, 'HdroFreq', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') - CALL AllocAry( HdroAddMs, NInpFreq, 21,'HdroAddMs', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') - CALL AllocAry( HdroDmpng, NInpFreq, 21,'HdroDmpng', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') + CALL AllocAry( HdroAddMs, NInpFreq, 6*p%NBody, 6*p%NBody, 'HdroAddMs', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') + CALL AllocAry( HdroDmpng, NInpFreq, 6*p%NBody, 6*p%NBody, 'HdroDmpng', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -463,8 +493,8 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init PrvPer = 0.0 ! Initialize to a don't care FirstPass = .TRUE. ! Initialize to .TRUE. for the first pass - HdroAddMs(:,:) = 0.0 ! Initialize to zero - HdroDmpng(:,:) = 0.0 ! Initialize to zero + HdroAddMs = 0.0 ! Initialize to zero + HdroDmpng = 0.0 ! Initialize to zero DO ! Loop through all rows in the file @@ -506,28 +536,31 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init !bjj: verify that I and J are valid indices for RdtnDim - IF ( J >= I ) THEN ! .TRUE. if we are on or above the diagonal - Indx = 6*( I - 1 ) + J - ( I*( I - 1 ) )/2 ! Convert from row/column indices to an index in the format used to save only the upper-triangular portion of the matrix. NOTE: ( I*( I - 1 ) )/2 = SUM(I,START=1,END=I-1). + ! IF ( J >= I ) THEN ! .TRUE. if we are on or above the diagonal + ! Indx = 6*( I - 1 ) + J - ( I*( I - 1 ) )/2 ! Convert from row/column indices to an index in the format used to save only the upper-triangular portion of the matrix. NOTE: ( I*( I - 1 ) )/2 = SUM(I,START=1,END=I-1). + iSub = mod(I-1,6)+1 ! Finds the 6x6 sub-matrix indexing for the SttcDim multiplier matrix + jSub = mod(J-1,6)+1 - HdroAddMs(SortFreqInd(K),Indx) = TmpData1*RdtnDim(I,J) ! Redimensionalize the data and place it at the appropriate location within the array - END IF + HdroAddMs(SortFreqInd(K),I,J) = TmpData1*RdtnDim(iSub,jSub) ! Redimensionalize the data and place it at the appropriate location within the array + ! END IF ELSE ! We must have a positive, non-infinite frequency. - READ (Line,*,IOSTAT=Sttus) TmpPer, I, J, TmpData1, TmpData2 ! Read in the period, row index, column index, and nondimensional data from the WAMIT file + READ (Line,*,IOSTAT=Sttus) TmpPer, I, J, TmpData1, TmpData2 ! Read in the period, row index, column index, and nondimensional data from the WAMIT file IF ( Sttus /= 0 ) THEN CALL SetErrStat( ErrID_Fatal, "Error reading line from WAMIT file", ErrStat, ErrMsg, 'WAMIT_Init') CALL Cleanup() RETURN END IF -!bjj: verify that I and J are valid indices for RdtnDim - - IF ( J >= I ) THEN ! .TRUE. if we are on or above the diagonal - Indx = 6*( I - 1 ) + J - ( I*( I - 1 ) )/2 ! Convert from row/column indices to an index in the format used to save only the upper-triangular portion of the matrix. NOTE: ( I*( I - 1 ) )/2 = SUM(I,START=1,END=I-1). + - HdroAddMs(SortFreqInd(K),Indx) = TmpData1*RdtnDim(I,J) ! Redimensionalize the data and place it at the appropriate location within the array - HdroDmpng(SortFreqInd(K),Indx) = TmpData2*RdtnDim(I,J)*HdroFreq(SortFreqInd(K)) ! Redimensionalize the data and place it at the appropriate location within the array - END IF + !IF ( J >= I ) THEN ! .TRUE. if we are on or above the diagonal + ! Indx = 6*( I - 1 ) + J - ( I*( I - 1 ) )/2 ! Convert from row/column indices to an index in the format used to save only the upper-triangular portion of the matrix. NOTE: ( I*( I - 1 ) )/2 = SUM(I,START=1,END=I-1). + iSub = mod(I-1,6)+1 ! Finds the 6x6 sub-matrix indexing for the SttcDim multiplier matrix + jSub = mod(J-1,6)+1 + HdroAddMs(SortFreqInd(K),I,J) = TmpData1*RdtnDim(iSub,jSub) ! Redimensionalize the data and place it at the appropriate location within the array + HdroDmpng(SortFreqInd(K),I,J) = TmpData2*RdtnDim(iSub,jSub)*HdroFreq(SortFreqInd(K)) ! Redimensionalize the data and place it at the appropriate location within the array + ! END IF END IF @@ -546,8 +579,13 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init CLOSE ( UnW1 ) ! Close file. - - + ! need to transform HdroAddMs and HdroDmpng when PtfmRefztRot is nonzero per plan + do I = 1, NInpFreq + call TransformWAMITMatrices( p%NBody, InitInp%PtfmRefztRot, HdroAddMs(I,:,:) ) + call TransformWAMITMatrices( p%NBody, InitInp%PtfmRefztRot, HdroDmpng(I,:,:) ) + end do + + ! Linear, frequency- and direction-dependent complex hydrodynamic wave ! excitation force per unit wave amplitude vector from the diffraction ! problem: @@ -623,7 +661,7 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init RETURN END IF - ALLOCATE ( HdroExctn (NInpFreq,NInpWvDir,6) , STAT=ErrStat2 ) ! complex so we don't have a reoutine + ALLOCATE ( HdroExctn (NInpFreq,NInpWvDir,6*p%NBody) , STAT=ErrStat2 ) ! complex so we don't have a built in subroutine IF ( ErrStat2 /= 0 ) THEN CALL SetErrStat( ErrID_Fatal, 'Error allocating space for HdroExctn array', ErrStat, ErrMsg, 'WAMIT_Init') CALL Cleanup() @@ -783,8 +821,8 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init END IF - - HdroExctn(SortFreqInd(K),SortWvDirInd(J),I) = CMPLX( TmpRe, TmpIm )*DffrctDim(I) ! Redimensionalize the data and place it at the appropriate location within the array + iSub = mod(I-1,6)+1 ! Finds the 6x6 sub-matrix indexing for the SttcDim multiplier matrix + HdroExctn(SortFreqInd(K),SortWvDirInd(J),I) = CMPLX( TmpRe, TmpIm )*DffrctDim(iSub) ! Redimensionalize the data and place it at the appropriate location within the array ELSE ! We must have reached the end of the file, so stop reading in data @@ -850,16 +888,16 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init ! Set the infinite-frequency limit of the frequency-dependent hydrodynamic ! added mass matrix, HdroAdMsI, based on the highest frequency available: - - Indx = 0 - DO J = 1,6 ! Loop through all rows of HdroAdMsI - DO K = J,6 ! Loop through all columns of HdroAdMsI above and including the diagonal - Indx = Indx + 1 - p%HdroAdMsI(J,K) = HdroAddMs(NInpFreq,Indx) +!TODO: Is this index order correct for computational speed? GJH 9/5/19 + !Indx = 0 + DO J = 1,6*p%NBody ! Loop through all rows of HdroAdMsI + DO K = 1,6*p%NBody ! Loop through all columns of HdroAdMsI above and including the diagonal + ! Indx = Indx + 1 + p%HdroAdMsI(J,K) = HdroAddMs(NInpFreq,J,K) END DO ! K - All columns of HdroAdMsI above and including the diagonal - DO K = J+1,6 ! Loop through all rows of HdroAdMsI below the diagonal - p%HdroAdMsI(K,J) = p%HdroAdMsI(J,K) - END DO ! K - All rows of HdroAdMsI below the diagonal + ! DO K = J+1,6 ! Loop through all rows of HdroAdMsI below the diagonal + ! p%HdroAdMsI(K,J) = p%HdroAdMsI(J,K) + ! END DO ! K - All rows of HdroAdMsI below the diagonal END DO ! J - All rows of HdroAdMsI @@ -871,11 +909,12 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init ! Initialize the variables associated with the incident wave: SELECT CASE ( InitInp%WaveMod ) ! Which incident wave kinematics model are we using? - CASE ( 0 ) + CASE ( 0 ) ! No waves if ( p%ExctnMod == 1 ) then - ! Initialize everything to zero: - ALLOCATE ( p%WaveExctn (0:InitInp%NStepWave,6) , STAT=ErrStat2 ) + ! Initialize everything to zero: + + ALLOCATE ( p%WaveExctn (0:InitInp%NStepWave,6*p%NBody) , STAT=ErrStat2 ) IF ( ErrStat2 /= 0 ) THEN CALL SetErrStat( ErrID_Fatal, 'Error allocating memory for the WaveExctn array.', ErrStat, ErrMsg, 'WAMIT_Init') CALL Cleanup() @@ -889,10 +928,15 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init SS_Exctn_InitInp%InputFile = InitInp%WAMITFile SS_Exctn_InitInp%WaveDir = InitInp%WaveDir SS_Exctn_InitInp%NStepWave = p%NStepWave + SS_Exctn_InitInp%NBody = InitInp%NBody + SS_Exctn_InitInp%PtfmRefztRot = InitInp%PtfmRefztRot + ! No other modules need this WaveElev0 array so we will simply move the allocation over to the SS_Exctn module IF (ALLOCATED(InitInp%WaveElev0)) CALL MOVE_ALLOC(InitInp%WaveElev0, SS_Exctn_InitInp%WaveElev0) +!TODO: Verify what happens within SS_Exctn when we have no waves. + ! We need the WaveTime array to stay intact for use in other modules, so we will make a copy instead of moving the allocation ALLOCATE ( SS_Exctn_InitInp%WaveTime (0:InitInp%NStepWave) , STAT=ErrStat2 ) IF ( ErrStat2 /= 0 ) THEN @@ -935,22 +979,87 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init ! ALLOCATE the arrays: - ALLOCATE ( WaveExctnC(0:InitInp%NStepWave2 ,6) , STAT=ErrStat2 ) + ALLOCATE ( WaveExctnC(0:InitInp%NStepWave2 ,6*p%NBody) , STAT=ErrStat2 ) IF ( ErrStat2 /= 0 ) THEN CALL SetErrStat( ErrID_Fatal, 'Error allocating memory for the WaveExctnC array.', ErrStat, ErrMsg, 'WAMIT_Init') CALL Cleanup() RETURN END IF - ALLOCATE ( p%WaveExctn (0:InitInp%NStepWave,6) , STAT=ErrStat2 ) + ALLOCATE ( p%WaveExctn (0:InitInp%NStepWave,6*p%NBody) , STAT=ErrStat2 ) IF ( ErrStat2 /= 0 ) THEN CALL SetErrStat( ErrID_Fatal, 'Error allocating memory for the WaveExctn array.', ErrStat, ErrMsg, 'WAMIT_Init') CALL Cleanup() RETURN END IF + !==================================== + ! Transform the wave excitation coefs + !==================================== + + if ( p%NBodyMod == 2 ) then + + ! Since NBodyMod = 2, then NBody = 1 for this WAMIT object (this requirement is encoded at the HydroDyn module level) + + allocate ( HdroExctn_Local(NInpFreq, NInpWvDir, 6), STAT=ErrStat2 ) + IF ( ErrStat2 /= 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Error allocating memory for the HdroExctn_Local array.', ErrStat, ErrMsg, 'WAMIT_Init') + CALL Cleanup() + RETURN + END IF - + do K = 1,6 ! Loop through all wave excitation forces and moments + do J = 1, NInpWvDir + TmpCoord(2) = HdroWvDir(J) - InitInp%PtfmRefztRot(1)*R2D ! apply locale Z rotation to heading angle (degrees) + do I = 1, NInpFreq + TmpCoord(1) = HdroFreq(I) + ! Iterpolate to find new coef + call WAMIT_Interp2D_Cplx( TmpCoord, HdroExctn(:,:,K), HdroFreq, HdroWvDir, LastInd2, HdroExctn_Local(I,J,K), ErrStat2, ErrMsg2 ) + end do + end do + end do + + ! Now apply rotation and phase shift + + do J = 1, NInpWvDir + do I = 1, NInpFreq + ! Fxy = exp(-j * k(w) * ( X*cos(Beta(w)) + Y*sin(Beta(w)) ) + WaveNmbr = WaveNumber ( HdroFreq(I), InitInp%Gravity, InitInp%WtrDpth ) + tmpAngle = WaveNmbr * ( InitInp%PtfmRefxt(1)*cos(HdroWvDir(J)*D2R) + InitInp%PtfmRefyt(1)*sin(HdroWvDir(J)*D2R) ) + TmpRe = cos(tmpAngle) + TmpIm = -sin(tmpAngle) + Fxy = CMPLX( TmpRe, TmpIm ) + + HdroExctn(I,J,1) = Fxy*( HdroExctn_Local(I,J,1)*cos(InitInp%PtfmRefztRot(1)) - HdroExctn_Local(I,J,2)*sin(InitInp%PtfmRefztRot(1)) ) + HdroExctn(I,J,2) = Fxy*( HdroExctn_Local(I,J,1)*sin(InitInp%PtfmRefztRot(1)) + HdroExctn_Local(I,J,2)*cos(InitInp%PtfmRefztRot(1)) ) + HdroExctn(I,J,3) = Fxy*( HdroExctn_Local(I,J,3) ) + HdroExctn(I,J,4) = Fxy*( HdroExctn_Local(I,J,4)*cos(InitInp%PtfmRefztRot(1)) - HdroExctn_Local(I,J,5)*sin(InitInp%PtfmRefztRot(1)) ) + HdroExctn(I,J,5) = Fxy*( HdroExctn_Local(I,J,4)*sin(InitInp%PtfmRefztRot(1)) + HdroExctn_Local(I,J,5)*cos(InitInp%PtfmRefztRot(1)) ) + HdroExctn(I,J,6) = Fxy*( HdroExctn_Local(I,J,6) ) + + end do + end do + deallocate(HdroExctn_Local) + else + + ! Apply rotation only for NBodyMod = 1,3 + do J = 1, NInpWvDir + do I = 1, NInpFreq + + Ctmp1 = ( HdroExctn(I,J,1)*cos(InitInp%PtfmRefztRot(1)) ) - ( HdroExctn(I,J,2)*sin(InitInp%PtfmRefztRot(1)) ) + Ctmp2 = ( HdroExctn(I,J,1)*sin(InitInp%PtfmRefztRot(1)) ) + ( HdroExctn(I,J,2)*cos(InitInp%PtfmRefztRot(1)) ) + Ctmp4 = ( HdroExctn(I,J,4)*cos(InitInp%PtfmRefztRot(1)) ) - ( HdroExctn(I,J,5)*sin(InitInp%PtfmRefztRot(1)) ) + Ctmp5 = ( HdroExctn(I,J,4)*sin(InitInp%PtfmRefztRot(1)) ) + ( HdroExctn(I,J,5)*cos(InitInp%PtfmRefztRot(1)) ) + + HdroExctn(I,J,1) = Ctmp1 + HdroExctn(I,J,2) = Ctmp2 + HdroExctn(I,J,4) = Ctmp4 + HdroExctn(I,J,5) = Ctmp5 + end do + end do + + end if + ! Compute the positive-frequency components (including zero) of the discrete ! Fourier transform of the wave excitation force: @@ -959,11 +1068,12 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init ! Compute the frequency of this component: Omega = I*InitInp%WaveDOmega + ! Compute the discrete Fourier transform of the instantaneous value of the ! total excitation force on the support platfrom from incident waves: - DO J = 1,6 ! Loop through all wave excitation forces and moments + DO J = 1,6*p%NBody ! Loop through all wave excitation forces and moments TmpCoord(1) = Omega TmpCoord(2) = InitInp%WaveDirArr(I) CALL WAMIT_Interp2D_Cplx( TmpCoord, HdroExctn(:,:,J), HdroFreq, HdroWvDir, LastInd2, WaveExctnC(I,J), ErrStat2, ErrMsg2 ) @@ -1021,7 +1131,7 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init RETURN END IF - DO J = 1,6 ! Loop through all wave excitation forces and moments + DO J = 1,6*p%NBody ! Loop through all wave excitation forces and moments CALL ApplyFFT_cx ( p%WaveExctn(0:InitInp%NStepWave-1,J), WaveExctnC(:,J), FFT_Data, ErrStat2 ) CALL SetErrStat( ErrStat2, ' An error occured while applying an FFT to WaveExctnC.', ErrStat, ErrMsg, 'WAMIT_Init') IF ( ErrStat >= AbortErrLev) THEN @@ -1044,18 +1154,80 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init SS_Exctn_InitInp%InputFile = InitInp%WAMITFile SS_Exctn_InitInp%WaveDir = InitInp%WaveDir SS_Exctn_InitInp%NStepWave = p%NStepWave + SS_Exctn_InitInp%NBody = InitInp%NBody + SS_Exctn_InitInp%PtfmRefztRot = InitInp%PtfmRefztRot + + + + if (allocated(InitInp%WaveElev0)) then + ! No other modules need this WaveElev0 array so we will simply move the allocation over to the SS_Exctn module - IF (ALLOCATED(InitInp%WaveElev0)) CALL MOVE_ALLOC(InitInp%WaveElev0, SS_Exctn_InitInp%WaveElev0) + call MOVE_ALLOC(InitInp%WaveElev0, SS_Exctn_InitInp%WaveElev0) - ! We need the WaveTime array to stay intact for use in other modules, so we will make a copy instead of moving the allocation - ALLOCATE ( SS_Exctn_InitInp%WaveTime (0:InitInp%NStepWave) , STAT=ErrStat2 ) - IF ( ErrStat2 /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, 'Error allocating memory for the SS_Exctn_InitInp%WaveTime array.', ErrStat, ErrMsg, 'WAMIT_Init') - CALL Cleanup() - RETURN - END IF - SS_Exctn_InitInp%WaveTime = InitInp%WaveTime + + ! Handle special case when NBodyMod=2 and (PtfmRefxt /= 0 or PtfmRefyt /= 0) : Need to phase shift the wave elevation data for the offset body + if ( p%NBodyMod==2 .and. (InitInp%PtfmRefxt(1) /= 0 .or. InitInp%PtfmRefyt(1) /= 0) ) then + + ! Need to start with the DFT of the Wave Elevation data at the Platform reference point: InitInp%WaveElevC0 + + ! Now apply the phase shift in the frequency space + + do J = 1, NInpWvDir + do I = 0,InitInp%NStepWave2 ! Loop through the positive frequency components (including zero) of the discrete Fourier transform + + ! Compute the frequency of this component: + + Omega = I*InitInp%WaveDOmega + ! Fxy = exp(-j * k(w) * ( X*cos(Beta(w)) + Y*sin(Beta(w)) ) + WaveNmbr = WaveNumber ( Omega, InitInp%Gravity, InitInp%WtrDpth ) + tmpAngle = WaveNmbr * ( InitInp%PtfmRefxt(1)*cos(HdroWvDir(J)*D2R) + InitInp%PtfmRefyt(1)*sin(HdroWvDir(J)*D2R) ) + TmpRe = cos(tmpAngle) + TmpIm = -sin(tmpAngle) + Fxy = CMPLX( TmpRe, TmpIm ) + + tmpComplexArr(I) = Fxy*CMPLX(InitInp%WaveElevC0(1,I), InitInp%WaveElevC0(2,I)) + + + end do + end do + + ! Compute the inverse discrete Fourier transforms to find the time-domain + ! representations of the wave kinematics without stretcing: + + CALL InitFFT ( InitInp%NStepWave, FFT_Data, .TRUE., ErrStat2 ) + CALL SetErrStat(ErrStat2,'Error occured while initializing the FFT.',ErrStat,ErrMsg,'WAMIT_Init') + IF ( ErrStat >= AbortErrLev ) THEN + CALL CleanUp() + RETURN + END IF + + ! We'll need the following for wave stretching once we implement it. + CALL ApplyFFT_cx ( SS_Exctn_InitInp%WaveElev0(0:InitInp%NStepWave-1), tmpComplexArr(: ), FFT_Data, ErrStat2 ) + CALL SetErrStat(ErrStat2,'Error occured while applying the FFT to WaveElev0.',ErrStat,ErrMsg,'WAMIT_Init') + IF ( ErrStat >= AbortErrLev ) THEN + CALL CleanUp() + RETURN + END IF + + CALL ExitFFT(FFT_Data, ErrStat2) + CALL SetErrStat( ErrStat2, 'Error in call to ExitFFT.', ErrStat, ErrMsg, 'WAMIT_Init') + IF ( ErrStat >= AbortErrLev) THEN + CALL Cleanup() + RETURN + END IF + + end if + ! We need the WaveTime array to stay intact for use in other modules, so we will make a copy instead of moving the allocation + ALLOCATE ( SS_Exctn_InitInp%WaveTime (0:InitInp%NStepWave) , STAT=ErrStat2 ) + IF ( ErrStat2 /= 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Error allocating memory for the SS_Exctn_InitInp%WaveTime array.', ErrStat, ErrMsg, 'WAMIT_Init') + CALL Cleanup() + RETURN + END IF + SS_Exctn_InitInp%WaveTime = InitInp%WaveTime + + end if call SS_Exc_Init(SS_Exctn_InitInp, m%SS_Exctn_u, p%SS_Exctn, x%SS_Exctn, xd%SS_Exctn, z%SS_Exctn, OtherState%SS_Exctn, & m%SS_Exctn_y, m%SS_Exctn, Interval_Sub, SS_Exctn_InitOut, ErrStat2, ErrMsg2) @@ -1093,7 +1265,7 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init CALL MOVE_ALLOC( HdroFreq, Conv_Rdtn_InitInp%HdroFreq ) CALL MOVE_ALLOC( HdroAddMs, Conv_Rdtn_InitInp%HdroAddMs ) CALL MOVE_ALLOC( HdroDmpng, Conv_Rdtn_InitInp%HdroDmpng ) - + Conv_Rdtn_InitInp%NBody = InitInp%NBody Conv_Rdtn_InitInp%RdtnTMax = InitInp%RdtnTMax Conv_Rdtn_InitInp%RdtnDT = InitInp%Conv_Rdtn%RdtnDT Conv_Rdtn_InitInp%HighFreq = HighFreq @@ -1116,8 +1288,21 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init ELSE IF ( InitInp%RdtnMod == 2 ) THEN SS_Rdtn_InitInp%InputFile = InitInp%WAMITFile - SS_Rdtn_InitInp%DOFs = 1 + + call AllocAry(SS_Rdtn_InitInp%enabledDOFs, 6*p%NBody, 'SS_Rdtn_InitInp%enabledDOFs', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'WAMIT_Init') + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + END IF + SS_Rdtn_InitInp%enabledDOFs = 1 ! Set to 1 (True) for all DOFs, meaning each DOF is to be used in the analysis. Interval_Sub = InitInp%Conv_Rdtn%RdtnDT + SS_Rdtn_InitInp%NBody = InitInp%NBody + call AllocAry(SS_Rdtn_InitInp%PtfmRefztRot, p%NBody, 'SS_Rdtn_InitInp%PtfmRefztRot', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'WAMIT_Init') + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + END IF + SS_Rdtn_InitInp%PtfmRefztRot = InitInp%PtfmRefztRot CALL SS_Rad_Init(SS_Rdtn_InitInp, m%SS_Rdtn_u, p%SS_Rdtn, x%SS_Rdtn, xd%SS_Rdtn, z%SS_Rdtn, OtherState%SS_Rdtn, & m%SS_Rdtn_y, m%SS_Rdtn, Interval_Sub, SS_Rdtn_InitOut, ErrStat2, ErrMsg2) @@ -1150,89 +1335,89 @@ SUBROUTINE WAMIT_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init - ! Define system output initializations (set up mesh) here: - + ! Define system output initializations (set up meshes) here: + ! Create the input and output meshes associated with lumped loads + - CALL MeshCreate( BlankMesh = u%Mesh & - ,IOS = COMPONENT_INPUT & - ,Nnodes = 1 & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 & - ,TranslationDisp = .TRUE. & - ,Orientation = .TRUE. & - ,TranslationVel = .TRUE. & - ,RotationVel = .TRUE. & - ,TranslationAcc = .TRUE. & - ,RotationAcc = .TRUE.) + + call MeshCreate( BlankMesh = u%Mesh & + ,IOS = COMPONENT_INPUT & + ,Nnodes = p%NBody & + ,ErrStat = ErrStat2 & + ,ErrMess = ErrMsg2 & + ,TranslationDisp = .TRUE. & + ,Orientation = .TRUE. & + ,TranslationVel = .TRUE. & + ,RotationVel = .TRUE. & + ,TranslationAcc = .TRUE. & + ,RotationAcc = .TRUE.) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - ! Create the node on the mesh - + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + END IF + do iBody = 1, p%NBody + + theta = (/ 0.0_R8Ki, 0.0_R8Ki, InitInp%PtfmRefztRot(iBody)/) + orientation = EulerConstruct(theta) - CALL MeshPositionNode (u%Mesh & - , 1 & - , (/0.0_ReKi, 0.0_ReKi, 0.0_ReKi/) & - , ErrStat2 & - , ErrMsg2 ) - - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') - - - ! Create the mesh element - CALL MeshConstructElement ( u%Mesh & - , ELEMENT_POINT & - , ErrStat2 & - , ErrMsg2 & - , 1 & - ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') + + ! Create the node on the mesh + + CALL MeshPositionNode (u%Mesh & + , iBody & + , (/InitInp%PtfmRefxt(iBody), InitInp%PtfmRefyt(iBody), InitInp%PtfmRefzt(iBody)/) & + , ErrStat2 & + , ErrMsg2 & + , orientation ) + + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') + + + ! Create the mesh element + CALL MeshConstructElement ( u%Mesh & + , ELEMENT_POINT & + , ErrStat2 & + , ErrMsg2 & + , iBody & + ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') + + end do CALL MeshCommit ( u%Mesh & - , ErrStat2 & - , ErrMsg2 ) + , ErrStat2 & + , ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN END IF - - CALL MeshCopy ( SrcMesh = u%Mesh & - ,DestMesh = y%Mesh & - ,CtrlCode = MESH_SIBLING & - ,IOS = COMPONENT_OUTPUT & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 & - ,Force = .TRUE. & - ,Moment = .TRUE. ) - - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') + call MeshCopy ( SrcMesh = u%Mesh & + ,DestMesh = y%Mesh & + ,CtrlCode = MESH_SIBLING & + ,IOS = COMPONENT_OUTPUT & + ,ErrStat = ErrStat2 & + ,ErrMess = ErrMsg2 & + ,Force = .TRUE. & + ,Moment = .TRUE. ) + + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN - END IF - + END IF + u%Mesh%RemapFlag = .TRUE. + y%Mesh%RemapFlag = .TRUE. + - u%Mesh%RemapFlag = .TRUE. - y%Mesh%RemapFlag = .TRUE. - ! Define initialization-routine output here: - ! Initialize the outputs - CALL WMTOUT_Init( InitInp, y, p, InitOut, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'WAMIT_Init') - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF @@ -1364,6 +1549,10 @@ SUBROUTINE WAMIT_UpdateStates( t, n, Inputs, InputTimes, p, x, xd, z, OtherState INTEGER :: I ! Generic loop counter INTEGER :: nTime ! Number of inputs + integer(IntKi) :: iBody ! WAMIT body index + + integer(IntKi) :: indxStart, indxEnd ! Starting and ending indices for the iBody_th sub vector in an NBody long vector + ! INTEGER(IntKi) :: ErrStat2 ! Error status of the operation (secondary error) ! CHARACTER(ErrMsgLen) :: ErrMsg2 ! Error message if ErrStat2 /= ErrID_None @@ -1385,10 +1574,6 @@ SUBROUTINE WAMIT_UpdateStates( t, n, Inputs, InputTimes, p, x, xd, z, OtherState nTime = size(Inputs) - - - - IF ( p%RdtnMod == 1 ) THEN ! Update the convolution radiation memory effect sub-module's state ! Allocate array of Conv_Rdtn inputs @@ -1400,7 +1585,16 @@ SUBROUTINE WAMIT_UpdateStates( t, n, Inputs, InputTimes, p, x, xd, z, OtherState END IF DO I=1,nTime - Conv_Rdtn_u(I)%Velocity = (/Inputs(I)%Mesh%TranslationVel(:,1), Inputs(I)%Mesh%RotationVel(:,1)/) + ALLOCATE( Conv_Rdtn_u(I)%Velocity(size(m%Conv_Rdtn_u%Velocity)), STAT = ErrStat ) + IF (ErrStat /=0) THEN + ErrMsg = ' Failed to allocate array Conv_Rdtn_u(I)%Velocity.' + RETURN + END IF + do iBody=1,p%NBody + indxStart = (iBody-1)*6+1 + indxEnd = indxStart+5 + Conv_Rdtn_u(I)%Velocity(indxStart:indxEnd) = (/Inputs(I)%Mesh%TranslationVel(:,iBody), Inputs(I)%Mesh%RotationVel(:,iBody)/) + end do END DO CALL Conv_Rdtn_UpdateStates( t, n, Conv_Rdtn_u, InputTimes, p%Conv_Rdtn, x%Conv_Rdtn, xd%Conv_Rdtn, & @@ -1419,9 +1613,17 @@ SUBROUTINE WAMIT_UpdateStates( t, n, Inputs, InputTimes, p, x, xd, z, OtherState END IF DO I=1,nTime - SS_Rdtn_u(I)%dq(1:3) = Inputs(I)%Mesh%TranslationVel(:,1) - SS_Rdtn_u(I)%dq(4:6) = Inputs(I)%Mesh%RotationVel(:,1) - !SS_Rdtn_u(I)%dq = reshape((/Inputs(I)%Mesh%TranslationVel(:,1), Inputs(I)%Mesh%RotationVel(:,1)/), (/6,1/)) !reshape(u%Velocity, (/6,1/)) ! dq is a 6x1 matrix + ALLOCATE( SS_Rdtn_u(I)%dq(size(m%SS_Rdtn_u%dq)), STAT = ErrStat ) + IF (ErrStat /=0) THEN + ErrMsg = ' Failed to allocate array SS_Rdtn_u(I)%dq.' + RETURN + END IF + do iBody=1,p%NBody + indxStart = (iBody-1)*6+1 + SS_Rdtn_u(I)%dq(indxStart:indxStart+2) = Inputs(I)%Mesh%TranslationVel(:,iBody) + SS_Rdtn_u(I)%dq(indxStart+3:indxStart+5) = Inputs(I)%Mesh%RotationVel(:,iBody) + !SS_Rdtn_u(I)%dq = reshape((/Inputs(I)%Mesh%TranslationVel(:,1), Inputs(I)%Mesh%RotationVel(:,1)/), (/6,1/)) !reshape(u%Velocity, (/6,1/)) ! dq is a 6x1 matrix + end do END DO CALL SS_Rad_UpdateStates( t, n, SS_Rdtn_u, InputTimes, p%SS_Rdtn, x%SS_Rdtn, xd%SS_Rdtn, z%SS_Rdtn, OtherState%SS_Rdtn, m%SS_Rdtn, ErrStat, ErrMsg ) @@ -1449,10 +1651,11 @@ SUBROUTINE WAMIT_UpdateStates( t, n, Inputs, InputTimes, p, x, xd, z, OtherState END SUBROUTINE WAMIT_UpdateStates !---------------------------------------------------------------------------------------------------------------------------------- !> Routine for computing outputs, used in both loose and tight coupling. -SUBROUTINE WAMIT_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) +SUBROUTINE WAMIT_CalcOutput( Time, WaveTime, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) !.................................................................................................................................. REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds + real(SiKi), intent(in ) :: WaveTime(:) !< Array of wave kinematic time samples, (sec) TYPE(WAMIT_InputType), INTENT(IN ) :: u !< Inputs at Time TYPE(WAMIT_ParameterType), INTENT(IN ) :: p !< Parameters TYPE(WAMIT_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time @@ -1474,9 +1677,11 @@ SUBROUTINE WAMIT_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, Er INTEGER(IntKi) :: I ! Generic index INTEGER(IntKi) :: J ! Generic index ! INTEGER(IntKi) :: K ! Generic index - REAL(ReKi) :: q(6), qdot(6), qdotdot(6) + REAL(ReKi) :: q(6*p%NBody), qdot(6*p%NBody), qdotdot(6*p%NBody) ! kinematics for all WAMIT bodies REAL(ReKi) :: rotdisp(3) ! small angle rotational displacements - REAL(ReKi) :: AllOuts(MaxWAMITOutputs) + REAL(ReKi) :: AllOuts(MaxWAMITOutputs) + integer(IntKi) :: iBody ! Counter for WAMIT bodies. If NBodyMod > 1 then NBody = 1, and hence iBody = 1 + integer(IntKi) :: indxStart, indxEnd ! Starting and ending indices for the iBody_th sub vector in an NBody long vector ! Initialize ErrStat @@ -1503,11 +1708,10 @@ SUBROUTINE WAMIT_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, Er RETURN END IF - DO I = 1,6 ! Loop through all wave excitation forces and moments - m%F_Waves1(I) = InterpWrappedStpReal ( REAL(Time, SiKi), p%WaveTime(:), p%WaveExctn(:,I), & + DO I = 1,6*p%NBody ! Loop through all wave excitation forces and moments + m%F_Waves1(I) = InterpWrappedStpReal ( REAL(Time, SiKi), WaveTime(:), p%WaveExctn(:,I), & m%LastIndWave, p%NStepWave + 1 ) END DO ! I - All wave excitation forces and moments - else if ( p%ExctnMod == 2 ) then call SS_Exc_CalcOutput( Time, m%SS_Exctn_u, p%SS_Exctn, x%SS_Exctn, xd%SS_Exctn, & @@ -1517,42 +1721,29 @@ SUBROUTINE WAMIT_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, Er end if - + do iBody = 1, p%NBody - ! Determine the rotational angles from the direction-cosine matrix - rotdisp = GetSmllRotAngs ( u%Mesh%Orientation(:,:,1), ErrStat, ErrMsg ) - - q = reshape((/real(u%Mesh%TranslationDisp(:,1),ReKi),rotdisp(:)/),(/6/)) - qdot = reshape((/u%Mesh%TranslationVel(:,1),u%Mesh%RotationVel(:,1)/),(/6/)) - qdotdot = reshape((/u%Mesh%TranslationAcc(:,1),u%Mesh%RotationAcc(:,1)/),(/6/)) - - - ! Compute the load contirbution from user-supplied added stiffness and damping - ! This is being done by the HydroDyn Module now. GJH 1/6/14 - m%F_PtfmAdd = 0.0 ! p%AddF0 - matmul(p%AddCLin, q) - matmul(p%AddBLin, qdot) - matmul(p%AddBQuad, qdotsq) - - - - + ! Determine the rotational angles from the direction-cosine matrix + rotdisp = GetSmllRotAngs ( u%Mesh%Orientation(:,:,iBody), ErrStat, ErrMsg ) + indxStart = (iBody-1)*6+1 + indxEnd = indxStart+5 + q (indxStart:indxEnd) = reshape((/real(u%Mesh%TranslationDisp(:,iBody),ReKi),rotdisp(:)/),(/6/)) + qdot (indxStart:indxEnd) = reshape((/u%Mesh%TranslationVel(:,iBody),u%Mesh%RotationVel(:,iBody)/),(/6/)) + qdotdot(indxStart:indxEnd) = reshape((/u%Mesh%TranslationAcc(:,iBody),u%Mesh%RotationAcc(:,iBody)/),(/6/)) + + end do ! Compute the load contribution from hydrostatics: - m%F_HS(:) = 0.0 ! Initialize to zero... - m%F_HS(3) = p%RhoXg*p%PtfmVol0 ! except for the hydrostatic buoyancy force from Archimede's Principle when the support platform is in its undisplaced position - m%F_HS(4) = p%RhoXg*p%PtfmVol0*p%PtfmCOByt ! and the moment about X due to the COB being offset from the WAMIT reference point - m%F_HS(5) = -p%RhoXg*p%PtfmVol0*p%PtfmCOBxt ! and the moment about Y due to the COB being offset from the WAMIT reference point - - DO I = 1,6 ! Loop through all hydrostatic forces and moments - DO J = 1,6 ! Loop through all platform DOFs - m%F_HS(I) = m%F_HS(I) - p%HdroSttc(I,J)*q(J) - END DO ! J - platform DOFs - - END DO ! I - All hydrostatic forces and moments + m%F_HS = -matmul(p%HdroSttc,q) - - + do iBody = 1, p%NBody + indxStart = (iBody-1)*6+1 + indxEnd = indxStart+5 + m%F_HS(indxStart:indxEnd) = m%F_HS(indxStart:indxEnd) + p%F_HS_Moment_Offset(:,iBody) ! except for the hydrostatic buoyancy force from Archimede's Principle when the support platform is in its undisplaced position + end do - + ! If necessary, compute the load contribution from wave radiation damping ! (i.e., the radiation problem): @@ -1591,31 +1782,20 @@ SUBROUTINE WAMIT_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, Er ! Compute outputs here: - DO I=1,3 - y%Mesh%Force(I,1) = m%F_PtfmAM(I) + m%F_Rdtn(I) + m%F_Waves1(I) + m%F_HS(I) + m%F_PtfmAdd(I) - END DO - DO I=1,3 - y%Mesh%Moment(I,1) = m%F_PtfmAM(I+3) + m%F_Rdtn(I+3) + m%F_Waves1(I+3) + m%F_HS(I+3) + m%F_PtfmAdd(I+3) - END DO - - - - - - - - ! Map calculated results into the AllOuts Array - CALL WMTOut_MapOutputs(Time, y, m%F_Waves1, m%F_HS, m%F_Rdtn, m%F_PtfmAM, AllOuts, ErrStat, ErrMsg) + do iBody = 1, p%NBody + indxStart = (iBody-1)*6 + + DO I=1,3 + y%Mesh%Force(I,iBody) = m%F_PtfmAM(indxStart+I) + m%F_Rdtn(indxStart+I) + m%F_Waves1(indxStart+I) + m%F_HS(indxStart+I) + END DO + DO I=1,3 + y%Mesh%Moment(I,iBody) = m%F_PtfmAM(indxStart+I+3) + m%F_Rdtn(indxStart+I+3) + m%F_Waves1(indxStart+I+3) + m%F_HS(indxStart+I+3) + END DO + end do - - ! Put the output data in the OutData array - - DO I = 1,p%NumOuts - - y%WriteOutput(I) = p%OutParam(I)%SignM * AllOuts( p%OutParam(I)%Indx ) - END DO - + ! Output channels will be dealt with by the HydroDyn module + END SUBROUTINE WAMIT_CalcOutput !---------------------------------------------------------------------------------------------------------------------------------- @@ -1635,23 +1815,31 @@ SUBROUTINE WAMIT_CalcContStateDeriv( Time, u, p, x, xd, z, OtherState, m, dxdt, INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - + integer(IntKi) :: iBody ! WAMIT body index + integer(IntKi) :: indxStart ! Starting and ending indices for the iBody_th sub vector in an NBody long vector + ! Initialize ErrStat ErrStat = ErrID_None ErrMsg = "" - ! Compute the first time derivatives of the continuous states here: - m%SS_Rdtn_u%dq(1:3) = u%Mesh%TranslationVel(:,1) - m%SS_Rdtn_u%dq(4:6) = u%Mesh%RotationVel(:,1) - - CALL SS_Rad_CalcContStateDeriv( Time, m%SS_Rdtn_u, p%SS_Rdtn, x%SS_Rdtn, xd%SS_Rdtn, z%SS_Rdtn, OtherState%SS_Rdtn, m%SS_Rdtn, dxdt%SS_Rdtn, ErrStat, ErrMsg ) + ! Compute the first time derivatives of the continuous states here: + if (p%RdtnMod == 2) then + do iBody = 1, p%NBody + indxStart = (iBody-1)*6+1 + m%SS_Rdtn_u%dq(indxStart:indxStart+2) = u%Mesh%TranslationVel(:,iBody) + m%SS_Rdtn_u%dq(indxStart+3:indxStart+5) = u%Mesh%RotationVel(:,iBody) + end do + CALL SS_Rad_CalcContStateDeriv( Time, m%SS_Rdtn_u, p%SS_Rdtn, x%SS_Rdtn, xd%SS_Rdtn, z%SS_Rdtn, OtherState%SS_Rdtn, m%SS_Rdtn, dxdt%SS_Rdtn, ErrStat, ErrMsg ) + end if + ! NOTE: The input below (0.0) will only work as part of a linearization Get_OP call! If this routine (WAMIT_CalcContStateDeriv) is called in another context, then the following - ! input needs to be implemented generically. - CALL SS_Exc_CalcContStateDeriv( Time, 0.0_SiKi, p%SS_Exctn, x%SS_Exctn, xd%SS_Exctn, z%SS_Exctn, OtherState%SS_Exctn, m%SS_Exctn, dxdt%SS_Exctn, ErrStat, ErrMsg ) - + ! input needs to be implemented generically. As of Aug 10, 2020, this is only called for Get_OP related work. GJH + if (p%ExctnMod == 2) then + CALL SS_Exc_CalcContStateDeriv( Time, 0.0_SiKi, p%SS_Exctn, x%SS_Exctn, xd%SS_Exctn, z%SS_Exctn, OtherState%SS_Exctn, m%SS_Exctn, dxdt%SS_Exctn, ErrStat, ErrMsg ) + end if END SUBROUTINE WAMIT_CalcContStateDeriv !---------------------------------------------------------------------------------------------------------------------------------- @@ -1672,7 +1860,9 @@ SUBROUTINE WAMIT_UpdateDiscState( Time, n, u, p, x, xd, z, OtherState, m, ErrSta INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - + integer(IntKi) :: iBody ! WAMIT body index + integer(IntKi) :: indxStart, indxEnd ! Starting and ending indices for the iBody_th sub vector in an NBody long vector + ! Initialize ErrStat ErrStat = ErrID_None @@ -1681,9 +1871,11 @@ SUBROUTINE WAMIT_UpdateDiscState( Time, n, u, p, x, xd, z, OtherState, m, ErrSta ! Update discrete states here: IF ( p%RdtnMod == 1 ) THEN ! .TRUE. when we will be modeling wave radiation damping. - - m%Conv_Rdtn_u%Velocity = (/u%Mesh%TranslationVel(:,1), u%Mesh%RotationVel(:,1)/) - + do iBody=1,p%NBody + indxStart = (iBody-1)*6+1 + indxEnd = indxStart+5 + m%Conv_Rdtn_u%Velocity(indxStart:indxEnd) = (/u%Mesh%TranslationVel(:,iBody), u%Mesh%RotationVel(:,iBody)/) + end do CALL Conv_Rdtn_UpdateDiscState( Time, n, m%Conv_Rdtn_u, p%Conv_Rdtn, x%Conv_Rdtn, xd%Conv_Rdtn, z%Conv_Rdtn, & OtherState%Conv_Rdtn, m%Conv_Rdtn, ErrStat, ErrMsg ) diff --git a/modules/hydrodyn/src/WAMIT.txt b/modules/hydrodyn/src/WAMIT.txt index b4aedf027e..0317f50c9f 100644 --- a/modules/hydrodyn/src/WAMIT.txt +++ b/modules/hydrodyn/src/WAMIT.txt @@ -17,12 +17,20 @@ usefrom Conv_Radiation.txt usefrom SS_Radiation.txt usefrom SS_Excitation.txt usefrom Waves.txt -param WAMIT/WAMIT unused INTEGER MaxWAMITOutputs - 18 - "" - -typedef WAMIT/WAMIT InitInputType ReKi PtfmVol0 - - - "" - +param WAMIT/WAMIT unused INTEGER MaxWAMITOutputs - 18 - "" - +typedef ^ InitInputType INTEGER NBody - - - "[>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6]" - +typedef ^ ^ INTEGER NBodyMod - - - "Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1]" - +typedef ^ ^ ReKi Gravity - - - "Supplied by Driver: Gravitational acceleration" "(m/s^2)" +typedef ^ ^ SiKi WtrDpth - - - "Water depth (positive-valued)" m +typedef ^ ^ ReKi PtfmVol0 {:} - - "" - typedef ^ ^ LOGICAL HasWAMIT - - - ".TRUE. if using WAMIT model, .FALSE. otherwise" - typedef ^ ^ ReKi WAMITULEN - - - "" - -typedef ^ ^ ReKi PtfmCOBxt - - - "" - -typedef ^ ^ ReKi PtfmCOByt - - - "" - +typedef ^ ^ ReKi PtfmRefxt {:} - - "The xt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1 ]" (m) +typedef ^ ^ ReKi PtfmRefyt {:} - - "The yt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1 ]" (m) +typedef ^ ^ ReKi PtfmRefzt {:} - - "The zt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1; must be 0.0 if NBodyMod=2 ]" (m) +typedef ^ ^ R8Ki PtfmRefztRot {:} - - "The rotation about zt of the body reference frame(s) from xt/yt" radians +typedef ^ ^ ReKi PtfmCOBxt {:} - - "" - +typedef ^ ^ ReKi PtfmCOByt {:} - - "" - typedef ^ ^ INTEGER RdtnMod - - - "" - typedef ^ ^ INTEGER ExctnMod - - - "" - typedef ^ ^ DbKi RdtnTMax - - - "" - @@ -49,10 +57,7 @@ typedef ^ ^ INTEGER # # # Define outputs from the initialization routine here: -# -#typedef ^ InitOutputType MeshType OutputMesh - - - "" - -typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {:} - - "" - -typedef ^ ^ CHARACTER(ChanLen) WriteOutputUnt {:} - - "" - +typedef ^ InitOutputType ReKi NULLVAL - - - "" - # # # ..... States .................................................................................................................... @@ -88,11 +93,10 @@ typedef ^ ^ Conv_Rdtn_O # 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 INTEGER LastIndWave - - - "" - -typedef ^ ^ ReKi F_HS {6} - - "local variable in CalcOutput:Total load contribution from hydrostatics, including the effects of waterplane area and the center of buoyancy" "(N, N-m)" -typedef ^ ^ ReKi F_Waves1 {6} - - "local variable in CalcOutput:Total load contribution from incident waves (i.e., the diffraction problem)" "(N, N-m)" -typedef ^ ^ ReKi F_Rdtn {6} - - "local variable in CalcOutput:Total load contribution from wave radiation damping (i.e., the diffraction problem)" "(N, N-m)" -typedef ^ ^ ReKi F_PtfmAdd {6} - - "local variable in CalcOutput:set to zero because this is calculated in HydroDyn now" - -typedef ^ ^ ReKi F_PtfmAM {6} - - "local variable in CalcOutput:" - +typedef ^ ^ ReKi F_HS {:} - - "local variable in CalcOutput:Total load contribution from hydrostatics, including the effects of waterplane area and the center of buoyancy" "(N, N-m)" +typedef ^ ^ ReKi F_Waves1 {:} - - "local variable in CalcOutput:Total load contribution from incident waves (i.e., the diffraction problem)" "(N, N-m)" +typedef ^ ^ ReKi F_Rdtn {:} - - "local variable in CalcOutput:Total load contribution from wave radiation damping (i.e., the diffraction problem)" "(N, N-m)" +typedef ^ ^ ReKi F_PtfmAM {:} - - "local variable in CalcOutput:" - typedef ^ ^ SS_Rad_MiscVarType SS_Rdtn - - - "" - typedef ^ ^ SS_Rad_InputType SS_Rdtn_u - - - "" - typedef ^ ^ SS_Rad_OutputType SS_Rdtn_y - - - "" - @@ -107,30 +111,22 @@ typedef ^ ^ Conv_Rdtn_O # Define parameters here: # Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: # -typedef ^ ParameterType ReKi HdroAdMsI {6}{6} - - "" (sec) -typedef ^ ^ ReKi HdroSttc {6}{6} - - "" - -typedef ^ ^ ReKi PtfmVol0 - - - "" - -typedef ^ ^ ReKi PtfmCOBxt - - - "" - -typedef ^ ^ ReKi PtfmCOByt - - - "" - +typedef ^ ParameterType INTEGER NBody - - - "[>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6]" - +typedef ^ ^ INTEGER NBodyMod - - - "Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1]" - +typedef ^ ^ ReKi F_HS_Moment_Offset {:}{:} - - "The offset moment due to the COB being offset from the WAMIT body's local location {matrix 3xNBody}" N-m +typedef ^ ^ SiKi HdroAdMsI {:}{:} - - "" (sec) +typedef ^ ^ SiKi HdroSttc {:}{:} - - "" - typedef ^ ^ INTEGER RdtnMod - - - "" - -typedef ^ ^ INTEGER ExctnMod - - - "" - +typedef ^ ^ INTEGER ExctnMod - - - "" - typedef ^ ^ SiKi WaveExctn {:}{:} - - "" - -typedef ^ ^ ReKi RhoXg - - - "" - -typedef ^ ^ SiKi WaveTime {:} - - "" - typedef ^ ^ INTEGER NStepWave - - - "" - typedef ^ ^ Conv_Rdtn_ParameterType Conv_Rdtn - - - "" - typedef ^ ^ SS_Rad_ParameterType SS_Rdtn - - - "" - typedef ^ ^ SS_Exc_ParameterType SS_Exctn - - - "" - typedef ^ ^ DbKi DT - - - "" - -typedef ^ ^ LOGICAL PtfmSgF - - - "" - -typedef ^ ^ LOGICAL PtfmSwF - - - "" - -typedef ^ ^ LOGICAL PtfmHvF - - - "" - -typedef ^ ^ LOGICAL PtfmRF - - - "" - -typedef ^ ^ LOGICAL PtfmPF - - - "" - -typedef ^ ^ LOGICAL PtfmYF - - - "" - typedef ^ ^ OutParmType OutParam {:} - - "" - typedef ^ ^ INTEGER NumOuts - - - "" - -typedef ^ ^ INTEGER NumOutAll - - - "" - +typedef ^ ^ INTEGER NumOutAll - - - "" - typedef ^ ^ CHARACTER(20) OutFmt - - - "" - typedef ^ ^ CHARACTER(20) OutSFmt - - - "" - typedef ^ ^ CHARACTER(ChanLen) Delim - - - "" - @@ -140,10 +136,9 @@ typedef ^ ^ INTEGER # ..... Inputs .................................................................................................................... # Define inputs that are contained on the mesh here: # -typedef ^ InputType MeshType Mesh - - - "Displacements at the WAMIT reference point in the inertial frame" - +typedef ^ InputType MeshType Mesh - - - "Displacements at the WAMIT reference point in the inertial frame" - # # # ..... Outputs ................................................................................................................... # Define outputs that are contained on the mesh here: -typedef ^ OutputType MeshType Mesh - - - "Loads at the WAMIT reference point in the inertial frame" - -typedef ^ ^ ReKi WriteOutput {:} - - "" - +typedef ^ OutputType MeshType Mesh - - - "Loads at the WAMIT reference point in the inertial frame" - diff --git a/modules/hydrodyn/src/WAMIT2.f90 b/modules/hydrodyn/src/WAMIT2.f90 index af88651924..765e7c86eb 100644 --- a/modules/hydrodyn/src/WAMIT2.f90 +++ b/modules/hydrodyn/src/WAMIT2.f90 @@ -23,7 +23,7 @@ ! distributed under the License is distributed on an "AS IS" BASIS, ! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ! See the License for the specific language governing permissions and -! +! !********************************************************************************************************************************** MODULE WAMIT2 @@ -51,10 +51,9 @@ MODULE WAMIT2 !! - + USE Waves, ONLY: WaveNumber USE WAMIT2_Types USE WAMIT_Interp - USE WAMIT2_Output USE NWTC_Library USE NWTC_FFTPACK @@ -66,7 +65,7 @@ MODULE WAMIT2 TYPE(ProgDesc), PARAMETER :: WAMIT2_ProgDesc = ProgDesc( 'WAMIT2', '', '' ) !< This holds the name of the program, version info, and date. - REAL(DbKi), PARAMETER, PRIVATE :: OnePlusEps = 1.0 + EPSILON(OnePlusEps) ! The number slighty greater than unity in the precision of DbKi. + REAL(SiKi), PARAMETER, PRIVATE :: OnePlusEps = 1.0 + EPSILON(OnePlusEps) ! The number slighty greater than unity in the precision of SiKi. ! ..... Public Subroutines ................................................................................................... @@ -113,7 +112,7 @@ MODULE WAMIT2 !> This type is only used locally for holding data during the Initialization. It will not be used outside of the WAMIT2_Init !! routine. The 3D data is of the form F_k( WvFreq1, WvDir1, WvDir2, k ) where k is coordinate index to the load components - !! (surge, sway, heave, roll, pitch, yaw). DataSet is of size (NumFreq1,NumWvDir1,NumWvDir2,6). The LoadComponents array + !! (surge, sway, heave, roll, pitch, yaw). DataSet is of size (NumFreq1,NumWvDir1,NumWvDir2,6*NumBodies). The LoadComponents array !! contains flags that will indicate which of the LoadComponents were read in from the data file. !! !! The DataMask array is of the same size as the DataSet matrix and corresponds to it. Each point in DataMask that is true @@ -124,8 +123,9 @@ MODULE WAMIT2 INTEGER(IntKi) :: NumWvFreq1 !< Number of frequencies in first frequency direction set INTEGER(IntKi) :: NumWvDir1 !< Number of wave directions in first wave direction set INTEGER(IntKi) :: NumWvDir2 !< Number of wave directions in second wave direction set - LOGICAL :: DataIsSparse(6) !< Flag to indicate if the data is sparse or complete. One per component direction - LOGICAL :: LoadComponents(6) !< Which load components actually exist in the input file + INTEGER(IntKi) :: NumBodies !< Number of bodies in the file (based on highest LoadComponent listed) + LOGICAL, ALLOCATABLE :: DataIsSparse(:) !< Flag to indicate if the data is sparse or complete. One per component direction + LOGICAL, ALLOCATABLE :: LoadComponents(:) !< Which load components actually exist in the input file COMPLEX(SiKi), ALLOCATABLE :: DataSet(:,:,:,:) !< Storage for 3D data from the 2nd order WAMIT file LOGICAL, ALLOCATABLE :: DataMask(:,:,:,:) !< Mask for knowing which data points are complete, which are missing REAL(SiKi), ALLOCATABLE :: WvFreq1(:) !< (1:NumFreq1) elements -- values correspond to index 1 of DataSet @@ -136,7 +136,7 @@ MODULE WAMIT2 !> This type is only used locally for holding data during the Initialization. It will not be used outside of the WAMIT2_Init !! routine. The 4D data is of the form F_k( WvFreq1, WvFreq2, WvDir1, WvDir2, k ) where k is coordinate index to the load components - !! (surge, sway, heave, roll, pitch, yaw). DataSet is of size (NumFreq1,NumFreq2,NumWvDir1,NumWvDir2,6). The LoadComponents + !! (surge, sway, heave, roll, pitch, yaw). DataSet is of size (NumFreq1,NumFreq2,NumWvDir1,NumWvDir2,6*NumBodies). The LoadComponents !! array contains flags that will indicate which of the LoadComponents were read in from the data file. !! !! The DataMask array is of the same size as the DataSet matrix and corresponds to it. Each point in DataMask that is true @@ -147,10 +147,11 @@ MODULE WAMIT2 INTEGER(IntKi) :: NumWvFreq2 !< Number of frequencies in second frequency direction set INTEGER(IntKi) :: NumWvDir1 !< Number of wave directions in first wave direction set INTEGER(IntKi) :: NumWvDir2 !< Number of wave directions in second wave direction set - LOGICAL :: DataIsSparse(6) !< Flag to indicate if the data is sparse or complete. One per component direction + INTEGER(IntKi) :: NumBodies !< Number of bodies in the file (based on highest LoadComponent listed) + LOGICAL, ALLOCATABLE :: DataIsSparse(:) !< Flag to indicate if the data is sparse or complete. One per component direction LOGICAL :: WvFreqDiagComplete !< Flag to indicate if the diagonal element is complete or not (Omega_m, Omega_m). LOGICAL :: IsSumForce !< Flag to indicate that this is a sum type array. Used in setting the F_{nm} term from F_{mn} term. - LOGICAL :: LoadComponents(6) !< Which load components actually exist in the input file + LOGICAL, ALLOCATABLE :: LoadComponents(:) !< Which load components actually exist in the input file COMPLEX(SiKi), ALLOCATABLE :: DataSet(:,:,:,:,:) !< Storage for 4D data from the 2nd order WAMIT file LOGICAL, ALLOCATABLE :: DataMask(:,:,:,:,:) !< Mask for knowing which data points are complete, which are missing REAL(SiKi), ALLOCATABLE :: WvFreq1(:) !< (1:NumFreq1) elements -- values correspond to index 1 of DataSet @@ -224,10 +225,14 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini ! Local Variables -! TYPE(FFT_DataType) :: FFT_Data !< the instance of the FFT module we're using - - INTEGER(IntKi) :: I !< Generic counter + INTEGER(IntKi) :: IBody !< Counter for current body + INTEGER(IntKi) :: ThisDim !< Counter to currrent dimension INTEGER(IntKi) :: J !< Generic counter + INTEGER(IntKi) :: Idx !< Generic counter + REAL(R8Ki) :: theta(3) !< rotation about z for the current body (0 about x,y) + REAL(R8Ki) :: orientation(3,3) !< Orientation matrix for orientation of the current body + REAL(ReKi) :: XYZloc(3) !< Starting position of this WAMIT2 body + ! QTF storage -- from the data files that are read in TYPE(W2_DiffData_Type) :: MnDriftData !< Data storage for the Mean Drift method @@ -236,7 +241,7 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini TYPE(W2_SumData_Type) :: SumQTFData !< Data storage for the full sum QTF method ! Force arrays - REAL(SiKi) :: MnDriftForce(6) !< MnDrift force array. Constant for all time. First index is force component + REAL(SiKi), ALLOCATABLE :: MnDriftForce(:) !< MnDrift force array. Constant for all time. First index is force component REAL(SiKi), ALLOCATABLE :: NewmanAppForce(:,:) !< NewmanApp force array. Index 1: Time, Index 2: force component REAL(SiKi), ALLOCATABLE :: DiffQTFForce(:,:) !< DiffQTF force array. Index 1: Time, Index 2: force component REAL(SiKi), ALLOCATABLE :: SumQTFForce(:,:) !< SumQTF force array. Index 1: Time, Index 2: force component @@ -244,6 +249,7 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini ! Temporary error trapping variables INTEGER(IntKi) :: ErrStatTmp !< Temporary variable for holding the error status returned from a CALL statement CHARACTER(2048) :: ErrMsgTmp !< Temporary variable for holding the error message returned from a CALL statement + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_Init' !> ### Subroutine contents @@ -292,8 +298,8 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini !------------------------------------------------------------------------------------------------------------- !> 1. Check the data file related values (_MnDrift_, _MnDriftF_ etc). Also copy over important things from _InitInp_ to _p_ and _InitOut_. - CALL CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, DiffQTFData, SumQTFData, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init') + CALL CheckInitInput( InitInp, Interval, InitOut, p, MnDriftData, NewmanAppData, DiffQTFData, SumQTFData, ErrStatTmp, ErrMsgTmp ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp RETURN @@ -308,15 +314,15 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini !> If the MnDrift method will be used, read in the data for it. IF ( p%MnDriftF ) THEN IF ( MnDriftData%DataIs3D ) THEN - CALL Read_DataFile3D( TRIM(MnDriftData%Filename), MnDriftData%Data3D, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init') + CALL Read_DataFile3D( InitInp, TRIM(MnDriftData%Filename), MnDriftData%Data3D, ErrStatTmp, ErrMsgTmp ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) ELSEIF ( MnDriftData%DataIs4D ) THEN MnDriftData%Data4D%IsSumForce = .FALSE. - CALL Read_DataFile4D( TRIM(MnDriftData%Filename), MnDriftData%Data4D, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init') + CALL Read_DataFile4D( InitInp, TRIM(MnDriftData%Filename), MnDriftData%Data4D, ErrStatTmp, ErrMsgTmp ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) ELSE CALL SetErrStat( ErrID_Fatal, ' Programming error. MnDrift method flags incorrectly set by '// & - 'CheckInitInput subroutine.', ErrStat, ErrMsg, 'WAMIT2_Init' ) + 'CheckInitInput subroutine.', ErrStat, ErrMsg, RoutineName ) ENDIF IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp @@ -328,15 +334,15 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini !> If the NewmanApp method will be used, read in the data for it. IF ( p%NewmanAppF ) THEN IF ( NewmanAppData%DataIs3D ) THEN - CALL Read_DataFile3D( TRIM(NewmanAppData%Filename), NewmanAppData%Data3D, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init') + CALL Read_DataFile3D( InitInp, TRIM(NewmanAppData%Filename), NewmanAppData%Data3D, ErrStatTmp, ErrMsgTmp ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) ELSEIF ( NewmanAppData%DataIs4D ) THEN NewmanAppData%Data4D%IsSumForce = .FALSE. - CALL Read_DataFile4D( TRIM(NewmanAppData%Filename), NewmanAppData%Data4D, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init') + CALL Read_DataFile4D( InitInp, TRIM(NewmanAppData%Filename), NewmanAppData%Data4D, ErrStatTmp, ErrMsgTmp ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) ELSE CALL SetErrStat( ErrID_Fatal, ' Programming error. NewmanApp method flags incorrectly set by '// & - 'CheckInitInput subroutine.', ErrStat, ErrMsg, 'WAMIT2_Init' ) + 'CheckInitInput subroutine.', ErrStat, ErrMsg, RoutineName ) ENDIF IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp @@ -351,14 +357,14 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini IF ( p%DiffQTFF ) THEN IF ( DiffQTFData%DataIs3D ) THEN CALL SetErrStat( ErrID_Fatal, ' Programming error. DiffQTF method flags incorrectly set by '// & - 'CheckInitInput subroutine. 3D data cannot be used in the DiffQTF method.', ErrStat, ErrMsg, 'WAMIT2_Init' ) + 'CheckInitInput subroutine. 3D data cannot be used in the DiffQTF method.', ErrStat, ErrMsg, RoutineName ) ELSEIF ( DiffQTFData%DataIs4D ) THEN DiffQTFData%Data4D%IsSumForce = .FALSE. - CALL Read_DataFile4D( TRIM(DiffQTFData%Filename), DiffQTFData%Data4D, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init') + CALL Read_DataFile4D( InitInp, TRIM(DiffQTFData%Filename), DiffQTFData%Data4D, ErrStatTmp, ErrMsgTmp ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) ELSE CALL SetErrStat( ErrID_Fatal, ' Programming error. DiffQTF method flags incorrectly set by '// & - 'CheckInitInput subroutine.', ErrStat, ErrMsg, 'WAMIT2_Init' ) + 'CheckInitInput subroutine.', ErrStat, ErrMsg, RoutineName ) ENDIF IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp @@ -371,11 +377,11 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini IF ( p%SumQTFF ) THEN IF ( SumQTFData%DataIs4D ) THEN SumQTFData%Data4D%IsSumForce = .TRUE. - CALL Read_DataFile4D( TRIM(SumQTFData%Filename), SumQTFData%Data4D, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init') + CALL Read_DataFile4D( InitInp, TRIM(SumQTFData%Filename), SumQTFData%Data4D, ErrStatTmp, ErrMsgTmp ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) ELSE CALL SetErrStat( ErrID_Fatal, ' Programming error. SumQTF method flags incorrectly set by '// & - 'CheckInitInput subroutine.', ErrStat, ErrMsg, 'WAMIT2_Init' ) + 'CheckInitInput subroutine.', ErrStat, ErrMsg, RoutineName ) ENDIF IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp @@ -389,25 +395,32 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini !> 3. Now check the data to ensure that all the dimensions that were requested acually exist in the file. At !! this point, the MnDriftData and NewmanApp data will be either 3D or 4D, but not both. !! - !> Check the MnDrift data: check both in case we have already copied 4D data into the 3D. Will decide later which is used. IF ( p%MnDriftF ) THEN IF ( MnDriftData%DataIs3D ) THEN - ! Check the dimensions used. The LoadComponents(I) flag will be set to .TRUE. if data was found in the file - DO I=1,6 - IF ( p%MnDriftDims(I) .AND. ( .NOT. MnDriftData%Data3D%LoadComponents(I) ) ) & - CALL SetErrStat( ErrID_Fatal, ' '//TRIM(MnDriftData%Filename)//' does not contain information for the '// & - TRIM(Num2LStr(I))//' force component for the MnDrift method.', ErrStat,ErrMsg,'WAMIT2_Init') + ! Check the dimensions used. The LoadComponents(Idx) flag will be set to .TRUE. if data was found in the file + DO IBody=1,MnDriftData%Data3D%NumBodies + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( p%MnDriftDims(ThisDim) .AND. ( .NOT. MnDriftData%Data3D%LoadComponents(Idx) ) ) & + CALL SetErrStat( ErrID_Warn, ' '//TRIM(MnDriftData%Filename)//' does not contain information for the '// & + TRIM(Num2LStr(ThisDim))//' force component for the MnDrift method. Setting this component to zero.', & + ErrStat,ErrMsg,RoutineName) + ENDDO ENDDO ELSE IF ( MnDriftData%DataIs4D ) THEN - ! Check the dimensions used. The LoadComponents(I) flag will be set to .TRUE. if data was found in the file - DO I=1,6 - IF ( p%MnDriftDims(I) .AND. ( .NOT. MnDriftData%Data4D%LoadComponents(I) ) )& - CALL SetErrStat( ErrID_Fatal, ' '//TRIM(MnDriftData%Filename)//' does not contain information for the '// & - TRIM(Num2LStr(I))//' force component for the MnDrift method.', ErrStat,ErrMsg,'WAMIT2_Init') + ! Check the dimensions used. The LoadComponents(Idx) flag will be set to .TRUE. if data was found in the file + DO IBody=1,MnDriftData%Data4D%NumBodies + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( p%MnDriftDims(ThisDim) .AND. ( .NOT. MnDriftData%Data4D%LoadComponents(Idx) ) )& + CALL SetErrStat( ErrID_Warn, ' '//TRIM(MnDriftData%Filename)//' does not contain information for the '// & + TRIM(Num2LStr(ThisDim))//' force component for the MnDrift method. Setting this component to zero.', & + ErrStat,ErrMsg,RoutineName) + ENDDO ENDDO ELSE ! We didn't find any data to use... - CALL SetErrStat( ErrID_Fatal, ' Programming error. MnDrift flag is set, but no data has been read in.',ErrStat,ErrMsg, 'WAMIT2_Init') + CALL SetErrStat( ErrID_Fatal, ' Programming error. MnDrift flag is set, but no data has been read in.',ErrStat,ErrMsg, RoutineName) ENDIF IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp @@ -419,25 +432,29 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini !> Check the NewmanApp data: check both in case we have already copied 4D data into the 3D. Will decide later which is used. IF ( p%NewmanAppF ) THEN IF ( NewmanAppData%DataIs3D ) THEN - ! Check the dimensions used. The LoadComponents(I) flag will be set to .TRUE. if data was found in the file - DO I=1,6 - IF ( p%NewmanAppDims(I) ) THEN - IF ( .NOT. NewmanAppData%Data3D%LoadComponents(I) ) & - CALL SetErrStat( ErrID_Fatal, ' '//TRIM(NewmanAppData%Filename)//' does not contain information for the '// & - TRIM(Num2LStr(I))//' force component for the NewmanApp method.', ErrStat,ErrMsg,'WAMIT2_Init') - END IF + ! Check the dimensions used. The LoadComponents(Idx) flag will be set to .TRUE. if data was found in the file + DO IBody=1,NewmanAppData%Data3D%NumBodies + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( p%NewmanAppDims(ThisDim) .AND. ( .NOT. NewmanAppData%Data3D%LoadComponents(Idx) ) ) & + CALL SetErrStat( ErrID_Warn, ' '//TRIM(NewmanAppData%Filename)//' does not contain information for the '// & + TRIM(Num2LStr(ThisDim))//' force component for the NewmanApp method. Setting this component to zero.', & + ErrStat,ErrMsg,RoutineName) + ENDDO ENDDO ELSE IF ( NewmanAppData%DataIs4D ) THEN - ! Check the dimensions used. The LoadComponents(I) flag will be set to .TRUE. if data was found in the file - DO I=1,6 - IF ( p%NewmanAppDims(I) ) THEN - IF ( .NOT. NewmanAppData%Data4D%LoadComponents(I) ) & - CALL SetErrStat( ErrID_Fatal, ' '//TRIM(NewmanAppData%Filename)//' does not contain information for the '// & - TRIM(Num2LStr(I))//' force component for the NewmanApp method.', ErrStat,ErrMsg,'WAMIT2_Init') - END IF + ! Check the dimensions used. The LoadComponents(Idx) flag will be set to .TRUE. if data was found in the file + DO IBody=1,NewmanAppData%Data4D%NumBodies + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( p%NewmanAppDims(ThisDim) .AND. ( .NOT. NewmanAppData%Data4D%LoadComponents(Idx) ) ) & + CALL SetErrStat( ErrID_Warn, ' '//TRIM(NewmanAppData%Filename)//' does not contain information for the '// & + TRIM(Num2LStr(ThisDim))//' force component for the NewmanApp method. Setting this component to zero.', & + ErrStat,ErrMsg,RoutineName) + ENDDO ENDDO ELSE - CALL SetErrStat( ErrID_Fatal, ' Programming error. NewmanApp flag is set, but no data has been read in.',ErrStat,ErrMsg, 'WAMIT2_Init') + CALL SetErrStat( ErrID_Fatal, ' Programming error. NewmanApp flag is set, but no data has been read in.',ErrStat,ErrMsg, RoutineName) ENDIF IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp @@ -449,16 +466,18 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini !> Check the DiffQTF data: Don't check the 3D data. We may have copied 4D into it for the MnDrift term. IF ( p%DiffQTFF ) THEN IF ( DiffQTFData%DataIs4D ) THEN - ! Check the dimensions used. The LoadComponents(I) flag will be set to .TRUE. if data was found in the file - DO I=1,6 - IF ( p%DiffQTFDims(I) ) THEN - IF ( .NOT. DiffQTFData%Data4D%LoadComponents(I) ) & - CALL SetErrStat( ErrID_Fatal, ' '//TRIM(DiffQTFData%Filename)//' does not contain information for the '// & - TRIM(Num2LStr(I))//' force component for the DiffQTF method.', ErrStat,ErrMsg,'WAMIT2_Init') - END IF + ! Check the dimensions used. The LoadComponents(Idx) flag will be set to .TRUE. if data was found in the file + DO IBody=1,DiffQTFData%Data4D%NumBodies + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( p%DiffQTFDims(ThisDim) .AND. ( .NOT. DiffQTFData%Data4D%LoadComponents(Idx) ) ) & + CALL SetErrStat( ErrID_Warn, ' '//TRIM(DiffQTFData%Filename)//' does not contain information for the '// & + TRIM(Num2LStr(ThisDim))//' force component for the DiffQTF method. Setting this component to zero.', & + ErrStat,ErrMsg,RoutineName) + ENDDO ENDDO ELSE - CALL SetErrStat( ErrID_Fatal, ' Programming error. DiffQTF flag is set, but no data has been read in.',ErrStat,ErrMsg, 'WAMIT2_Init') + CALL SetErrStat( ErrID_Fatal, ' Programming error. DiffQTF flag is set, but no data has been read in.',ErrStat,ErrMsg, RoutineName) ENDIF IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp @@ -470,16 +489,18 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini !> Check the SumQTF data IF ( p%SumQTFF ) THEN IF ( SumQTFData%DataIs4D ) THEN - ! Check the dimensions used. The LoadComponents(I) flag will be set to .TRUE. if data was found in the file - DO I=1,6 - IF ( p%SumQTFDims(I) ) THEN - IF ( .NOT. SumQTFData%Data4D%LoadComponents(I) ) & - CALL SetErrStat( ErrID_Fatal, ' '//TRIM(SumQTFData%Filename)//' does not contain information for the '// & - TRIM(Num2LStr(I))//' force component for the SumQTF method.', ErrStat,ErrMsg,'WAMIT2_Init') - END IF + ! Check the dimensions used. The LoadComponents(Idx) flag will be set to .TRUE. if data was found in the file + DO IBody=1,SumQTFData%Data4D%NumBodies + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( p%SumQTFDims(ThisDim) .AND. ( .NOT. SumQTFData%Data4D%LoadComponents(Idx) ) ) & + CALL SetErrStat( ErrID_Warn, ' '//TRIM(SumQTFData%Filename)//' does not contain information for the '// & + TRIM(Num2LStr(ThisDim))//' force component for the SumQTF method. Setting this component to zero.', & + ErrStat,ErrMsg,RoutineName) + ENDDO ENDDO ELSE - CALL SetErrStat( ErrID_Fatal, ' Programming error. SumQTF flag is set, but no data has been read in.',ErrStat,ErrMsg, 'WAMIT2_Init') + CALL SetErrStat( ErrID_Fatal, ' Programming error. SumQTF flag is set, but no data has been read in.',ErrStat,ErrMsg, RoutineName) ENDIF IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp @@ -519,12 +540,12 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini !> If the MnDrift method will be used, call the subroutine to calculate the force time series IF ( p%MnDriftF ) THEN - + ! Tell our nice users what is about to happen that may take a while: CALL WrScr ( ' Calculating second order mean drift force.' ) CALL MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsgTmp, ErrStatTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init' ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp RETURN @@ -538,7 +559,7 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini CALL WrScr ( " Calculating second order difference-frequency force using the Newman's approximation." ) CALL NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsgTmp, ErrStatTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init' ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp RETURN @@ -554,7 +575,7 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini CALL WrScr ( ' Calculating second order difference-frequency force using the full quadratic transfer function.' ) CALL DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsgTmp, ErrStatTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init' ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp RETURN @@ -568,7 +589,7 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini CALL WrScr ( ' Calculating second order sum-frequency force using the full quadratic transfer function.' ) CALL SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsgTmp, ErrStatTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init' ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp RETURN @@ -585,29 +606,37 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini ! Difference method data. Only one difference method can be calculated at a time. - IF ( p%MnDriftF ) THEN - DO I=1,6 ! Loop through load components. Set ones that are calculated. - IF ( p%MnDriftDims(I) ) THEN - p%WaveExctn2(:,I) = MnDriftForce(I) - ENDIF + DO IBody=1,p%NBody ! Loop through load components. Set ones that are calculated. + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( p%MnDriftDims(ThisDim) ) THEN + p%WaveExctn2(:,Idx) = MnDriftForce(Idx) + ENDIF + ENDDO ENDDO ELSE IF ( p%NewmanAppF ) THEN - DO I=1,6 ! Loop through load components. Set ones that are calculated. - IF ( p%NewmanAppDims(I) ) THEN - p%WaveExctn2(:,I) = NewmanAppForce(:,I) - ENDIF + DO IBody=1,p%NBody ! Loop through load components. Set ones that are calculated. + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( p%NewmanAppDims(ThisDim) ) THEN + p%WaveExctn2(:,Idx) = NewmanAppForce(:,Idx) + ENDIF + ENDDO ENDDO ELSE IF ( p%DiffQTFF ) THEN - DO I=1,6 ! Loop through load components. Set ones that are calculated. - IF ( p%DiffQTFDims(I) ) THEN - p%WaveExctn2(:,I) = DiffQTFForce(:,I) - ENDIF + DO IBody=1,p%NBody ! Loop through load components. Set ones that are calculated. + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( p%DiffQTFDims(ThisDim) ) THEN + p%WaveExctn2(:,Idx) = DiffQTFForce(:,Idx) + ENDIF + ENDDO ENDDO ENDIF @@ -616,13 +645,13 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini ! Summation method IF ( p%SumQTFF ) THEN - DO I=1,6 ! Loop through load components. Set ones that are calculated. - IF ( p%SumQTFDims(I) ) THEN - ! Add the sum force to the difference force calculated above (if there was one). Loop through all timesteps. - DO J=1,InitInp%NStepWave - p%WaveExctn2(J,I) = p%WaveExctn2(J,I) + SumQTFForce(J,I) - ENDDO - ENDIF + DO IBody=1,p%NBody ! Loop through load components. Set ones that are calculated. + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( p%SumQTFDims(ThisDim) ) THEN + p%WaveExctn2(:,Idx) = p%WaveExctn2(:,Idx) + SumQTFForce(:,Idx) + ENDIF + ENDDO ENDDO ENDIF @@ -636,7 +665,6 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini - !---------------------------------------------------------------------- !> 5. Create the mesh used for exporting the 2nd order forces from the !! WAMIT2_CalcOuput routine at each timestep. Also set the outputs @@ -646,7 +674,7 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini ! Create the input and output meshes associated with lumped loads CALL MeshCreate( BlankMesh = u%Mesh , & IOS = COMPONENT_INPUT , & - Nnodes = 1 , & + Nnodes = p%NBody , & ErrStat = ErrStatTmp , & ErrMess = ErrMsgTmp , & TranslationDisp = .TRUE. , & @@ -656,22 +684,30 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini TranslationAcc = .FALSE. , & RotationAcc = .FALSE.) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init') + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp RETURN END IF - ! Create the node on the mesh - CALL MeshPositionNode (u%Mesh, 1, (/0.0_ReKi, 0.0_ReKi, 0.0_ReKi/), ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init') + DO IBody = 1,p%NBody - ! Create the mesh element - CALL MeshConstructElement ( u%Mesh, ELEMENT_POINT, ErrStatTmp, ErrMsgTmp, 1 ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init') + ! Set orientation and position for each body in mesh + theta = (/ 0.0_R8Ki, 0.0_R8Ki, InitInp%PtfmRefztRot(IBody)/) ! angle in radians + orientation = EulerConstruct(theta) + XYZloc = (/InitInp%PtfmRefxt(IBody), InitInp%PtfmRefyt(IBody), InitInp%PtfmRefzt(IBody)/) + + ! Create the node on the mesh + CALL MeshPositionNode (u%Mesh, IBody, XYZloc, ErrStatTmp, ErrMsgTmp, orientation ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) + + ! Create the mesh element + CALL MeshConstructElement ( u%Mesh, ELEMENT_POINT, ErrStatTmp, ErrMsgTmp, IBody ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) + ENDDO CALL MeshCommit ( u%Mesh, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init') + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp RETURN @@ -680,7 +716,7 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini CALL MeshCopy( SrcMesh=u%Mesh, DestMesh=y%Mesh, CtrlCode=MESH_SIBLING, IOS=COMPONENT_OUTPUT, & ErrStat=ErrStatTmp, ErrMess=ErrMsgTmp, Force=.TRUE., Moment=.TRUE. ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init') + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp RETURN @@ -691,17 +727,6 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini y%Mesh%RemapFlag = .TRUE. - - ! Initialize the outputs - CALL WMT2OUT_Init( InitInp, y, p, InitOut, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WAMIT2_Init') - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp - RETURN - END IF - - - !---------------------------------------------------------------------- !> 6. Set zero values for unused outputs. This is mostly so that the !! compiler does not complain. @@ -709,10 +734,12 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini x%DummyContState = 0.0_SiKi xd%DummyDiscState = 0.0_SiKi z%DummyConstrState = 0.0_SiKi + CALL AllocAry( m%LastIndWave, p%NBody, 'm%LastIndWave', ErrStatTmp, ErrMsgTmp) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) m%LastIndWave = 1_IntKi OtherState%DummyOtherState = 0 - + ! Cleanup remaining stuff CALL CleanUp @@ -739,7 +766,6 @@ END SUBROUTINE CleanUp - !------------------------------------------------------------------------------------------------------------------------------- !> This subroutine calculates the force time series using the MnDrift calculation. !! The data is stored in either 3D or 4D arrays depending on the file type used. @@ -764,11 +790,15 @@ END SUBROUTINE CleanUp !! !! where \f$ k \f$ indicates the index to the load component, \f$ {F_{{ex}~k}^{{-}(2)}} \f$ is the resulting time !! independent mean drift force, and \f$ a_m \f$ and \f$ a_m^* \f$ are the complex wave amplitude and its complex conjugate for - !! the \f$ m^{th} \f$ frequency. Note the lack of time dependence in this equation: the mean drift is the average drift + !! the \f$ m^{th} \f$ frequency. _Note the lack of time dependence in this equation:_ the mean drift is the average drift !! force over the entire simulation. Note also that \f$ F_k^{-} (\omega_m, \beta_m) \f$ is the dimensionalized real valued !! diagonal of the QTF read from the WAMIT file and interpolated for the \f$ m^{th} \f$ wave frequency. Note that this is !! is a numerical integral, so the \f$ \Delta\omega \f$ term is necessary. !! + !! @note The mean drift is a static value representing the mean drift force for the entire simulation. Therefore, any offset + !! in the body location can be ignored since it cancels out (it is in the complex part that is ignored in the summation). + !! The orientation of the platform is therefore handled after the summation. + !! !! Since the frequency range of the QTF has not yet been checked, we will do that now. !! !------------------------------------------------------------------------------------------------------------------------------- @@ -779,7 +809,7 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS TYPE(WAMIT2_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization routine TYPE(WAMIT2_ParameterType), INTENT(IN ) :: p !< Parameters TYPE(W2_DiffData_Type), INTENT(INOUT) :: MnDriftData !< Data storage for the MnDrift method. Set to INOUT in case we need to convert 4D to 3D - REAL(SiKi), INTENT( OUT) :: MnDriftForce(6) !< Force data. Index 1 is the force component. Constant for all time. + REAL(SiKi), ALLOCATABLE, INTENT( OUT) :: MnDriftForce(:) !< Force data. Index 1 is the force component. Constant for all time. CHARACTER(*), INTENT( OUT) :: ErrMsg INTEGER(IntKi), INTENT( OUT) :: ErrStat @@ -789,18 +819,24 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS REAL(SiKi) :: TmpReal1 !< Temporary real REAL(SiKi) :: TmpReal2 !< Temporary real LOGICAL :: TmpFlag !< Temporary logical flag - INTEGER(IntKi) :: I !< Generic counter + INTEGER(IntKi) :: ThisDim !< Generic counter for dimension + INTEGER(IntKi) :: IBody !< Index to which body we are on + INTEGER(IntKi) :: Idx !< Index to the full set of 6*NBody INTEGER(IntKi) :: J !< Generic counter INTEGER(IntKi) :: K !< Generic counter + CHARACTER(*), PARAMETER :: RoutineName = 'MnDrift_InitCalc' + ! Wave information and QTF temporary COMPLEX(SiKi) :: QTF_Value !< Temporary complex number for QTF COMPLEX(SiKi) :: aWaveElevC !< Wave elevation of current frequency component. NStepWave2 normalization is removed. - REAL(SiKi) :: Omega1 !< Wave frequency of this component + REAL(ReKi) :: Omega1 !< Wave frequency of this component ! Interpolation routine indices and value to search for, and smaller array to pass INTEGER(IntKi) :: LastIndex3(3) !< Last used index for searching in the interpolation algorithms INTEGER(IntKi) :: LastIndex4(4) !< Last used index for searching in the interpolation algorithms + REAL(SiKi) :: RotateZdegOffset !< Offset to wave heading (NBodyMod==2 only) + REAL(SiKi) :: RotateZMatrixT(2,2) !< The transpose of rotation in matrix form for rotation about z (from global to local) REAL(SiKi) :: Coord3(3) !< The (omega1,beta1,beta2) coordinate we want in the 3D dataset REAL(SiKi) :: Coord4(4) !< The (omega1,omega2,beta1,beta2) coordinate we want in the 4D dataset COMPLEX(SiKi),ALLOCATABLE :: TmpData3D(:,:,:) !< Temporary 3D array we put the 3D data into (minus the load component indice) @@ -812,15 +848,23 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS ErrMsgTmp = '' ErrStat = ErrID_None ErrStatTmp = ErrID_None + + ! Initialize resulting forces + ALLOCATE( MnDriftForce(6*p%NBody), STAT=ErrStatTmp ) + IF (ErrStatTmp /= 0) THEN + CALL SetErrStat(ErrID_Fatal,' Cannot allocate array for the resulting mean drift force '// & + 'of the 2nd order force.',ErrStat, ErrMsg, RoutineName) + RETURN + ENDIF MnDriftForce = 0.0_SiKi !> 1. Check the data to see if low cutoff on the difference frequency is 0. If it is above zero, that implies no mean drift - !! term since \f$ \omega_1=\omega_2 \f$ + !! term since \f$ \omega_1=\omega_2 \f$ IF ( InitInp%WvLowCOffD > 0.0_SiKi ) THEN CALL SetErrStat( ErrID_Warn, ' WvLowCOffD > 0.0, so no mean drift term is calculated (the mean drift uses only the equal '//& - 'frequency terms of the QTF). Setting the mean drift force to 0.',ErrStat,ErrMsg,'MnDrift_InitCalc') + 'frequency terms of the QTF). Setting the mean drift force to 0.',ErrStat,ErrMsg,RoutineName) MnDriftForce = 0.0_SiKi RETURN ENDIF @@ -837,7 +881,7 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS IF ( MINVAL( MnDriftData%Data3D%WvFreq1 ) > InitInp%WvLowCOffD ) THEN CALL SetErrStat( ErrID_Fatal,' The lowest frequency ( '//TRIM(Num2LStr(MINVAL(MnDriftData%Data3D%WvFreq1)))// & ' rad/s for first wave period) data in '//TRIM(MnDriftData%Filename)// & - ' is above the low frequency cutoff set by WvLowCOffD.',ErrStat,ErrMsg,'MnDrift_InitCalc') + ' is above the low frequency cutoff set by WvLowCOffD.',ErrStat,ErrMsg,RoutineName) ENDIF ! Check the high frequency cutoff -- using the Difference high frequency cutoff. The first order high frequency @@ -845,7 +889,7 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS IF ( (MAXVAL(MnDriftData%Data3D%WvFreq1 ) < InitInp%WvHiCOffD) ) THEN CALL SetErrStat( ErrID_Fatal,' The highest frequency ( '//TRIM(Num2LStr(MAXVAL(MnDriftData%Data3D%WvFreq1)))// & ' rad/s for first wave period) data in '//TRIM(MnDriftData%Filename)// & - ' is below the high frequency cutoff set by WvHiCOffD.',ErrStat,ErrMsg,'MnDrift_InitCalc') + ' is below the high frequency cutoff set by WvHiCOffD.',ErrStat,ErrMsg,RoutineName) ENDIF ELSE IF ( MnDriftData%DataIs4D ) THEN ! only check if not 3D data. If there is 3D data, we default to using it for calculations @@ -854,12 +898,12 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS IF ( MINVAL( MnDriftData%Data4D%WvFreq1 ) > InitInp%WvLowCOffD ) THEN CALL SetErrStat( ErrID_Fatal,' The lowest frequency ( '//TRIM(Num2LStr(MINVAL(MnDriftData%Data4D%WvFreq1)))// & ' rad/s first wave period) data in '//TRIM(MnDriftData%Filename)// & - ' is above the low frequency cutoff set by WvLowCOff.',ErrStat,ErrMsg,'MnDrift_InitCalc') + ' is above the low frequency cutoff set by WvLowCOff.',ErrStat,ErrMsg,RoutineName) ENDIF IF ( MINVAL( MnDriftData%Data4D%WvFreq2 ) > InitInp%WvLowCOff ) THEN CALL SetErrStat( ErrID_Fatal,' The lowest frequency ( '//TRIM(Num2LStr(MINVAL(MnDriftData%Data4D%WvFreq2)))// & ' rad/s for second wave period) data in '//TRIM(MnDriftData%Filename)// & - ' is above the low frequency cutoff set by WvLowCOffD.',ErrStat,ErrMsg,'MnDrift_InitCalc') + ' is above the low frequency cutoff set by WvLowCOffD.',ErrStat,ErrMsg,RoutineName) ENDIF ! Check the high frequency cutoff -- using the Difference high frequency cutoff. The first order high frequency @@ -867,17 +911,17 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS IF ( (MAXVAL(MnDriftData%Data4D%WvFreq1) < InitInp%WvHiCOffD) ) THEN CALL SetErrStat( ErrID_Fatal,' The highest frequency ( '//TRIM(Num2LStr(MAXVAL(MnDriftData%Data4D%WvFreq1)))// & ' rad/s for first wave period) data in '//TRIM(MnDriftData%Filename)// & - ' is below the high frequency cutoff set by WvHiCOffD.',ErrStat,ErrMsg,'MnDrift_InitCalc') + ' is below the high frequency cutoff set by WvHiCOffD.',ErrStat,ErrMsg,RoutineName) ENDIF IF ( (MAXVAL(MnDriftData%Data4D%WvFreq2) < InitInp%WvHiCOffD) ) THEN CALL SetErrStat( ErrID_Fatal,' The highest frequency ( '//TRIM(Num2LStr(MAXVAL(MnDriftData%Data4D%WvFreq1)))// & ' rad/s second wave period) data in '//TRIM(MnDriftData%Filename)// & - ' is below the high frequency cutoff set by WvHiCOffD.',ErrStat,ErrMsg,'MnDrift_InitCalc') + ' is below the high frequency cutoff set by WvHiCOffD.',ErrStat,ErrMsg,RoutineName) ENDIF ELSE ! This is a catastrophic issue. We should not have called this routine without data that is usable for the MnDrift calculation - CALL SetErrStat( ErrID_Fatal, ' Mean drift calculation called without data.',ErrStat,ErrMsg,'MnDrift_InitCalc') + CALL SetErrStat( ErrID_Fatal, ' Mean drift calculation called without data.',ErrStat,ErrMsg,RoutineName) ENDIF IF ( ErrStat >= AbortErrLev ) RETURN @@ -892,12 +936,12 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS CALL SetErrStat( ErrID_Fatal,' WAMIT output file '//TRIM(MnDriftData%Filename)//' only contains one wave '// & 'direction at '//TRIM(Num2LStr(MnDriftData%Data3D%WvDir1(1)))//' degrees (first wave direction). '// & 'It cannot be used with multidirectional waves. Set WvDirMod to 0 to use this file.', & - ErrStat,ErrMsg,'MnDrift_InitCalc') + ErrStat,ErrMsg,RoutineName) ELSE IF ( InitInp%WaveMultiDir .AND. (MnDriftData%Data3D%NumWvDir2 == 1) ) THEN CALL SetErrStat( ErrID_Fatal,' WAMIT output file '//TRIM(MnDriftData%Filename)//' only contains one wave '// & 'direction at '//TRIM(Num2LStr(MnDriftData%Data3D%WvDir2(1)))//' degrees (second wave direction). '// & 'It cannot be used with multidirectional waves. Set WvDirMod to 0 to use this file.', & - ErrStat,ErrMsg,'MnDrift_InitCalc') + ErrStat,ErrMsg,RoutineName) ELSE ! See Known Issues #1 at the top of this file. There may be problems if the data spans the +/- Pi boundary. For @@ -909,7 +953,7 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS (minval(MnDriftData%data3d%WvDir2) > 150.0_SiKi) .OR. (maxval(MnDriftData%data3d%WvDir2) < -150.0_SiKi) ) THEN CALL SetErrStat( ErrID_Warn,' There may be issues with how the wave direction data is handled when the wave '// & 'direction of interest is near the +/- 180 direction. This is a known issue with '// & - 'the WAMIT2 module that has not yet been addressed.',ErrStat,ErrMsg,'MnDrift_InitCalc') + 'the WAMIT2 module that has not yet been addressed.',ErrStat,ErrMsg,RoutineName) ENDIF ! Now check the limits for the first wave direction @@ -917,12 +961,12 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS IF ( InitInp%WaveDirMin < MINVAL(MnDriftData%Data3D%WvDir1) ) THEN CALL SetErrStat( ErrID_Fatal,' Minimum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMin))//' is not'//& 'found in the WAMIT data file '//TRIM(MnDriftData%Filename)//' for the first wave direction.', & - ErrStat, ErrMsg, 'MnDrift_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF - IF ( InitInp%WaveDirMax < MAXVAL(MnDriftData%Data3D%WvDir1) ) THEN + IF ( InitInp%WaveDirMax > MAXVAL(MnDriftData%Data3D%WvDir1) ) THEN CALL SetErrStat( ErrID_Fatal,' Maximum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMax))//' is not'//& 'found in the WAMIT data file '//TRIM(MnDriftData%Filename)//' for the first wave direction.', & - ErrStat, ErrMsg, 'MnDrift_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF @@ -931,12 +975,12 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS IF ( InitInp%WaveDirMin < MINVAL(MnDriftData%Data3D%WvDir2) ) THEN CALL SetErrStat( ErrID_Fatal,' Minimum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMin))//' is not'//& 'found in the WAMIT data file '//TRIM(MnDriftData%Filename)//' for the second wave direction.', & - ErrStat, ErrMsg, 'MnDrift_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF - IF ( InitInp%WaveDirMax < MAXVAL(MnDriftData%Data3D%WvDir2) ) THEN + IF ( InitInp%WaveDirMax > MAXVAL(MnDriftData%Data3D%WvDir2) ) THEN CALL SetErrStat( ErrID_Fatal,' Maximum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMax))//' is not'//& 'found in the WAMIT data file '//TRIM(MnDriftData%Filename)//' for the second wave direction.', & - ErrStat, ErrMsg, 'MnDrift_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF ENDIF @@ -948,12 +992,12 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS CALL SetErrStat( ErrID_Fatal,' WAMIT output file '//TRIM(MnDriftData%Filename)//' only contains one wave '// & 'direction at '//TRIM(Num2LStr(MnDriftData%Data4D%WvDir1(1)))//' degrees (first wave direction). '// & 'It cannot be used with multidirectional waves. Set WvDirMod to 0 to use this file.', & - ErrStat,ErrMsg,'MnDrift_InitCalc') + ErrStat,ErrMsg,RoutineName) ELSE IF ( InitInp%WaveMultiDir .AND. (MnDriftData%Data4D%NumWvDir2 == 1) ) THEN CALL SetErrStat( ErrID_Fatal,' WAMIT output file '//TRIM(MnDriftData%Filename)//' only contains one wave '// & 'direction at '//TRIM(Num2LStr(MnDriftData%Data4D%WvDir2(1)))//' degrees (second wave direction). '// & 'It cannot be used with multidirectional waves. Set WvDirMod to 0 to use this file.', & - ErrStat,ErrMsg,'MnDrift_InitCalc') + ErrStat,ErrMsg,RoutineName) ELSE ! See Known Issues #1 at the top of this file. There may be problems if the data spans the +/- Pi boundary. For @@ -965,7 +1009,7 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS (MINVAL(MnDriftData%Data4D%WvDir2) > 150.0_SiKi) .OR. (MAXVAL(MnDriftData%Data4D%WvDir2) < -150.0_SiKi) ) THEN CALL SetErrStat( ErrID_Warn,' There may be issues with how the wave direction data is handled when the wave '// & 'direction of interest is near the +/- 180 direction. This is a known issue with '// & - 'the WAMIT2 module that has not yet been addressed.',ErrStat,ErrMsg,'MnDrift_InitCalc') + 'the WAMIT2 module that has not yet been addressed.',ErrStat,ErrMsg,RoutineName) ENDIF ! Now check the limits for the first wave direction @@ -974,12 +1018,12 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS IF ( InitInp%WaveDirMin < MINVAL(MnDriftData%Data4D%WvDir1) ) THEN CALL SetErrStat( ErrID_Fatal,' Minimum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMin))//' is not'//& 'found in the WAMIT data file '//TRIM(MnDriftData%Filename)//' for the first wave direction.', & - ErrStat, ErrMsg, 'MnDrift_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF - IF ( InitInp%WaveDirMax < MAXVAL(MnDriftData%Data4D%WvDir1) ) THEN + IF ( InitInp%WaveDirMax > MAXVAL(MnDriftData%Data4D%WvDir1) ) THEN CALL SetErrStat( ErrID_Fatal,' Maximum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMax))//' is not'//& 'found in the WAMIT data file '//TRIM(MnDriftData%Filename)//' for the first wave direction.', & - ErrStat, ErrMsg, 'MnDrift_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF @@ -988,19 +1032,19 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS IF ( InitInp%WaveDirMin < MINVAL(MnDriftData%Data4D%WvDir2) ) THEN CALL SetErrStat( ErrID_Fatal,' Minimum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMin))//' is not'//& 'found in the WAMIT data file '//TRIM(MnDriftData%Filename)//' for the second wave direction.', & - ErrStat, ErrMsg, 'MnDrift_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF - IF ( InitInp%WaveDirMax < MAXVAL(MnDriftData%Data4D%WvDir2) ) THEN + IF ( InitInp%WaveDirMax > MAXVAL(MnDriftData%Data4D%WvDir2) ) THEN CALL SetErrStat( ErrID_Fatal,' Maximum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMax))//' is not'//& 'found in the WAMIT data file '//TRIM(MnDriftData%Filename)//' for the second wave direction.', & - ErrStat, ErrMsg, 'MnDrift_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF ENDIF ELSE ! No data. This is a catastrophic issue. We should not have called this routine without data that is usable for the MnDrift calculation - CALL SetErrStat( ErrID_Fatal, ' Mean drift calculation called without data.',ErrStat,ErrMsg,'MnDrift_InitCalc') + CALL SetErrStat( ErrID_Fatal, ' Mean drift calculation called without data.',ErrStat,ErrMsg,RoutineName) ENDIF IF ( ErrStat >= AbortErrLev ) RETURN @@ -1012,19 +1056,22 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS IF ( .NOT. MnDriftData%DataIs3D .AND. MnDriftData%Data4D%WvFreqDiagComplete ) THEN TmpFlag = .FALSE. ! if this goes true, then we need to convert to 3D data - DO I=1,6 - IF ( p%MnDriftDims(I) ) THEN ! Flag indicating which dimension we are calculating for - IF ( MnDriftData%Data4D%DataIsSparse(I) .AND. MnDriftData%Data4D%LoadComponents(I) ) TmpFlag = .TRUE. - ENDIF + DO IBody=1,MnDriftData%Data4D%NumBodies + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( p%MnDriftDims(IBody) ) THEN ! Flag indicating which dimension we are calculating for + IF ( MnDriftData%Data4D%DataIsSparse(Idx) .AND. MnDriftData%Data4D%LoadComponents(Idx) ) TmpFlag = .TRUE. + ENDIF + ENDDO ENDDO ! If we need to create the 3D data set, then CALL Copy_InitData4Dto3D( MnDriftData%Data4D, MnDriftData%Data3D, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,'MnDrift_InitCalc') + CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) IF (ErrStat >= AbortErrLev) RETURN MnDriftData%DataIs3D = .TRUE. ! Set flag to indicate we now have the 3D data. - + ENDIF @@ -1036,18 +1083,24 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS !! FIXME: remove this check and warning once the sparse matrix interpolation routines are implimented. TmpFlag = .FALSE. IF ( MnDriftData%DataIs3D ) THEN - DO I=1,6 - IF ( MnDriftData%Data3D%DataIsSparse(I) .AND. MnDriftData%Data3D%LoadComponents(I) .AND. p%MnDriftDims(I) ) TmpFlag = .TRUE. + DO IBody=1,MnDriftData%Data3D%NumBodies + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( MnDriftData%Data3D%DataIsSparse(Idx) .AND. MnDriftData%Data3D%LoadComponents(Idx) .AND. p%MnDriftDims(ThisDim) ) TmpFlag = .TRUE. + ENDDO ENDDO ELSE ! must be 4D -- we checked that we had something at the start of this routine. - DO I=1,6 - IF ( MnDriftData%Data4D%DataIsSparse(I) .AND. MnDriftData%Data4D%LoadComponents(I) .AND. p%MnDriftDims(I) ) TmpFlag = .TRUE. + DO IBody=1,MnDriftData%Data4D%NumBodies + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( MnDriftData%Data4D%DataIsSparse(Idx) .AND. MnDriftData%Data4D%LoadComponents(Idx) .AND. p%MnDriftDims(ThisDim) ) TmpFlag = .TRUE. + ENDDO ENDDO ENDIF IF (TmpFlag) THEN CALL SetErrStat(ErrID_Fatal,' The second order WAMIT data in '//TRIM(MnDriftData%Filename)//' is too sparse '// & 'for the interpolation routine used in the mean drift calculation. At some later point, we will allow for '// & - 'sparse data when a different interpolation routine is implimented.',ErrStat,ErrMsg,'MnDrift_InitCalc') + 'sparse data when a different interpolation routine is implimented.',ErrStat,ErrMsg,RoutineName) RETURN ENDIF @@ -1063,11 +1116,11 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS IF (MnDriftData%DataIs3D) THEN ALLOCATE( TmpData3D(MnDriftData%Data3D%NumWvFreq1, MnDriftData%Data3D%NumWvDir1,MnDriftData%Data3D%NumWvDir2),STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate temporary array for interpolation of 3D QTF data.', & - ErrStat, ErrMsg, 'MnDrift_InitCalc') + ErrStat, ErrMsg, RoutineName) ELSE ALLOCATE( TmpData4D(MnDriftData%Data4D%NumWvFreq1,MnDriftData%Data4D%NumWvFreq2,MnDriftData%Data4D%NumWvDir1,MnDriftData%Data4D%NumWvDir2),STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate temporary array for interpolation of 4D QTF data.', & - ErrStat, ErrMsg, 'MnDrift_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF ! If something went wrong during allocation of the temporary arrays... @@ -1079,94 +1132,134 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS ! Now loop through all the dimensions and perform the calculation - DO I=1,6 + DO IBody=1,p%NBody + + ! Heading correction, only applies to NBodyMod == 2 + if (p%NBodyMod==2) then + RotateZdegOffset = InitInp%PtfmRefztRot(IBody)*R2D + else + RotateZdegOffset = 0.0_SiKi + endif + + ! NOTE: RotateZMatrixT is the rotation from local to global. + RotateZMatrixT(:,1) = (/ cos(InitInp%PtfmRefztRot(IBody)), -sin(InitInp%PtfmRefztRot(IBody)) /) + RotateZMatrixT(:,2) = (/ sin(InitInp%PtfmRefztRot(IBody)), cos(InitInp%PtfmRefztRot(IBody)) /) + - ! Set the MnDrift force to 0.0 (Even ones we don't calculate) - MnDriftForce(I) = 0.0_SiKi + DO ThisDim=1,6 - ! Only on the dimensions we requested - IF ( p%MnDriftDims(I) ) THEN + Idx = (IBody-1)*6 + ThisDim - ! Set an initial search index for the 3D and 4D array interpolation - LastIndex3 = (/0,0,0/) - LastIndex4 = (/0,0,0,0/) + ! Set the MnDrift force to 0.0 (Even ones we don't calculate) + MnDriftForce(Idx) = 0.0_SiKi - ! To make things run slightly quicker, copy the data we will be interpolating over into the temporary arrays IF (MnDriftData%DataIs3D) THEN - TmpData3D = MnDriftData%Data3D%DataSet(:,:,:,I) + TmpFlag = MnDriftData%Data3D%LoadComponents(Idx) ELSE - TmpData4D = MnDriftData%Data4D%DataSet(:,:,:,:,I) + TmpFlag = MnDriftData%Data4D%LoadComponents(Idx) END IF - - DO J=1,InitInp%NStepWave2 + ! Only on the dimensions we requested, and if it is present in the data + IF ( p%MnDriftDims(ThisDim) .AND. TmpFlag ) THEN - ! First get the wave amplitude -- must be reconstructed from the WaveElevC0 array. First index is the real (1) or - ! imaginary (2) part. Divide by NStepWave2 to remove the built in normalization in WaveElevC0. - aWaveElevC = CMPLX( InitInp%WaveElevC0(1,J), InitInp%WaveElevC0(2,J)) / InitInp%NStepWave2 + ! Set an initial search index for the 3D and 4D array interpolation + LastIndex3 = (/0,0,0/) + LastIndex4 = (/0,0,0,0/) - ! Calculate the frequency - Omega1 = J * InitInp%WaveDOmega + ! To make things run slightly quicker, copy the data we will be interpolating over into the temporary arrays + IF (MnDriftData%DataIs3D) THEN + TmpData3D = MnDriftData%Data3D%DataSet(:,:,:,Idx) + ELSE + TmpData4D = MnDriftData%Data4D%DataSet(:,:,:,:,Idx) + END IF - ! Only get a QTF value if within the range of frequencies we have wave amplitudes for (first order cutoffs). This - ! is done only for efficiency. - IF ( (Omega1 >= InitInp%WvLowCOff) .AND. (Omega1 <= InitInp%WvHiCOff) ) THEN + DO J=1,InitInp%NStepWave2 - ! Now get the QTF value that corresponds to this frequency and wavedirection pair. - IF ( MnDriftData%DataIs3D ) THEN + ! NOTE: since the Mean Drift only returns a static time independent average value for the drift force, we do not + ! need to account for any offset in the location of the WAMIT body (this term vanishes). + ! First get the wave amplitude -- must be reconstructed from the WaveElevC0 array. First index is the real (1) or + ! imaginary (2) part. Divide by NStepWave2 to remove the built in normalization in WaveElevC0. + aWaveElevC = CMPLX( InitInp%WaveElevC0(1,J), InitInp%WaveElevC0(2,J), SiKi) / InitInp%NStepWave2 - ! Set the (omega1,beta1,beta2) point we are looking for. - Coord3 = (/ Omega1, InitInp%WaveDirArr(J), InitInp%WaveDirArr(J) /) + ! Calculate the frequency + Omega1 = J * InitInp%WaveDOmega - ! get the interpolated value for F(omega1,beta1,beta2) - CALL WAMIT_Interp3D_Cplx( Coord3, TmpData3D, MnDriftData%Data3D%WvFreq1, & - MnDriftData%Data3D%WvDir1, MnDriftData%Data3D%WvDir2, LastIndex3, QTF_Value, ErrStatTmp, ErrMsgTmp ) - ELSE + ! Only get a QTF value if within the range of frequencies we have wave amplitudes for (first order cutoffs). This + ! is done only for efficiency. + IF ( (Omega1 >= InitInp%WvLowCOff) .AND. (Omega1 <= InitInp%WvHiCOff) ) THEN - ! Set the (omega1,omega2,beta1,beta2) point we are looking for. - Coord4 = (/ Omega1, Omega1, InitInp%WaveDirArr(J), InitInp%WaveDirArr(J) /) + ! Now get the QTF value that corresponds to this frequency and wavedirection pair. + IF ( MnDriftData%DataIs3D ) THEN - ! get the interpolated value for F(omega1,omega2,beta1,beta2) - CALL WAMIT_Interp4D_Cplx( Coord4, TmpData4D, MnDriftData%Data4D%WvFreq1, MnDriftData%Data4D%WvFreq2, & - MnDriftData%Data4D%WvDir1, MnDriftData%Data4D%WvDir2, LastIndex4, QTF_Value, ErrStatTmp, ErrMsgTmp ) + ! Set the (omega1,beta1,beta2) point we are looking for. (angles in degrees here) + Coord3 = (/ REAL(Omega1,SiKi), InitInp%WaveDirArr(J), InitInp%WaveDirArr(J) /) + ! Apply local Z rotation to heading angle (degrees) to put wave direction into the local (rotated) body frame + Coord3(2) = Coord3(2) - RotateZdegOffset + Coord3(3) = Coord3(3) - RotateZdegOffset - ENDIF !QTF value find + ! get the interpolated value for F(omega1,beta1,beta2) + CALL WAMIT_Interp3D_Cplx( Coord3, TmpData3D, MnDriftData%Data3D%WvFreq1, & + MnDriftData%Data3D%WvDir1, MnDriftData%Data3D%WvDir2, LastIndex3, QTF_Value, ErrStatTmp, ErrMsgTmp ) + ELSE - ELSE ! outside the frequency range + ! Set the (omega1,omega2,beta1,beta2) point we are looking for. (angles in degrees here) + Coord4 = (/ REAL(Omega1,SiKi), REAL(Omega1,SiKi), InitInp%WaveDirArr(J), InitInp%WaveDirArr(J) /) - QTF_Value = CMPLX(0.0_SiKi,0.0_SiKi) + ! Apply local Z rotation to heading angle (degrees) to put wave direction into the local (rotated) body frame + Coord4(3) = Coord4(3) - RotateZdegOffset + Coord4(4) = Coord4(4) - RotateZdegOffset - ENDIF ! frequency check + ! get the interpolated value for F(omega1,omega2,beta1,beta2) + CALL WAMIT_Interp4D_Cplx( Coord4, TmpData4D, MnDriftData%Data4D%WvFreq1, MnDriftData%Data4D%WvFreq2, & + MnDriftData%Data4D%WvDir1, MnDriftData%Data4D%WvDir2, LastIndex4, QTF_Value, ErrStatTmp, ErrMsgTmp ) - ! Check and make sure nothing bombed in the interpolation that we need to be aware of - CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,'MnDrift_InitCalc') - IF ( ErrStat >= AbortErrLev ) THEN - IF (ALLOCATED(TmpData3D)) DEALLOCATE(TmpData3D,STAT=ErrStatTmp) - IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) - RETURN - ENDIF + ENDIF !QTF value find - ! Now we have the value of the QTF. These values should only be real for the omega1=omega2 case of the mean drift. - ! However if the value came from the 4D interpolation routine, it might have some residual complex part to it. So - ! we throw the complex part out. - QTF_Value = CMPLX(REAL(QTF_Value),0.0_SiKi) + ELSE ! outside the frequency range + QTF_Value = CMPLX(0.0,0.0,SiKi) - ! Now put it all together... note the frequency stepsize is multiplied after the summation - MnDriftForce(I) = MnDriftForce(I) + REAL(QTF_Value * aWaveElevC * CONJG(aWaveElevC)) !bjj: put QTF_Value first so that if it's zero, the rest gets set to zero (to hopefully avoid overflow issues) + ENDIF ! frequency check - ENDDO + ! Check and make sure nothing bombed in the interpolation that we need to be aware of + CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + IF (ALLOCATED(TmpData3D)) DEALLOCATE(TmpData3D,STAT=ErrStatTmp) + IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) + RETURN + ENDIF - ENDIF ! Load component to calculate - ENDDO + ! Now we have the value of the QTF. These values should only be real for the omega1=omega2 case of the mean drift. + ! However if the value came from the 4D interpolation routine, it might have some residual complex part to it. So + ! we throw the complex part out. + QTF_Value = CMPLX(REAL(QTF_Value,SiKi),0.0,SiKi) + + ! NOTE: any offset in platform location vanishes when the only the REAL part is kept (the offset resides in the + ! phase shift, which is in the imaginary part) + ! Now put it all together... note the frequency stepsize is multiplied after the summation + MnDriftForce(Idx) = MnDriftForce(Idx) + REAL(QTF_Value * aWaveElevC * CONJG(aWaveElevC)) !bjj: put QTF_Value first so that if it's zero, the rest gets set to zero (to hopefully avoid overflow issues) + + ENDDO ! NStepWave2 + + ENDIF ! Load component to calculate + + + ENDDO ! ThisDim -- Load Component on body + + + ! Now rotate the force components with platform orientation + MnDriftForce(1:2) = MATMUL( RotateZMatrixT, MnDriftForce(1:2) ) ! Fx and Fy, rotation about z + MnDriftForce(4:5) = MATMUL( RotateZMatrixT, MnDriftForce(4:5) ) ! Mx and My, rotation about z + + ENDDO ! IBody @@ -1246,26 +1339,33 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg REAL(SiKi) :: TmpReal1 !< Temporary real REAL(SiKi) :: TmpReal2 !< Temporary real LOGICAL :: TmpFlag !< Temporary logical flag - INTEGER(IntKi) :: I !< Generic counter + INTEGER(IntKi) :: ThisDim !< Generic counter for dimension + INTEGER(IntKi) :: IBody !< Index to which body we are on + INTEGER(IntKi) :: Idx !< Index to the full set of 6*NBody INTEGER(IntKi) :: J !< Generic counter INTEGER(IntKi) :: K !< Generic counter TYPE(FFT_DataType) :: FFT_Data !< Temporary array for the FFT module we're using + CHARACTER(*), PARAMETER :: RoutineName = 'NewmanApp_InitCalc' ! Wave information and QTF temporary COMPLEX(SiKi) :: QTF_Value !< Temporary complex number for QTF - COMPLEX(SiKi), ALLOCATABLE :: NewmanTerm1C(:) !< First term in the newman calculation, complex frequency space. Current load dimension. - COMPLEX(SiKi), ALLOCATABLE :: NewmanTerm2C(:) !< Second term in the newman calculation, complex frequency space. Current load dimension. + COMPLEX(SiKi), ALLOCATABLE :: NewmanTerm1C(:,:) !< First term in the newman calculation, complex frequency space. All dimensions, this body. + COMPLEX(SiKi), ALLOCATABLE :: NewmanTerm2C(:,:) !< Second term in the newman calculation, complex frequency space. All dimensions, this body. COMPLEX(SiKi), ALLOCATABLE :: NewmanTerm1t(:) !< First term in the newman calculation, time domain. Current load dimension. COMPLEX(SiKi), ALLOCATABLE :: NewmanTerm2t(:) !< Second term in the newman calculation, time domain. Current load dimension. COMPLEX(SiKi) :: aWaveElevC !< Wave elevation of current frequency component. NStepWave2 factor removed. - REAL(SiKi) :: Omega1 !< Wave frequency of this component + REAL(ReKi) :: Omega1 !< Wave frequency of this component ! Interpolation routine indices and value to search for, and smaller array to pass INTEGER(IntKi) :: LastIndex3(3) !< Last used index for searching in the interpolation algorithms INTEGER(IntKi) :: LastIndex4(4) !< Last used index for searching in the interpolation algorithms REAL(SiKi) :: Coord3(3) !< The (omega1,beta1,beta2) coordinate we want in the 3D dataset REAL(SiKi) :: Coord4(4) !< The (omega1,omega2,beta1,beta2) coordinate we want in the 4D dataset + REAL(SiKi) :: RotateZdegOffset !< Offset to wave heading (NBodyMod==2 only) + REAL(SiKi) :: RotateZMatrixT(2,2) !< The transpose of rotation in matrix form for rotation about z (from global to local) + COMPLEX(SiKi) :: PhaseShiftXY !< The phase shift offset to apply to the body + REAL(SiKi) :: WaveNmbr1 !< Wavenumber for this frequency COMPLEX(SiKi), ALLOCATABLE :: TmpData3D(:,:,:) !< Temporary 3D array we put the 3D data into (minus the load component indice) COMPLEX(SiKi), ALLOCATABLE :: TmpData4D(:,:,:,:) !< Temporary 4D array we put the 4D data into (minus the load component indice) @@ -1289,7 +1389,7 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg CALL SetErrStat( ErrID_Fatal,' The lowest frequency ( '//TRIM(Num2LStr(MINVAL(NewmanAppData%Data3D%WvFreq1)))// & ' rad/s for first wave period) data in '//TRIM(NewmanAppData%Filename)// & ' is above the low frequency cutoff set by WvLowCOff.', & - ErrStat,ErrMsg,'NewmanApp_InitCalc') + ErrStat,ErrMsg,RoutineName) ENDIF ! Check the high frequency cutoff -- using the Difference high frequency cutoff. The first order high frequency @@ -1298,7 +1398,7 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg CALL SetErrStat( ErrID_Fatal,' The highest frequency ( '//TRIM(Num2LStr(MAXVAL(NewmanAppData%Data3D%WvFreq1)))// & ' rad/s for first wave period) data in '//TRIM(NewmanAppData%Filename)// & ' is below the high frequency cutoff set by WvHiCOff.', & - ErrStat,ErrMsg,'NewmanApp_InitCalc') + ErrStat,ErrMsg,RoutineName) ENDIF ELSE IF ( NewmanAppData%DataIs4D ) THEN ! only check if not 3D data. If there is 3D data, we default to using it for calculations @@ -1308,13 +1408,13 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg CALL SetErrStat( ErrID_Fatal,' The lowest frequency ( '//TRIM(Num2LStr(MINVAL(NewmanAppData%Data4D%WvFreq1)))// & ' rad/s first wave period) data in '//TRIM(NewmanAppData%Filename)// & ' is above the low frequency cutoff set by WvLowCOff.', & - ErrStat,ErrMsg,'NewmanApp_InitCalc') + ErrStat,ErrMsg,RoutineName) ENDIF IF ( MINVAL( NewmanAppData%Data4D%WvFreq2 ) > InitInp%WvLowCOff ) THEN CALL SetErrStat( ErrID_Fatal,' The lowest frequency ( '//TRIM(Num2LStr(MINVAL(NewmanAppData%Data4D%WvFreq2)))// & ' rad/s for second wave period) data in '//TRIM(NewmanAppData%Filename)// & ' is above the low frequency cutoff set by WvLowCOff.', & - ErrStat,ErrMsg,'NewmanApp_InitCalc') + ErrStat,ErrMsg,RoutineName) ENDIF ! Check the high frequency cutoff -- using the Difference high frequency cutoff. The first order high frequency @@ -1323,18 +1423,18 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg CALL SetErrStat( ErrID_Fatal,' The highest frequency ( '//TRIM(Num2LStr(MAXVAL(NewmanAppData%Data4D%WvFreq1)))// & ' rad/s for first wave period) data in '//TRIM(NewmanAppData%Filename)// & ' is below the high frequency cutoff set by WvHiCOff.', & - ErrStat,ErrMsg,'NewmanApp_InitCalc') + ErrStat,ErrMsg,RoutineName) ENDIF IF ( MAXVAL(NewmanAppData%Data4D%WvFreq2) < InitInp%WvHiCOff ) THEN CALL SetErrStat( ErrID_Fatal,' The highest frequency ( '//TRIM(Num2LStr(MAXVAL(NewmanAppData%Data4D%WvFreq1)))// & ' rad/s second wave period) data in '//TRIM(NewmanAppData%Filename)// & ' is below the high frequency cutoff set by WvHiCOff.', & - ErrStat,ErrMsg,'NewmanApp_InitCalc') + ErrStat,ErrMsg,RoutineName) ENDIF ELSE ! This is a catastrophic issue. We should not have called this routine without data that is usable for the NewmanApp calculation - CALL SetErrStat( ErrID_Fatal, ' Newman approximation calculation called without data.',ErrStat,ErrMsg,'NewmanApp_InitCalc') + CALL SetErrStat( ErrID_Fatal, ' Newman approximation calculation called without data.',ErrStat,ErrMsg,RoutineName) ENDIF IF ( ErrStat >= AbortErrLev ) RETURN @@ -1349,12 +1449,12 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg CALL SetErrStat( ErrID_Fatal,' WAMIT output file '//TRIM(NewmanAppData%Filename)//' only contains one wave '// & 'direction at '//TRIM(Num2LStr(NewmanAppData%Data3D%WvDir1(1)))//' degrees (first wave direction). '// & 'It cannot be used with multidirectional waves. Set WvDirMod to 0 to use this file.', & - ErrStat,ErrMsg,'NewmanApp_InitCalc') + ErrStat,ErrMsg,RoutineName) ELSE IF ( InitInp%WaveMultiDir .AND. (NewmanAppData%Data3D%NumWvDir2 == 1) ) THEN CALL SetErrStat( ErrID_Fatal,' WAMIT output file '//TRIM(NewmanAppData%Filename)//' only contains one wave '// & 'direction at '//TRIM(Num2LStr(NewmanAppData%Data3D%WvDir2(1)))//' degrees (second wave direction). '// & 'It cannot be used with multidirectional waves. Set WvDirMod to 0 to use this file.', & - ErrStat,ErrMsg,'NewmanApp_InitCalc') + ErrStat,ErrMsg,RoutineName) ELSE ! See Known Issues #1 at the top of this file. There may be problems if the data spans the +/- Pi boundary. For @@ -1366,7 +1466,7 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg (minval(NewmanAppData%data3d%WvDir2) > 150.0_SiKi) .OR. (maxval(NewmanAppData%data3d%WvDir2) < -150.0_SiKi) ) THEN CALL SetErrStat( ErrID_Warn,' There may be issues with how the wave direction data is handled when the wave '// & 'direction of interest is near the +/- 180 direction. This is a known issue with '// & - 'the WAMIT2 module that has not yet been addressed.',ErrStat,ErrMsg,'NewmanApp_InitCalc') + 'the WAMIT2 module that has not yet been addressed.',ErrStat,ErrMsg,RoutineName) ENDIF ! Now check the limits for the first wave direction @@ -1374,12 +1474,12 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg IF ( InitInp%WaveDirMin < MINVAL(NewmanAppData%Data3D%WvDir1) ) THEN CALL SetErrStat( ErrID_Fatal,' Minimum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMin))//' is not'//& 'found in the WAMIT data file '//TRIM(NewmanAppData%Filename)//' for the first wave direction.', & - ErrStat, ErrMsg, 'NewmanApp_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF - IF ( InitInp%WaveDirMax < MAXVAL(NewmanAppData%Data3D%WvDir1) ) THEN + IF ( InitInp%WaveDirMax > MAXVAL(NewmanAppData%Data3D%WvDir1) ) THEN CALL SetErrStat( ErrID_Fatal,' Maximum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMax))//' is not'//& 'found in the WAMIT data file '//TRIM(NewmanAppData%Filename)//' for the first wave direction.', & - ErrStat, ErrMsg, 'NewmanApp_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF @@ -1388,12 +1488,12 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg IF ( InitInp%WaveDirMin < MINVAL(NewmanAppData%Data3D%WvDir2) ) THEN CALL SetErrStat( ErrID_Fatal,' Minimum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMin))//' is not'//& 'found in the WAMIT data file '//TRIM(NewmanAppData%Filename)//' for the second wave direction.', & - ErrStat, ErrMsg, 'NewmanApp_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF - IF ( InitInp%WaveDirMax < MAXVAL(NewmanAppData%Data3D%WvDir2) ) THEN + IF ( InitInp%WaveDirMax > MAXVAL(NewmanAppData%Data3D%WvDir2) ) THEN CALL SetErrStat( ErrID_Fatal,' Maximum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMax))//' is not'//& 'found in the WAMIT data file '//TRIM(NewmanAppData%Filename)//' for the second wave direction.', & - ErrStat, ErrMsg, 'NewmanApp_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF ENDIF @@ -1405,12 +1505,12 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg CALL SetErrStat( ErrID_Fatal,' WAMIT output file '//TRIM(NewmanAppData%Filename)//' only contains one wave '// & 'direction at '//TRIM(Num2LStr(NewmanAppData%Data4D%WvDir1(1)))//' degrees (first wave direction). '// & 'It cannot be used with multidirectional waves. Set WvDirMod to 0 to use this file.', & - ErrStat,ErrMsg,'NewmanApp_InitCalc') + ErrStat,ErrMsg,RoutineName) ELSE IF ( InitInp%WaveMultiDir .AND. (NewmanAppData%Data4D%NumWvDir2 == 1) ) THEN CALL SetErrStat( ErrID_Fatal,' WAMIT output file '//TRIM(NewmanAppData%Filename)//' only contains one wave '// & 'direction at '//TRIM(Num2LStr(NewmanAppData%Data4D%WvDir2(1)))//' degrees (second wave direction). '// & 'It cannot be used with multidirectional waves. Set WvDirMod to 0 to use this file.', & - ErrStat,ErrMsg,'NewmanApp_InitCalc') + ErrStat,ErrMsg,RoutineName) ELSE ! See Known Issues #1 at the top of this file. There may be problems if the data spans the +/- Pi boundary. For @@ -1422,7 +1522,7 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg (MINVAL(NewmanAppData%Data4D%WvDir2) > 150.0_SiKi) .OR. (MAXVAL(NewmanAppData%Data4D%WvDir2) < -150.0_SiKi) ) THEN CALL SetErrStat( ErrID_Warn,' There may be issues with how the wave direction data is handled when the wave '// & 'direction of interest is near the +/- 180 direction. This is a known issue with '// & - 'the WAMIT2 module that has not yet been addressed.',ErrStat,ErrMsg,'NewmanApp_InitCalc') + 'the WAMIT2 module that has not yet been addressed.',ErrStat,ErrMsg,RoutineName) ENDIF ! Now check the limits for the first wave direction @@ -1431,12 +1531,12 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg IF ( InitInp%WaveDirMin < MINVAL(NewmanAppData%Data4D%WvDir1) ) THEN CALL SetErrStat( ErrID_Fatal,' Minimum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMin))//' is not'//& 'found in the WAMIT data file '//TRIM(NewmanAppData%Filename)//' for the first wave direction.', & - ErrStat, ErrMsg, 'NewmanApp_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF - IF ( InitInp%WaveDirMax < MAXVAL(NewmanAppData%Data4D%WvDir1) ) THEN + IF ( InitInp%WaveDirMax > MAXVAL(NewmanAppData%Data4D%WvDir1) ) THEN CALL SetErrStat( ErrID_Fatal,' Maximum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMax))//' is not'//& 'found in the WAMIT data file '//TRIM(NewmanAppData%Filename)//' for the first wave direction.', & - ErrStat, ErrMsg, 'NewmanApp_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF @@ -1445,19 +1545,19 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg IF ( InitInp%WaveDirMin < MINVAL(NewmanAppData%Data4D%WvDir2) ) THEN CALL SetErrStat( ErrID_Fatal,' Minimum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMin))//' is not'//& 'found in the WAMIT data file '//TRIM(NewmanAppData%Filename)//' for the second wave direction.', & - ErrStat, ErrMsg, 'NewmanApp_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF - IF ( InitInp%WaveDirMax < MAXVAL(NewmanAppData%Data4D%WvDir2) ) THEN + IF ( InitInp%WaveDirMax > MAXVAL(NewmanAppData%Data4D%WvDir2) ) THEN CALL SetErrStat( ErrID_Fatal,' Maximum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMax))//' is not'//& 'found in the WAMIT data file '//TRIM(NewmanAppData%Filename)//' for the second wave direction.', & - ErrStat, ErrMsg, 'NewmanApp_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF ENDIF ELSE ! No data. This is a catastrophic issue. We should not have called this routine without data that is usable for the NewmanApp calculation - CALL SetErrStat( ErrID_Fatal, ' Newman approximation calculation called without data.',ErrStat,ErrMsg,'NewmanApp_InitCalc') + CALL SetErrStat( ErrID_Fatal, ' Newman approximation calculation called without data.',ErrStat,ErrMsg,RoutineName) ENDIF IF ( ErrStat >= AbortErrLev ) RETURN @@ -1469,19 +1569,22 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg IF ( .NOT. NewmanAppData%DataIs3D .AND. NewmanAppData%Data4D%WvFreqDiagComplete ) THEN TmpFlag = .FALSE. ! if this goes true, then we need to convert to 3D data - DO I=1,6 - IF ( p%NewmanAppDims(I) ) THEN ! Flag indicating which dimension we are calculating for - IF ( NewmanAppData%Data4D%DataIsSparse(I) .AND. NewmanAppData%Data4D%LoadComponents(I) ) TmpFlag = .TRUE. - ENDIF + DO IBody=1,NewmanAppData%Data4D%NumBodies + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( p%NewmanAppDims(ThisDim) ) THEN ! Flag indicating which dimension we are calculating for + IF ( NewmanAppData%Data4D%DataIsSparse(Idx) .AND. NewmanAppData%Data4D%LoadComponents(Idx) ) TmpFlag = .TRUE. + ENDIF + ENDDO ENDDO ! If we need to create the 3D data set, then CALL Copy_InitData4Dto3D( NewmanAppData%Data4D, NewmanAppData%Data3D, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,'NewmanApp_InitCalc') + CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) IF (ErrStat >= AbortErrLev) RETURN NewmanAppData%DataIs3D = .TRUE. ! Set flag to indicate we now have the 3D data. - + ENDIF @@ -1493,18 +1596,24 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg !! FIXME: remove this check and warning once the sparse matrix interpolation routines are implimented. TmpFlag = .FALSE. IF ( NewmanAppData%DataIs3D ) THEN - DO I=1,6 - IF ( NewmanAppData%Data3D%DataIsSparse(I) .AND. NewmanAppData%Data3D%LoadComponents(I) .AND. p%NewmanAppDims(I) ) TmpFlag = .TRUE. + DO IBody=1,NewmanAppData%Data3D%NumBodies + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( NewmanAppData%Data3D%DataIsSparse(Idx) .AND. NewmanAppData%Data3D%LoadComponents(Idx) .AND. p%NewmanAppDims(ThisDim) ) TmpFlag = .TRUE. + ENDDO ENDDO ELSE ! must be 4D -- we checked that we had something at the start of this routine. - DO I=1,6 - IF ( NewmanAppData%Data4D%DataIsSparse(I) .AND. NewmanAppData%Data4D%LoadComponents(I) .AND. p%NewmanAppDims(I) ) TmpFlag = .TRUE. + DO IBody=1,NewmanAppData%Data4D%NumBodies + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( NewmanAppData%Data4D%DataIsSparse(Idx) .AND. NewmanAppData%Data4D%LoadComponents(Idx) .AND. p%NewmanAppDims(ThisDim) ) TmpFlag = .TRUE. + ENDDO ENDDO ENDIF IF (TmpFlag) THEN CALL SetErrStat(ErrID_Fatal,' The second order WAMIT data in '//TRIM(NewmanAppData%Filename)//' is too sparse '// & 'for the interpolation routine used in the Newman approximation calculation. At some later point, we will allow for '// & - 'sparse data when a different interpolation routine is implimented.',ErrStat,ErrMsg,'NewmanApp_InitCalc') + 'sparse data when a different interpolation routine is implimented.',ErrStat,ErrMsg,RoutineName) RETURN ENDIF @@ -1525,30 +1634,30 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg IF (NewmanAppData%DataIs3D) THEN ALLOCATE( TmpData3D(NewmanAppData%Data3D%NumWvFreq1, NewmanAppData%Data3D%NumWvDir1,NewmanAppData%Data3D%NumWvDir2),STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate temporary array for interpolation of 3D QTF data.', & - ErrStat, ErrMsg, 'NewmanApp_InitCalc') + ErrStat, ErrMsg, RoutineName) ELSE ALLOCATE( TmpData4D(NewmanAppData%Data4D%NumWvFreq1,NewmanAppData%Data4D%NumWvFreq1,NewmanAppData%Data4D%NumWvDir1,NewmanAppData%Data4D%NumWvDir2),STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate temporary array for interpolation of 4D QTF data.', & - ErrStat, ErrMsg, 'NewmanApp_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF ! Setup the arrays holding the Newman terms, both the complex frequency domain and real time domain pieces ALLOCATE( NewmanTerm1t( 0:InitInp%NStepWave ), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate array for calculating the first term of the Newmans '// & - 'approximation in the time domain.',ErrStat, ErrMsg, 'NewmanApp_InitCalc') + 'approximation in the time domain.',ErrStat, ErrMsg, RoutineName) ALLOCATE( NewmanTerm2t( 0:InitInp%NStepWave ), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate array for calculating the second term of the Newmans '// & - 'approximation in the time domain.',ErrStat, ErrMsg, 'NewmanApp_InitCalc') - ALLOCATE( NewmanTerm1C( 0:InitInp%NStepWave2 ), STAT=ErrStatTmp ) + 'approximation in the time domain.',ErrStat, ErrMsg, RoutineName) + ALLOCATE( NewmanTerm1C( 0:InitInp%NStepWave2, 6 ), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate array for calculating the first term of the Newmans '// & - 'approximation in the frequency domain.',ErrStat, ErrMsg, 'NewmanApp_InitCalc') - ALLOCATE( NewmanTerm2C( 0:InitInp%NStepWave2 ), STAT=ErrStatTmp ) + 'approximation in the frequency domain.',ErrStat, ErrMsg, RoutineName) + ALLOCATE( NewmanTerm2C( 0:InitInp%NStepWave2, 6 ), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate array for calculating the second term of the Newmans '// & - 'approximation in the frequency domain.',ErrStat, ErrMsg, 'NewmanApp_InitCalc') - ALLOCATE( NewmanAppForce( 0:InitInp%NStepWave, 6), STAT=ErrStatTmp ) + 'approximation in the frequency domain.',ErrStat, ErrMsg, RoutineName) + ALLOCATE( NewmanAppForce( 0:InitInp%NStepWave, 6*p%NBody), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate array for the resulting Newmans '// & - 'approximation of the 2nd order force.',ErrStat, ErrMsg, 'NewmanApp_InitCalc') + 'approximation of the 2nd order force.',ErrStat, ErrMsg, RoutineName) @@ -1571,7 +1680,7 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg ! Initialize the FFT library CALL InitCFFT ( InitInp%NStepWave, FFT_Data, .FALSE., ErrStatTmp ) ! Complex result FFT initialize - CALL SetErrStat(ErrStatTmp,'Error occured while initializing the FFT.',ErrStat,ErrMsg,'NewmanApp_InitCalc') + CALL SetErrStat(ErrStatTmp,'Error occured 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) @@ -1584,118 +1693,203 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg END IF + ! Loop through all bodies + DO IBody=1,p%NBody + + ! set all frequency terms to zero to start + NewmanTerm1C(:,:) = CMPLX(0.0, 0.0, SiKi) + NewmanTerm2C(:,:) = CMPLX(0.0, 0.0, SiKi) - ! Now loop through all the dimensions and perform the calculation - DO I=1,6 - ! set zero frequency term to zero - NewmanTerm1C(0) = CMPLX(0.0_SiKi, 0.0_SiKi) - NewmanTerm2C(0) = CMPLX(0.0_SiKi, 0.0_SiKi) + ! Heading correction, only applies to NBodyMod == 2 + if (p%NBodyMod==2) then + RotateZdegOffset = InitInp%PtfmRefztRot(IBody)*R2D + else + RotateZdegOffset = 0.0_SiKi + endif - ! Only on the dimensions we requested - IF ( p%NewmanAppDims(I) ) THEN + !---------------------------------------------------- + ! Populate the frequency terms for this body + !---------------------------------------------------- - ! Set an initial search index for the 3D and 4D array interpolation - LastIndex3 = (/0,0,0/) - LastIndex4 = (/0,0,0,0/) + DO ThisDim=1,6 + + Idx= (IBody-1)*6+ThisDim - ! To make things run slightly quicker, copy the data we will be interpolating over into the temporary arrays IF (NewmanAppData%DataIs3D) THEN - TmpData3D = NewmanAppData%Data3D%DataSet(:,:,:,I) + TmpFlag = NewmanAppData%Data3D%LoadComponents(Idx) ELSE - TmpData4D = NewmanAppData%Data4D%DataSet(:,:,:,:,I) + TmpFlag = NewmanAppData%Data4D%LoadComponents(Idx) END IF - - DO J=1,InitInp%NStepWave2 + ! Only on the dimensions we requested, and if it is present in the data + IF ( p%NewmanAppDims(ThisDim) .AND. TmpFlag ) THEN - ! First get the wave amplitude -- must be reconstructed from the WaveElevC array. First index is the real (1) or - ! imaginary (2) part. Divide by NStepWave2 so that the wave amplitude is of the same form as the paper. - aWaveElevC = CMPLX( InitInp%WaveElevC0(1,J), InitInp%WaveElevC0(2,J)) / InitInp%NStepWave2 - ! Calculate the frequency - Omega1 = J * InitInp%WaveDOmega + ! Set an initial search index for the 3D and 4D array interpolation + LastIndex3 = (/0,0,0/) + LastIndex4 = (/0,0,0,0/) + ! To make things run slightly quicker, copy the data we will be interpolating over into the temporary arrays + IF (NewmanAppData%DataIs3D) THEN + TmpData3D = NewmanAppData%Data3D%DataSet(:,:,:,Idx) + ELSE + TmpData4D = NewmanAppData%Data4D%DataSet(:,:,:,:,Idx) + END IF - ! Only get a QTF value if within the range of frequencies between the cutoffs for the difference frequency - IF ( (Omega1 >= InitInp%WvLowCOff) .AND. (Omega1 <= InitInp%WvHiCOff) ) THEN - ! Now get the QTF value that corresponds to this frequency and wavedirection pair. - IF ( NewmanAppData%DataIs3D ) THEN + DO J=1,InitInp%NStepWave2 - ! Set the (omega1,beta1,beta2) point we are looking for. - Coord3 = (/ Omega1, InitInp%WaveDirArr(J), InitInp%WaveDirArr(J) /) + ! First get the wave amplitude -- must be reconstructed from the WaveElevC array. First index is the real (1) or + ! imaginary (2) part. Divide by NStepWave2 so that the wave amplitude is of the same form as the paper. + aWaveElevC = CMPLX( InitInp%WaveElevC0(1,J), InitInp%WaveElevC0(2,J), SiKi) / InitInp%NStepWave2 - ! get the interpolated value for F(omega1,beta1,beta2) - CALL WAMIT_Interp3D_Cplx( Coord3, TmpData3D, NewmanAppData%Data3D%WvFreq1, & - NewmanAppData%Data3D%WvDir1, NewmanAppData%Data3D%WvDir2, LastIndex3, QTF_Value, ErrStatTmp, ErrMsgTmp ) + ! Calculate the frequency + Omega1 = J * InitInp%WaveDOmega - ELSE - ! Set the (omega1,omega2,beta1,beta2) point we are looking for. - Coord4 = (/ Omega1, Omega1, InitInp%WaveDirArr(J), InitInp%WaveDirArr(J) /) + ! Only get a QTF value if within the range of frequencies between the cutoffs for the difference frequency + IF ( (Omega1 >= InitInp%WvLowCOff) .AND. (Omega1 <= InitInp%WvHiCOff) ) THEN - ! get the interpolated value for F(omega1,omega2,beta1,beta2) - CALL WAMIT_Interp4D_Cplx( Coord4, TmpData4D, NewmanAppData%Data4D%WvFreq1, NewmanAppData%Data4D%WvFreq2, & - NewmanAppData%Data4D%WvDir1, NewmanAppData%Data4D%WvDir2, LastIndex4, QTF_Value, ErrStatTmp, ErrMsgTmp ) + ! Now get the QTF value that corresponds to this frequency and wavedirection pair. + IF ( NewmanAppData%DataIs3D ) THEN + ! Set the (omega1,beta1,beta2) point we are looking for. + Coord3 = (/ REAL(Omega1,SiKi), InitInp%WaveDirArr(J), InitInp%WaveDirArr(J) /) - ENDIF !QTF value find + ! Apply local Z rotation to heading angle (degrees) to put wave direction into the local (rotated) body frame + Coord3(2) = Coord3(2) - RotateZdegOffset + Coord3(3) = Coord3(3) - RotateZdegOffset + ! get the interpolated value for F(omega1,beta1,beta2) + CALL WAMIT_Interp3D_Cplx( Coord3, TmpData3D, NewmanAppData%Data3D%WvFreq1, & + NewmanAppData%Data3D%WvDir1, NewmanAppData%Data3D%WvDir2, LastIndex3, QTF_Value, ErrStatTmp, ErrMsgTmp ) - ELSE ! outside the frequency range + ELSE - QTF_Value = CMPLX(0.0_SiKi,0.0_SiKi) + ! Set the (omega1,omega2,beta1,beta2) point we are looking for. + Coord4 = (/ REAL(Omega1,SiKi), REAL(Omega1,SiKi), InitInp%WaveDirArr(J), InitInp%WaveDirArr(J) /) - ENDIF ! frequency check + ! Apply local Z rotation to heading angle (degrees) to put wave direction into the local (rotated) body frame + Coord4(3) = Coord4(3) - RotateZdegOffset + Coord4(4) = Coord4(4) - RotateZdegOffset + ! get the interpolated value for F(omega1,omega2,beta1,beta2) + CALL WAMIT_Interp4D_Cplx( Coord4, TmpData4D, NewmanAppData%Data4D%WvFreq1, NewmanAppData%Data4D%WvFreq2, & + NewmanAppData%Data4D%WvDir1, NewmanAppData%Data4D%WvDir2, LastIndex4, QTF_Value, ErrStatTmp, ErrMsgTmp ) - ! Check and make sure nothing bombed in the interpolation that we need to be aware of - CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,'NewmanApp_InitCalc') - IF ( ErrStat >= AbortErrLev ) THEN - IF (ALLOCATED(TmpData3D)) DEALLOCATE(TmpData3D,STAT=ErrStatTmp) - IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) - IF (ALLOCATED(NewmanTerm1t)) DEALLOCATE(NewmanTerm1t,STAT=ErrStatTmp) - IF (ALLOCATED(NewmanTerm2t)) DEALLOCATE(NewmanTerm2t,STAT=ErrStatTmp) - IF (ALLOCATED(NewmanTerm1C)) DEALLOCATE(NewmanTerm1C,STAT=ErrStatTmp) - IF (ALLOCATED(NewmanTerm2C)) DEALLOCATE(NewmanTerm2C,STAT=ErrStatTmp) - IF (ALLOCATED(NewmanAppForce)) DEALLOCATE(NewmanAppForce,STAT=ErrStatTmp) - RETURN - ENDIF + ENDIF !QTF value find + + ! Now we have the value of the QTF. These values should only be real for the omega1=omega2 case of the approximation. + ! However if the value came from the 4D interpolation routine, it might have some residual complex part to it. So + ! we throw the complex part out. NOTE: the phase shift due to location will be added before the FFT. + QTF_Value = CMPLX(REAL(QTF_Value,SiKi),0.0,SiKi) + + + ELSE ! outside the frequency range + QTF_Value = CMPLX(0.0,0.0,SiKi) + ENDIF ! frequency check - ! Now we have the value of the QTF. These values should only be real for the omega1=omega2 case of the approximation. - ! However if the value came from the 4D interpolation routine, it might have some residual complex part to it. So - ! we throw the complex part out. - QTF_Value = CMPLX(REAL(QTF_Value),0.0_SiKi) + ! Check and make sure nothing bombed in the interpolation that we need to be aware of + CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + IF (ALLOCATED(TmpData3D)) DEALLOCATE(TmpData3D,STAT=ErrStatTmp) + IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) + IF (ALLOCATED(NewmanTerm1t)) DEALLOCATE(NewmanTerm1t,STAT=ErrStatTmp) + IF (ALLOCATED(NewmanTerm2t)) DEALLOCATE(NewmanTerm2t,STAT=ErrStatTmp) + IF (ALLOCATED(NewmanTerm1C)) DEALLOCATE(NewmanTerm1C,STAT=ErrStatTmp) + IF (ALLOCATED(NewmanTerm2C)) DEALLOCATE(NewmanTerm2C,STAT=ErrStatTmp) + IF (ALLOCATED(NewmanAppForce)) DEALLOCATE(NewmanAppForce,STAT=ErrStatTmp) + RETURN + ENDIF + ! Now calculate the Newman terms + IF (REAL(QTF_Value) > 0.0_SiKi) THEN - ! Now we place these results into the arrays - IF (REAL(QTF_Value) > 0.0_SiKi) THEN + NewmanTerm1C(J,ThisDim) = aWaveElevC * (QTF_Value)**0.5_SiKi + NewmanTerm2C(J,ThisDim) = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) - NewmanTerm1C(J) = aWaveElevC * (QTF_Value)**0.5_SiKi - NewmanTerm2C(J) = CMPLX(0.0_SiKi, 0.0_SiKi) + ELSE IF (REAL(QTF_Value) < 0.0_SiKi) THEN - ELSE IF (REAL(QTF_Value) < 0.0_SiKi) THEN + NewmanTerm1C(J,ThisDim) = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + NewmanTerm2C(J,ThisDim) = aWaveElevC * (-QTF_Value)**0.5_SiKi - NewmanTerm1C(J) = CMPLX(0.0_SiKi, 0.0_SiKi) - NewmanTerm2C(J) = aWaveElevC * (-QTF_Value)**0.5_SiKi + ELSE ! at 0 - ELSE ! at 0 + NewmanTerm1C(J,ThisDim) = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + NewmanTerm2C(J,ThisDim) = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) - NewmanTerm1C(J) = CMPLX(0.0_SiKi, 0.0_SiKi) - NewmanTerm2C(J) = CMPLX(0.0_SiKi, 0.0_SiKi) + ENDIF - ENDIF + ENDDO ! J=1,InitInp%NStepWave2 + ENDIF ! Load component to calculate - ENDDO + ENDDO ! ThisDim -- index to current dimension + + + !---------------------------------------------------- + ! Rotate back to global frame and phase shift and set the terms for the summation + !---------------------------------------------------- + + ! Set rotation + ! NOTE: RotateZMatrixT is the rotation from local to global. + RotateZMatrixT(:,1) = (/ cos(InitInp%PtfmRefztRot(IBody)), -sin(InitInp%PtfmRefztRot(IBody)) /) + RotateZMatrixT(:,2) = (/ sin(InitInp%PtfmRefztRot(IBody)), cos(InitInp%PtfmRefztRot(IBody)) /) + + ! Loop through all the frequencies + DO J=1,InitInp%NStepWave2 + + ! Frequency + Omega1 = J * InitInp%WaveDOmega + + !> Phase shift due to offset in location, only for NBodyMod==2 + if (p%NBodyMod == 2) then + + !> The phase shift due to an (x,y) offset is of the form + !! \f$ exp[-\imath k(\omega) ( X cos(\beta(w)) + Y sin(\beta(w)) )] \f$ + ! NOTE: the phase shift applies to the aWaveElevC of the incoming wave. Including it here instead + ! of above is mathematically equivalent, but only because each frequency has only one wave + ! direction associated with it through the equal energy approach used in multidirectional waves. + + WaveNmbr1 = WaveNumber ( REAL(Omega1,SiKi), InitInp%Gravity, InitInp%WtrDpth ) ! SiKi returned + TmpReal1 = WaveNmbr1 * ( InitInp%PtfmRefxt(1)*cos(InitInp%WaveDirArr(J)*D2R) + InitInp%PtfmRefyt(1)*sin(InitInp%WaveDirArr(J)*D2R) ) + PhaseShiftXY = CMPLX( cos(TmpReal1), -sin(TmpReal1) ) + + ! Apply the phase shift + DO ThisDim=1,6 + NewmanTerm1C(J,ThisDim) = NewmanTerm1C(J,ThisDim)*PhaseShiftXY ! Newman term 1 + NewmanTerm2C(J,ThisDim) = NewmanTerm2C(J,ThisDim)*PhaseShiftXY ! Newman term 2 + ENDDO + endif + + + ! Apply the rotation to get back to global frame -- Term 1 + NewmanTerm1C(J,1:2) = MATMUL(RotateZMatrixT, NewmanTerm1C(J,1:2)) + NewmanTerm1C(J,4:5) = MATMUL(RotateZMatrixT, NewmanTerm1C(J,4:5)) + + ! Apply the rotation to get back to global frame -- Term 2 + NewmanTerm2C(J,1:2) = MATMUL(RotateZMatrixT, NewmanTerm2C(J,1:2)) + NewmanTerm2C(J,4:5) = MATMUL(RotateZMatrixT, NewmanTerm2C(J,4:5)) + + ENDDO ! J=1,InitInp%NStepWave2 + + + + !---------------------------------------------------- + ! Apply the FFT to get time domain results + !---------------------------------------------------- + + DO ThisDim=1,6 ! Loop through all dimensions + + Idx= (IBody-1)*6+ThisDim ! Now we apply the FFT to the first piece. - CALL ApplyCFFT( NewmanTerm1t(:), NewmanTerm1C(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,'NewmanApp_InitCalc') + CALL ApplyCFFT( NewmanTerm1t(:), NewmanTerm1C(:,ThisDim), FFT_Data, ErrStatTmp ) + CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData3D)) DEALLOCATE(TmpData3D,STAT=ErrStatTmp) IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) @@ -1708,8 +1902,8 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg END IF ! Now we apply the FFT to the second piece. - CALL ApplyCFFT( NewmanTerm2t(:), NewmanTerm2C(:), FFT_Data, ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,'NewmanApp_InitCalc') + CALL ApplyCFFT( NewmanTerm2t(:), NewmanTerm2C(:,ThisDim), FFT_Data, ErrStatTmp ) + CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData3D)) DEALLOCATE(TmpData3D,STAT=ErrStatTmp) IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) @@ -1724,20 +1918,20 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg ! Now square the real part of the resulting time domain pieces and add them together to get the final force time series. DO J=0,InitInp%NStepWave-1 - NewmanAppForce(J,I) = (abs(NewmanTerm1t(J)))**2 - (abs(NewmanTerm2t(J)))**2 + NewmanAppForce(J,Idx) = (abs(NewmanTerm1t(J)))**2 - (abs(NewmanTerm2t(J)))**2 ENDDO ! Copy the last first term to the last so that it is cyclic - NewmanAppForce(InitInp%NStepWave,I) = NewmanAppForce(0,I) + NewmanAppForce(InitInp%NStepWave,Idx) = NewmanAppForce(0,Idx) - ENDIF ! Load component to calculate + ENDDO ! ThisDim -- index to current dimension - ENDDO + ENDDO ! IBody -- current body ! 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,'NewmanApp_InitCalc') + CALL SetErrStat(ErrStatTmp,'Error occured 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) @@ -1818,23 +2012,31 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS REAL(SiKi) :: TmpReal1 !< Temporary real REAL(SiKi) :: TmpReal2 !< Temporary real LOGICAL :: TmpFlag !< Temporary logical flag - INTEGER(IntKi) :: I !< Generic counter + INTEGER(IntKi) :: ThisDim !< Generic counter for dimension + INTEGER(IntKi) :: IBody !< Index to which body we are on + INTEGER(IntKi) :: Idx !< Index to the full set of 6*NBody INTEGER(IntKi) :: J !< Generic counter INTEGER(IntKi) :: K !< Generic counter TYPE(FFT_DataType) :: FFT_Data !< Temporary array for the FFT module we're using + CHARACTER(*), PARAMETER :: RoutineName = 'DiffQTF_InitCalc' ! Wave information and QTF temporary COMPLEX(SiKi) :: QTF_Value !< Temporary complex number for QTF - COMPLEX(SiKi), ALLOCATABLE :: TmpComplexArr(:) !< Temporary complex array for frequency domain of one complete load component + COMPLEX(SiKi), ALLOCATABLE :: TmpComplexArr(:,:) !< Temporary complex array for frequency domain of one complete load component COMPLEX(SiKi) :: TmpHMinusC !< Temporary variable for holding the current value of \f$ H^- \f$ COMPLEX(SiKi) :: aWaveElevC1 !< Wave elevation of the first frequency component. NStepWave2 factor removed. COMPLEX(SiKi) :: aWaveElevC2 !< Wave elevation of the second frequency component. NStepWave2 factor removed. - REAL(SiKi) :: OmegaDiff !< Wave difference frequency + REAL(ReKi) :: OmegaDiff !< Wave difference frequency REAL(SiKi), ALLOCATABLE :: TmpDiffQTFForce(:) !< The resulting diffQTF force for this load component - REAL(SiKi) :: Omega1 !< First wave frequency - REAL(SiKi) :: Omega2 !< Second wave frequency - REAL(SiKi) :: MnDriftForce(6) !< Mean drift force (first term). MnDrift_InitCalc routine will return this. + REAL(ReKi) :: Omega1 !< First wave frequency + REAL(ReKi) :: Omega2 !< Second wave frequency + REAL(SiKi), ALLOCATABLE :: MnDriftForce(:) !< Mean drift force (first term). MnDrift_InitCalc routine will return this. + REAL(SiKi) :: RotateZdegOffset !< Offset to wave heading (NBodyMod==2 only) + REAL(SiKi) :: RotateZMatrixT(2,2) !< The transpose of rotation in matrix form for rotation about z (from global to local) + COMPLEX(SiKi) :: PhaseShiftXY !< The phase shift offset to apply to the body + REAL(SiKi) :: WaveNmbr1 !< Wavenumber for this frequency + REAL(SiKi) :: WaveNmbr2 !< Wavenumber for this frequency ! Interpolation routine indices and value to search for, and smaller array to pass INTEGER(IntKi) :: LastIndex4(4) !< Last used index for searching in the interpolation algorithms. First wave freq @@ -1858,13 +2060,13 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS CALL SetErrStat( ErrID_Fatal,' The lowest frequency ( '//TRIM(Num2LStr(MINVAL(DiffQTFData%Data4D%WvFreq1)))// & ' rad/s first wave period) data in '//TRIM(DiffQTFData%Filename)// & ' is above the low frequency cutoff set by WvLowCOffD.', & - ErrStat,ErrMsg,'DiffQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) ENDIF IF ( MINVAL( DiffQTFData%Data4D%WvFreq2 ) > InitInp%WvLowCOffD ) THEN CALL SetErrStat( ErrID_Fatal,' The lowest frequency ( '//TRIM(Num2LStr(MINVAL(DiffQTFData%Data4D%WvFreq2)))// & ' rad/s for second wave period) data in '//TRIM(DiffQTFData%Filename)// & ' is above the low frequency cutoff set by WvLowCOffD.', & - ErrStat,ErrMsg,'DiffQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) ENDIF ! Check the high frequency cutoff -- using the Difference high frequency cutoff. The first order high frequency @@ -1873,18 +2075,18 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS CALL SetErrStat( ErrID_Fatal,' The highest frequency ( '//TRIM(Num2LStr(MAXVAL(DiffQTFData%Data4D%WvFreq1)))// & ' rad/s for first wave period) data in '//TRIM(DiffQTFData%Filename)// & ' is below the high frequency cutoff set by WvHiCOffD.', & - ErrStat,ErrMsg,'DiffQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) ENDIF IF ( MAXVAL(DiffQTFData%Data4D%WvFreq2) < InitInp%WvHiCOffD ) THEN CALL SetErrStat( ErrID_Fatal,' The highest frequency ( '//TRIM(Num2LStr(MAXVAL(DiffQTFData%Data4D%WvFreq1)))// & ' rad/s second wave period) data in '//TRIM(DiffQTFData%Filename)// & ' is below the high frequency cutoff set by WvHiCOffD.', & - ErrStat,ErrMsg,'DiffQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) ENDIF ELSE ! This is a catastrophic issue. We should not have called this routine without data that is usable for the DiffQTF calculation - CALL SetErrStat( ErrID_Fatal, ' The full Difference QTF method requires 4D data, and was not passed any.',ErrStat,ErrMsg,'DiffQTF_InitCalc') + CALL SetErrStat( ErrID_Fatal, ' The full Difference QTF method requires 4D data, and was not passed any.',ErrStat,ErrMsg,RoutineName) ENDIF IF ( ErrStat >= AbortErrLev ) RETURN @@ -1897,12 +2099,12 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS CALL SetErrStat( ErrID_Fatal,' WAMIT output file '//TRIM(DiffQTFData%Filename)//' only contains one wave '// & 'direction at '//TRIM(Num2LStr(DiffQTFData%Data4D%WvDir1(1)))//' degrees (first wave direction). '// & 'It cannot be used with multidirectional waves. Set WvDirMod to 0 to use this file.', & - ErrStat,ErrMsg,'DiffQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) ELSE IF ( InitInp%WaveMultiDir .AND. (DiffQTFData%Data4D%NumWvDir2 == 1) ) THEN CALL SetErrStat( ErrID_Fatal,' WAMIT output file '//TRIM(DiffQTFData%Filename)//' only contains one wave '// & 'direction at '//TRIM(Num2LStr(DiffQTFData%Data4D%WvDir2(1)))//' degrees (second wave direction). '// & 'It cannot be used with multidirectional waves. Set WvDirMod to 0 to use this file.', & - ErrStat,ErrMsg,'DiffQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) ELSE ! See Known Issues #1 at the top of this file. There may be problems if the data spans the +/- Pi boundary. For @@ -1914,7 +2116,7 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS (MINVAL(DiffQTFData%Data4D%WvDir2) > 150.0_SiKi) .OR. (MAXVAL(DiffQTFData%Data4D%WvDir2) < -150.0_SiKi) ) THEN CALL SetErrStat( ErrID_Warn,' There may be issues with how the wave direction data is handled when the wave '// & 'direction of interest is near the +/- 180 direction. This is a known issue with '// & - 'the WAMIT2 module that has not yet been addressed.',ErrStat,ErrMsg,'DiffQTF_InitCalc') + 'the WAMIT2 module that has not yet been addressed.',ErrStat,ErrMsg,RoutineName) ENDIF ! Now check the limits for the first wave direction @@ -1923,12 +2125,12 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS IF ( InitInp%WaveDirMin < MINVAL(DiffQTFData%Data4D%WvDir1) ) THEN CALL SetErrStat( ErrID_Fatal,' Minimum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMin))//' is not'//& 'found in the WAMIT data file '//TRIM(DiffQTFData%Filename)//' for the first wave direction.', & - ErrStat, ErrMsg, 'DiffQTF_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF - IF ( InitInp%WaveDirMax < MAXVAL(DiffQTFData%Data4D%WvDir1) ) THEN + IF ( InitInp%WaveDirMax > MAXVAL(DiffQTFData%Data4D%WvDir1) ) THEN CALL SetErrStat( ErrID_Fatal,' Maximum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMax))//' is not'//& 'found in the WAMIT data file '//TRIM(DiffQTFData%Filename)//' for the first wave direction.', & - ErrStat, ErrMsg, 'DiffQTF_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF @@ -1937,12 +2139,12 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS IF ( InitInp%WaveDirMin < MINVAL(DiffQTFData%Data4D%WvDir2) ) THEN CALL SetErrStat( ErrID_Fatal,' Minimum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMin))//' is not'//& 'found in the WAMIT data file '//TRIM(DiffQTFData%Filename)//' for the second wave direction.', & - ErrStat, ErrMsg, 'DiffQTF_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF - IF ( InitInp%WaveDirMax < MAXVAL(DiffQTFData%Data4D%WvDir2) ) THEN + IF ( InitInp%WaveDirMax > MAXVAL(DiffQTFData%Data4D%WvDir2) ) THEN CALL SetErrStat( ErrID_Fatal,' Maximum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMax))//' is not'//& 'found in the WAMIT data file '//TRIM(DiffQTFData%Filename)//' for the second wave direction.', & - ErrStat, ErrMsg, 'DiffQTF_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF ENDIF @@ -1957,13 +2159,16 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS !! and set the TmpFlag to true if there is a sparse matrix for one of them. !! FIXME: remove this check and warning once the sparse matrix interpolation routines are implemented. TmpFlag = .FALSE. - DO I=1,6 - IF ( DiffQTFData%Data4D%DataIsSparse(I) .AND. DiffQTFData%Data4D%LoadComponents(I) .AND. p%DiffQTFDims(I) ) TmpFlag = .TRUE. + DO IBody=1,DiffQTFData%Data4D%NumBodies + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( DiffQTFData%Data4D%DataIsSparse(Idx) .AND. DiffQTFData%Data4D%LoadComponents(Idx) .AND. p%DiffQTFDims(ThisDim) ) TmpFlag = .TRUE. + ENDDO ENDDO IF (TmpFlag) THEN CALL SetErrStat(ErrID_Fatal,' The second order WAMIT data in '//TRIM(DiffQTFData%Filename)//' is too sparse '// & 'for the interpolation routine used in the full Difference QTF calculation. At some later point, we will allow for '// & - 'sparse data when a different interpolation routine is implemented.',ErrStat,ErrMsg,'DiffQTF_InitCalc') + 'sparse data when a different interpolation routine is implemented.',ErrStat,ErrMsg,RoutineName) RETURN ENDIF @@ -1975,19 +2180,19 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS ! Setup temporary arrays that we will be passing the data to the interpolation routines in. ALLOCATE( TmpData4D(DiffQTFData%Data4D%NumWvFreq1,DiffQTFData%Data4D%NumWvFreq1,DiffQTFData%Data4D%NumWvDir1,DiffQTFData%Data4D%NumWvDir2),STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate temporary array for interpolation of 4D QTF data.', & - ErrStat, ErrMsg, 'DiffQTF_InitCalc') + ErrStat, ErrMsg, RoutineName) ! Setup the arrays holding the DiffQTF terms, both the complex frequency domain and real time domain pieces ALLOCATE( TmpDiffQTFForce( 0:InitInp%NStepWave), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate array for one load component of the full difference '// & - 'QTF 2nd order force time series.',ErrStat, ErrMsg, 'DiffQTF_InitCalc') - ALLOCATE( TmpComplexArr( 0:InitInp%NStepWave2), STAT=ErrStatTmp ) + 'QTF 2nd order force time series.',ErrStat, ErrMsg, RoutineName) + ALLOCATE( TmpComplexArr( 0:InitInp%NStepWave2, 6), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate array for one load component of the full difference '// & - 'QTF 2nd order force in the frequency domain.',ErrStat, ErrMsg, 'DiffQTF_InitCalc') - ALLOCATE( DiffQTFForce( 0:InitInp%NStepWave, 6), STAT=ErrStatTmp ) + 'QTF 2nd order force in the frequency domain.',ErrStat, ErrMsg, RoutineName) + ALLOCATE( DiffQTFForce( 0:InitInp%NStepWave, 6*p%NBody), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate array for the full difference '// & - 'QTF 2nd order force time series.',ErrStat, ErrMsg, 'DiffQTF_InitCalc') + 'QTF 2nd order force time series.',ErrStat, ErrMsg, RoutineName) ! If something went wrong during allocation of the temporary arrays... IF ( ErrStat >= AbortErrLev ) THEN @@ -2005,7 +2210,7 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS ! Initialize the FFT library. Do not apply normalization. CALL InitFFT ( InitInp%NStepWave, FFT_Data, .FALSE., ErrStatTmp ) - CALL SetErrStat(ErrStatTmp,'Error occured while initializing the FFT.',ErrStat,ErrMsg,'DiffQTF_InitCalc') + CALL SetErrStat(ErrStatTmp,'Error occured while initializing the FFT.',ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) IF (ALLOCATED(DiffQTFForce)) DEALLOCATE(DiffQTFForce,STAT=ErrStatTmp) @@ -2020,7 +2225,7 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS ! Before we continue, we will get the MnDriftForce results. ! --> Note that we can pass the DiffQTFData directly since we are using the same type for both CALL MnDrift_InitCalc( InitInp, p, DiffQTFData, MnDriftForce, ErrMsgTmp, ErrStatTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'DiffQTF_InitCalc' ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) IF (ALLOCATED(DiffQTFForce)) DEALLOCATE(DiffQTFForce,STAT=ErrStatTmp) @@ -2032,11 +2237,11 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS ! Make sure we have a value for the mean drift for each of the dimensions we were requested to calculate. To ! find out we will just check the status of the flags for each dimension in the MnDriftDims against the ones ! for the DiffQTFDims - DO I=1,6 - IF ( p%DiffQTFDims(I) .AND. (.NOT. p%MnDriftDims(I)) ) & + DO ThisDim=1,6 + IF ( p%DiffQTFDims(ThisDim) .AND. (.NOT. p%MnDriftDims(ThisDim)) ) & CALL SetErrStat( ErrID_Fatal,' The DiffQTF method requires the use of the MnDrift method for the first term. '// & 'Something went wrong and the MnDrift method returned a different number of load components.', & - ErrStat,ErrMsg,'DiffQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) ENDDO IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) @@ -2049,85 +2254,156 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS ! Now loop through all the dimensions and perform the calculation - DO I=1,6 + DO IBody=1,p%NBody - ! Only on the dimensions we requested - IF ( p%DiffQTFDims(I) ) THEN + ! Initialize the temporary array to zero. + TmpComplexArr = CMPLX(0.0_SiKi,0.0_SiKi,SiKi) + ! Heading correction, only applies to NBodyMod == 2 + if (p%NBodyMod==2) then + RotateZdegOffset = InitInp%PtfmRefztRot(IBody)*R2D + else + RotateZdegOffset = 0.0_SiKi + endif - ! Set an initial search index for the 4D array interpolation - LastIndex4 = (/0,0,0,0/) + !---------------------------------------------------- + ! Populate the frequency terms for this body + ! -- with phase shift for NBodyMod == 2 + !---------------------------------------------------- - ! To make things run slightly quicker, copy the data we will be interpolating over into the temporary arrays - TmpData4D = DiffQTFData%Data4D%DataSet(:,:,:,:,I) + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim - ! Initialize the temporary array to zero. - TmpComplexArr = CMPLX(0.0_SiKi,0.0_SiKi) + ! Only on the dimensions we requested, and it exists in the dataset + IF ( p%DiffQTFDims(ThisDim) .AND. DiffQTFData%Data4D%LoadComponents(Idx) ) THEN - ! Outer loop to create the TmpComplexArr - DO J=1,InitInp%NStepWave2-1 + ! Set an initial search index for the 4D array interpolation + LastIndex4 = (/0,0,0,0/) - ! Calculate the frequency -- This is the difference frequency. - OmegaDiff = J * InitInp%WaveDOmega + ! To make things run slightly quicker, copy the data we will be interpolating over into the temporary arrays + TmpData4D = DiffQTFData%Data4D%DataSet(:,:,:,:,Idx) + ! Outer loop to create the TmpComplexArr + DO J=1,InitInp%NStepWave2-1 - ! Only perform calculations if the difference frequency is in the right range - IF ( (OmegaDiff >= InitInp%WvLowCOffD) .AND. (OmegaDiff <= InitInp%WvHiCOffD) ) THEN + ! Calculate the frequency -- This is the difference frequency. + OmegaDiff = J * InitInp%WaveDOmega - ! Set the \f$ H^- \f$ term to zero before we start - TmpHMinusC = CMPLX(0.0_SiKi,0.0_SiKi) + ! Only perform calculations if the difference frequency is in the right range + IF ( (OmegaDiff >= InitInp%WvLowCOffD) .AND. (OmegaDiff <= InitInp%WvHiCOffD) ) THEN - ! Do the sum over H^- - DO K=1,InitInp%NStepWave2-J ! note the funny upper limit. This is because we are doing a summation on a triangular area. + ! Set the \f$ H^- \f$ term to zero before we start + TmpHMinusC = CMPLX(0.0_SiKi,0.0_SiKi,SiKi) - ! set the two frequencies that the difference frequency comes from - Omega1 = (J + K) * InitInp%WaveDOmega ! the mth frequency -- \mu^- + n = m - Omega2 = K * InitInp%WaveDOmega ! the nth frequency + ! Do the sum over H^- + DO K=1,InitInp%NStepWave2-J ! note the funny upper limit. This is because we are doing a summation on a triangular area. - ! Find the Wave amplitudes 1 and 2 - aWaveElevC1 = CMPLX( InitInp%WaveElevC0(1,J+K), InitInp%WaveElevC0(2,J+K)) / InitInp%NStepWave2 - aWaveElevC2 = CMPLX( InitInp%WaveElevC0(1,K), InitInp%WaveElevC0(2,K)) / InitInp%NStepWave2 + ! set the two frequencies that the difference frequency comes from + Omega1 = (J + K) * InitInp%WaveDOmega ! the mth frequency -- \mu^- + n = m + Omega2 = K * InitInp%WaveDOmega ! the nth frequency - ! Set the (omega1,omega2,beta1,beta2) point we are looking for. - Coord4 = (/ Omega1, Omega2, InitInp%WaveDirArr(J+K), InitInp%WaveDirArr(K) /) + ! Find the Wave amplitudes 1 and 2 + aWaveElevC1 = CMPLX( InitInp%WaveElevC0(1,J+K), InitInp%WaveElevC0(2,J+K), SiKi) / InitInp%NStepWave2 + aWaveElevC2 = CMPLX( InitInp%WaveElevC0(1,K), InitInp%WaveElevC0(2,K), SiKi) / InitInp%NStepWave2 - ! get the interpolated value for F(omega1,omega2,beta1,beta2) --> QTF_Value - CALL WAMIT_Interp4D_Cplx( Coord4, TmpData4D, DiffQTFData%Data4D%WvFreq1, DiffQTFData%Data4D%WvFreq2, & - DiffQTFData%Data4D%WvDir1, DiffQTFData%Data4D%WvDir2, LastIndex4, QTF_Value, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,'DiffQTF_InitCalc') - IF (ErrStat >= AbortErrLev ) THEN - IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) - IF (ALLOCATED(DiffQTFForce)) DEALLOCATE(DiffQTFForce,STAT=ErrStatTmp) - IF (ALLOCATED(TmpDiffQTFForce)) DEALLOCATE(TmpDiffQTFForce,STAT=ErrStatTmp) - IF (ALLOCATED(TmpComplexArr)) DEALLOCATE(TmpComplexArr,STAT=ErrStatTmp) - RETURN - ENDIF + ! Set the (omega1,omega2,beta1,beta2) point we are looking for. + Coord4 = (/ REAL(Omega1,SiKi), REAL(Omega2,SiKi), InitInp%WaveDirArr(J+K), InitInp%WaveDirArr(K) /) - ! Calculate this value and add it to what we have so far. - TmpHMinusC = TmpHMinusC + aWaveElevC1 * CONJG(aWaveElevC2) * QTF_Value + ! Apply local Z rotation to heading angle (degrees) to put wave direction into the local (rotated) body frame + Coord4(3) = Coord4(3) - RotateZdegOffset + Coord4(4) = Coord4(4) - RotateZdegOffset - ENDDO + ! get the interpolated value for F(omega1,omega2,beta1,beta2) --> QTF_Value + CALL WAMIT_Interp4D_Cplx( Coord4, TmpData4D, DiffQTFData%Data4D%WvFreq1, DiffQTFData%Data4D%WvFreq2, & + DiffQTFData%Data4D%WvDir1, DiffQTFData%Data4D%WvDir2, LastIndex4, QTF_Value, ErrStatTmp, ErrMsgTmp ) + CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) + IF (ErrStat >= AbortErrLev ) THEN + IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) + IF (ALLOCATED(DiffQTFForce)) DEALLOCATE(DiffQTFForce,STAT=ErrStatTmp) + IF (ALLOCATED(TmpDiffQTFForce)) DEALLOCATE(TmpDiffQTFForce,STAT=ErrStatTmp) + IF (ALLOCATED(TmpComplexArr)) DEALLOCATE(TmpComplexArr,STAT=ErrStatTmp) + RETURN + ENDIF - ! Copy this value difference frequency information over to the array we will take the IFFT. Divide - ! by two for the single sided FFT given in the documentation. - TmpComplexArr(J) = TmpHMinusC / 2.0_SiKi + !-------------------------- + ! Phase shift due to offset + !-------------------------- + if (p%NBodyMod == 2) then + !> The phase shift due to an (x,y) offset for second order difference frequencies is of the form + !! \f$ exp[-\imath ( k(\omega_1) ( X cos(\beta(w_1)) + Y sin(\beta(w_1)) ) + !! - k(\omega_2) ( X cos(\beta(w_2)) + Y sin(\beta(w_2)) ) ) ]\f$ + ! NOTE: the phase shift applies to the aWaveElevC of the incoming wave. Including it here instead + ! of above is mathematically equivalent, but only because each frequency has only one wave + ! direction associated with it through the equal energy approach used in multidirectional waves. - ELSE ! outside the frequency range, so + WaveNmbr1 = WaveNumber ( REAL(Omega1,SiKi), InitInp%Gravity, InitInp%WtrDpth ) ! SiKi returned + WaveNmbr2 = WaveNumber ( REAL(Omega2,SiKi), InitInp%Gravity, InitInp%WtrDpth ) ! SiKi returned + TmpReal1 = WaveNmbr1 * ( InitInp%PtfmRefxt(1)*cos(InitInp%WaveDirArr(J+K)*D2R) + InitInp%PtfmRefyt(1)*sin(InitInp%WaveDirArr(J+K)*D2R) ) + TmpReal2 = WaveNmbr2 * ( InitInp%PtfmRefxt(1)*cos(InitInp%WaveDirArr(K)*D2R) + InitInp%PtfmRefyt(1)*sin(InitInp%WaveDirArr(K)*D2R) ) - TmpComplexArr(J) = CMPLX(0.0_SiKi,0.0_SiKi) + ! Set the phase shift for the set of difference frequencies + PhaseShiftXY = CMPLX( cos(TmpReal1 - TmpReal2), -sin(TmpReal1 - TmpReal2) ) - ENDIF ! frequency check + ! For similicity, apply to the QTF_Value (mathematically equivalent to applying to the wave elevations) + QTF_Value = QTF_Value*PhaseShiftXY + endif ! Phaseshift for NBodyMod==2 - ENDDO + ! Calculate this value and add it to what we have so far. + TmpHMinusC = TmpHMinusC + aWaveElevC1 * CONJG(aWaveElevC2) * QTF_Value + + ENDDO + + ! Copy this value difference frequency information over to the array we will take the IFFT. Divide + ! by two for the single sided FFT given in the documentation. + TmpComplexArr(J,ThisDim) = TmpHMinusC / 2.0_SiKi + + ELSE ! outside the frequency range, so + + TmpComplexArr(J,ThisDim) = CMPLX(0.0_SiKi,0.0_SiKi,SiKi) + + ENDIF ! frequency check + + + ENDDO + ENDIF ! Load component to calculate + ENDDO ! ThisDim -- The current dimension + + + !---------------------------------------------------- + ! Rotate back to global frame + !---------------------------------------------------- + + ! Set rotation + ! NOTE: RotateZMatrixT is the rotation from local to global. + RotateZMatrixT(:,1) = (/ cos(InitInp%PtfmRefztRot(IBody)), -sin(InitInp%PtfmRefztRot(IBody)) /) + RotateZMatrixT(:,2) = (/ sin(InitInp%PtfmRefztRot(IBody)), cos(InitInp%PtfmRefztRot(IBody)) /) + + ! Loop through all the frequencies + DO J=1,InitInp%NStepWave2 + + ! Apply the rotation to get back to global frame + TmpComplexArr(J,1:2) = MATMUL(RotateZMatrixT, TmpComplexArr(J,1:2)) + TmpComplexArr(J,4:5) = MATMUL(RotateZMatrixT, TmpComplexArr(J,4:5)) + + ENDDO ! J=1,InitInp%NStepWave2 + + + + !---------------------------------------------------- + ! Apply the FFT to get time domain results + !---------------------------------------------------- + + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim ! Now we apply the FFT to the result of the sum - CALL ApplyFFT_cx( TmpDiffQTFForce(:), TmpComplexArr(:), FFT_Data, ErrStatTmp ) + 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.', & - ErrStat,ErrMsg,'DiffQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) IF (ALLOCATED(DiffQTFForce)) DEALLOCATE(DiffQTFForce,STAT=ErrStatTmp) @@ -2138,22 +2414,23 @@ SUBROUTINE DiffQTF_InitCalc( InitInp, p, DiffQTFData, DiffQTFForce, ErrMsg, ErrS ! Now we multiply the result by 2 and save it to the DiffQTFForce array and add the MnDrift term - DO K=0,InitInp%NStepWave-1 ! bjj: added the "-1" here because TmpDiffQTFForce(InitInp%NStepWave) is not set and DiffQTFForce(InitInp%NStepWave,I) gets overwritten next, anyway - DiffQTFForce(K,I) = 2.0_SiKi * TmpDiffQTFForce(K) + MnDriftForce(I) + ! NOTE: phase shift and orientations on the MnDriftForce term have already been applied + ! NOTE: the "-1" since TmpDiffQTFForce(InitInp%NStepWave) is not set and DiffQTFForce(InitInp%NStepWave,Idx) gets overwritten + DO K=0,InitInp%NStepWave-1 + DiffQTFForce(K,Idx) = 2.0_SiKi * TmpDiffQTFForce(K) + MnDriftForce(Idx) ENDDO - ! Copy the last first term to the last so that it is cyclic - DiffQTFForce(InitInp%NStepWave,I) = DiffQTFForce(0,I) - - ENDIF ! Load component to calculate + ! Copy the last first term to the first so that it is cyclic + DiffQTFForce(InitInp%NStepWave,Idx) = DiffQTFForce(0,Idx) - ENDDO + ENDDO ! ThisDim -- The current dimension + ENDDO ! IBody -- This WAMIT body ! 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,'DiffQTF_InitCalc') + CALL SetErrStat(ErrStatTmp,'Error occured while cleaning up after the FFTs.', ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) IF (ALLOCATED(DiffQTFForce)) DEALLOCATE(DiffQTFForce,STAT=ErrStatTmp) @@ -2254,24 +2531,34 @@ SUBROUTINE SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsg, ErrStat CHARACTER(2048) :: ErrMsgTmp !< Temporary error message for calls INTEGER(IntKi) :: ErrStatTmp !< Temporary error status for calls LOGICAL :: TmpFlag !< Temporary logical flag - INTEGER(IntKi) :: I !< Generic counter + INTEGER(IntKi) :: ThisDim !< Generic counter for dimension + INTEGER(IntKi) :: IBody !< Index to which body we are on + INTEGER(IntKi) :: Idx !< Index to the full set of 6*NBody INTEGER(IntKi) :: J !< Generic counter INTEGER(IntKi) :: K !< Generic counter TYPE(FFT_DataType) :: FFT_Data !< Temporary array for the FFT module we're using. For the first term in the equation. + CHARACTER(*), PARAMETER :: RoutineName = 'SumQTF_InitCalc' ! Wave information and QTF temporary COMPLEX(SiKi) :: QTF_Value !< Temporary complex number for QTF - COMPLEX(SiKi), ALLOCATABLE :: Term1ArrayC(:) !< Temporary complex array for frequency domain of one load component. For first term. - COMPLEX(SiKi), ALLOCATABLE :: Term2ArrayC(:) !< Temporary complex array for frequency domain of one load component. For second term. + COMPLEX(SiKi), ALLOCATABLE :: Term1ArrayC(:,:) !< Temporary complex array for frequency domain of one load component. For first term. + COMPLEX(SiKi), ALLOCATABLE :: Term2ArrayC(:,:) !< Temporary complex array for frequency domain of one load component. For second term. REAL(SiKi), ALLOCATABLE :: Term1Array(:) !< Temporary complex array for time domain of one load component. For first term. REAL(SiKi), ALLOCATABLE :: Term2Array(:) !< Temporary complex array for time domain of one load component. For second term. COMPLEX(SiKi) :: TmpHPlusC !< Temporary variable for holding the current value of \f$ H^+ \f$ COMPLEX(SiKi) :: aWaveElevC1 !< Wave elevation of the first frequency component. NStepWave2 factor removed. COMPLEX(SiKi) :: aWaveElevC2 !< Wave elevation of the second frequency component. NStepWave2 factor removed. - REAL(SiKi) :: OmegaSum !< Wave difference frequency - REAL(SiKi) :: Omega1 !< First wave frequency - REAL(SiKi) :: Omega2 !< Second wave frequency + REAL(ReKi) :: OmegaSum !< Wave difference frequency + REAL(ReKi) :: Omega1 !< First wave frequency + REAL(ReKi) :: Omega2 !< Second wave frequency + REAL(SiKi) :: RotateZdegOffset !< Offset to wave heading (NBodyMod==2 only) + REAL(SiKi) :: RotateZMatrixT(2,2) !< The transpose of rotation in matrix form for rotation about z (from global to local) + COMPLEX(SiKi) :: PhaseShiftXY !< The phase shift offset to apply to the body + REAL(SiKi) :: WaveNmbr1 !< Wavenumber for this frequency + REAL(SiKi) :: WaveNmbr2 !< Wavenumber for this frequency + REAL(SiKi) :: TmpReal1 !< Temporary real + REAL(SiKi) :: TmpReal2 !< Temporary real ! Interpolation routine indices and value to search for, and smaller array to pass INTEGER(IntKi) :: LastIndex4(4) !< Last used index for searching in the interpolation algorithms. First wave freq @@ -2295,13 +2582,13 @@ SUBROUTINE SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsg, ErrStat CALL SetErrStat( ErrID_Fatal,' The lowest frequency ( '//TRIM(Num2LStr(MINVAL(SumQTFData%Data4D%WvFreq1)))// & ' rad/s first wave period) data in '//TRIM(SumQTFData%Filename)// & ' is above the low frequency cutoff set by WvLowCOffS.', & - ErrStat,ErrMsg,'SumQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) ENDIF IF ( MINVAL( SumQTFData%Data4D%WvFreq2 ) > InitInp%WvLowCOffS ) THEN CALL SetErrStat( ErrID_Fatal,' The lowest frequency ( '//TRIM(Num2LStr(MINVAL(SumQTFData%Data4D%WvFreq2)))// & ' rad/s for second wave period) data in '//TRIM(SumQTFData%Filename)// & ' is above the low frequency cutoff set by WvLowCOffS.', & - ErrStat,ErrMsg,'SumQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) ENDIF ! Check the high frequency cutoff -- using the Difference high frequency cutoff. The first order high frequency @@ -2310,18 +2597,18 @@ SUBROUTINE SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsg, ErrStat CALL SetErrStat( ErrID_Fatal,' The highest frequency ( '//TRIM(Num2LStr(MAXVAL(SumQTFData%Data4D%WvFreq1)))// & ' rad/s for first wave period) data in '//TRIM(SumQTFData%Filename)// & ' is below the high frequency cutoff set by WvHiCOffS.', & - ErrStat,ErrMsg,'SumQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) ENDIF IF ( MAXVAL(SumQTFData%Data4D%WvFreq2) < InitInp%WvHiCOffS ) THEN CALL SetErrStat( ErrID_Fatal,' The highest frequency ( '//TRIM(Num2LStr(MAXVAL(SumQTFData%Data4D%WvFreq1)))// & ' rad/s second wave period) data in '//TRIM(SumQTFData%Filename)// & ' is below the high frequency cutoff set by WvHiCOffS.', & - ErrStat,ErrMsg,'SumQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) ENDIF ELSE ! This is a catastrophic issue. We should not have called this routine without data that is usable for the SumQTF calculation - CALL SetErrStat( ErrID_Fatal, ' The full Sum QTF method requires 4D data, and was not passed any.',ErrStat,ErrMsg,'SumQTF_InitCalc') + CALL SetErrStat( ErrID_Fatal, ' The full Sum QTF method requires 4D data, and was not passed any.',ErrStat,ErrMsg,RoutineName) ENDIF IF ( ErrStat >= AbortErrLev ) RETURN @@ -2334,12 +2621,12 @@ SUBROUTINE SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsg, ErrStat CALL SetErrStat( ErrID_Fatal,' WAMIT output file '//TRIM(SumQTFData%Filename)//' only contains one wave '// & 'direction at '//TRIM(Num2LStr(SumQTFData%Data4D%WvDir1(1)))//' degrees (first wave direction). '// & 'It cannot be used with multidirectional waves. Set WvDirMod to 0 to use this file.', & - ErrStat,ErrMsg,'SumQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) ELSE IF ( InitInp%WaveMultiDir .AND. (SumQTFData%Data4D%NumWvDir2 == 1) ) THEN CALL SetErrStat( ErrID_Fatal,' WAMIT output file '//TRIM(SumQTFData%Filename)//' only contains one wave '// & 'direction at '//TRIM(Num2LStr(SumQTFData%Data4D%WvDir2(1)))//' degrees (second wave direction). '// & 'It cannot be used with multidirectional waves. Set WvDirMod to 0 to use this file.', & - ErrStat,ErrMsg,'SumQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) ELSE ! See Known Issues #1 at the top of this file. There may be problems if the data spans the +/- Pi boundary. For @@ -2351,7 +2638,7 @@ SUBROUTINE SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsg, ErrStat (MINVAL(SumQTFData%Data4D%WvDir2) > 150.0_SiKi) .OR. (MAXVAL(SumQTFData%Data4D%WvDir2) < -150.0_SiKi) ) THEN CALL SetErrStat( ErrID_Warn,' There may be issues with how the wave direction data is handled when the wave '// & 'direction of interest is near the +/- 180 direction. This is a known issue with '// & - 'the WAMIT2 module that has not yet been addressed.',ErrStat,ErrMsg,'SumQTF_InitCalc') + 'the WAMIT2 module that has not yet been addressed.',ErrStat,ErrMsg,RoutineName) ENDIF ! Now check the limits for the first wave direction @@ -2360,12 +2647,12 @@ SUBROUTINE SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsg, ErrStat IF ( InitInp%WaveDirMin < MINVAL(SumQTFData%Data4D%WvDir1) ) THEN CALL SetErrStat( ErrID_Fatal,' Minimum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMin))//' is not'//& 'found in the WAMIT data file '//TRIM(SumQTFData%Filename)//' for the first wave direction.', & - ErrStat, ErrMsg, 'SumQTF_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF - IF ( InitInp%WaveDirMax < MAXVAL(SumQTFData%Data4D%WvDir1) ) THEN + IF ( InitInp%WaveDirMax > MAXVAL(SumQTFData%Data4D%WvDir1) ) THEN CALL SetErrStat( ErrID_Fatal,' Maximum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMax))//' is not'//& 'found in the WAMIT data file '//TRIM(SumQTFData%Filename)//' for the first wave direction.', & - ErrStat, ErrMsg, 'SumQTF_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF @@ -2374,12 +2661,12 @@ SUBROUTINE SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsg, ErrStat IF ( InitInp%WaveDirMin < MINVAL(SumQTFData%Data4D%WvDir2) ) THEN CALL SetErrStat( ErrID_Fatal,' Minimum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMin))//' is not'//& 'found in the WAMIT data file '//TRIM(SumQTFData%Filename)//' for the second wave direction.', & - ErrStat, ErrMsg, 'SumQTF_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF - IF ( InitInp%WaveDirMax < MAXVAL(SumQTFData%Data4D%WvDir2) ) THEN + IF ( InitInp%WaveDirMax > MAXVAL(SumQTFData%Data4D%WvDir2) ) THEN CALL SetErrStat( ErrID_Fatal,' Maximum wave direction required of '//TRIM(Num2LStr(InitInp%WaveDirMax))//' is not'//& 'found in the WAMIT data file '//TRIM(SumQTFData%Filename)//' for the second wave direction.', & - ErrStat, ErrMsg, 'SumQTF_InitCalc') + ErrStat, ErrMsg, RoutineName) ENDIF ENDIF @@ -2394,13 +2681,16 @@ SUBROUTINE SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsg, ErrStat !! and set the TmpFlag to true if there is a sparse matrix for one of them. !! FIXME: remove this check and warning once the sparse matrix interpolation routines are implimented. TmpFlag = .FALSE. - DO I=1,6 - IF ( SumQTFData%Data4D%DataIsSparse(I) .AND. SumQTFData%Data4D%LoadComponents(I) .AND. p%SumQTFDims(I) ) TmpFlag = .TRUE. + DO IBody=1,SumQTFData%Data4D%NumBodies + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + IF ( SumQTFData%Data4D%DataIsSparse(Idx) .AND. SumQTFData%Data4D%LoadComponents(Idx) .AND. p%SumQTFDims(ThisDim) ) TmpFlag = .TRUE. + ENDDO ENDDO IF (TmpFlag) THEN CALL SetErrStat(ErrID_Fatal,' The second order WAMIT data in '//TRIM(SumQTFData%Filename)//' is too sparse '// & 'for the interpolation routine used in the full sum QTF calculation. At some later point, we will allow for '// & - 'sparse data when a different interpolation routine is implimented.',ErrStat,ErrMsg,'SumQTF_InitCalc') + 'sparse data when a different interpolation routine is implimented.',ErrStat,ErrMsg,RoutineName) RETURN ENDIF @@ -2412,25 +2702,25 @@ SUBROUTINE SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsg, ErrStat ! Setup temporary arrays that we will be passing the data to the interpolation routines in. ALLOCATE( TmpData4D(SumQTFData%Data4D%NumWvFreq1,SumQTFData%Data4D%NumWvFreq1,SumQTFData%Data4D%NumWvDir1,SumQTFData%Data4D%NumWvDir2),STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate temporary array for interpolation of 4D QTF data.', & - ErrStat, ErrMsg, 'SumQTF_InitCalc') + ErrStat, ErrMsg, RoutineName) ! Setup the arrays holding the SumQTF terms, both the complex frequency domain and real time domain pieces - ALLOCATE( Term1ArrayC( 0:InitInp%NStepWave2), STAT=ErrStatTmp ) + ALLOCATE( Term1ArrayC( 0:InitInp%NStepWave2, 6), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate array for the first term of one load component of the full sum '// & - 'QTF 2nd order force in the frequency domain.',ErrStat, ErrMsg, 'SumQTF_InitCalc') - ALLOCATE( Term2ArrayC( 0:InitInp%NStepWave2), STAT=ErrStatTmp ) + 'QTF 2nd order force in the frequency domain.',ErrStat, ErrMsg, RoutineName) + ALLOCATE( Term2ArrayC( 0:InitInp%NStepWave2, 6), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate array for the second term of one load component of the full sum '// & - 'QTF 2nd order force in the frequency domain.',ErrStat, ErrMsg, 'SumQTF_InitCalc') + 'QTF 2nd order force in the frequency domain.',ErrStat, ErrMsg, RoutineName) ALLOCATE( Term1Array( 0:InitInp%NStepWave), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate array for the first term of one load component of the full sum '// & - 'QTF 2nd order force in the time domain.',ErrStat, ErrMsg, 'SumQTF_InitCalc') + 'QTF 2nd order force in the time domain.',ErrStat, ErrMsg, RoutineName) ALLOCATE( Term2Array( 0:InitInp%NStepWave), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate array for the second term of one load component of the full sum '// & - 'QTF 2nd order force in the time domain.',ErrStat, ErrMsg, 'SumQTF_InitCalc') - ALLOCATE( SumQTFForce( 0:InitInp%NStepWave, 6), STAT=ErrStatTmp ) + 'QTF 2nd order force in the time domain.',ErrStat, ErrMsg, RoutineName) + ALLOCATE( SumQTFForce( 0:InitInp%NStepWave, 6*p%NBody), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,' Cannot allocate array for the full difference '// & - 'QTF 2nd order force time series.',ErrStat, ErrMsg, 'SumQTF_InitCalc') + 'QTF 2nd order force time series.',ErrStat, ErrMsg, RoutineName) ! If something went wrong during allocation of the temporary arrays... IF ( ErrStat >= AbortErrLev ) THEN @@ -2449,7 +2739,7 @@ SUBROUTINE SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsg, ErrStat ! Initialize the FFT library. Normalization not required in this formulation. CALL InitFFT ( InitInp%NStepWave, FFT_Data, .FALSE., ErrStatTmp ) ! FIXME: - CALL SetErrStat(ErrStatTmp,'Error occured while initializing the FFT.',ErrStat,ErrMsg,'SumQTF_InitCalc') + CALL SetErrStat(ErrStatTmp,'Error occured 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) @@ -2459,204 +2749,297 @@ SUBROUTINE SumQTF_InitCalc( InitInp, p, SumQTFData, SumQTFForce, ErrMsg, ErrStat ! Now loop through all the dimensions and perform the calculation - DO I=1,6 + DO IBody=1,p%NBody + + ! Initialize the temporary array to zero. + Term1ArrayC = CMPLX(0.0_SiKi,0.0_SiKi,SiKi) + Term2ArrayC = CMPLX(0.0_SiKi,0.0_SiKi,SiKi) - ! Only on the dimensions we requested - IF ( p%SumQTFDims(I) ) THEN + ! Heading correction, only applies to NBodyMod == 2 + if (p%NBodyMod==2) then + RotateZdegOffset = InitInp%PtfmRefztRot(IBody)*R2D + else + RotateZdegOffset = 0.0_SiKi + endif + !---------------------------------------------------- + ! Populate the frequency terms for this body + ! -- with phase shift for NBodyMod == 2 + !---------------------------------------------------- - ! To make things run slightly quicker, copy the data we will be interpolating over into the temporary arrays - TmpData4D = SumQTFData%Data4D%DataSet(:,:,:,:,I) + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim + ! Only on the dimensions we requested, and if it is present in the data + IF ( p%SumQTFDims(ThisDim) .AND. SumQTFData%Data4D%LoadComponents(Idx) ) THEN - !--------------------------------------------------------------------------------- - ! Calculate the first term - ! This term is only the FFT over the diagonal elements where omega_1 = omega_2 - ! note that the sum frequency is 2*omega. The index for the sum frequency is - ! therefore 2*J. Since we are placing the calculated value for the A_m * A_m * - ! F_k^+ term in the 2*omega location, we will only run through the first half of - ! the frequencies (the sum frequency will exceed the bounds of the frequencies - ! used in the FFT otherwise). - ! The IFFT will be calculated later. + ! To make things run slightly quicker, copy the data we will be interpolating over into the temporary arrays + TmpData4D = SumQTFData%Data4D%DataSet(:,:,:,:,Idx) - ! Set an initial search index for the 4D array interpolation - LastIndex4 = (/0,0,0,0/) + !--------------------------------------------------------------------------------- + ! Calculate the first term + ! This term is only the FFT over the diagonal elements where omega_1 = omega_2 + ! note that the sum frequency is 2*omega. The index for the sum frequency is + ! therefore 2*J. Since we are placing the calculated value for the A_m * A_m * + ! F_k^+ term in the 2*omega location, we will only run through the first half of + ! the frequencies (the sum frequency will exceed the bounds of the frequencies + ! used in the FFT otherwise). + ! The IFFT will be calculated later. - ! Initialize the array to zero - Term1ArrayC = CMPLX(0.0_SiKi,0.0_SiKi) + ! Set an initial search index for the 4D array interpolation + LastIndex4 = (/0,0,0,0/) + ! The limits look a little funny. But remember we are placing the value in the 2*J location, + ! so we cannot overun the end of the array, and the highest frequency must be zero. The + ! floor function is just in case (NStepWave2 - 1) is an odd number + DO J=1,FLOOR(REAL(InitInp%NStepWave2-1)/2.0_SiKi) - ! The limits look a little funny. But remember we are placing the value in the 2*J location, - ! so we cannot overun the end of the array, and the highest frequency must be zero. The - ! floor function is just in case (NStepWave2 - 1) is an odd number - DO J=1,FLOOR(REAL(InitInp%NStepWave2-1)/2.0_SiKi) + ! The frequency + Omega1 = REAL(J,ReKi) * InitInp%WaveDOmega + OmegaSum = 2.0_SiKi * Omega1 ! the sum frequency - ! The frequency - Omega1 = J * InitInp%WaveDOmega - OmegaSum = 2.0_SiKi * Omega1 ! the sum frequency + ! Only perform calculations if the difference frequency is in the right range + IF ( (OmegaSum >= InitInp%WvLowCOffS) .AND. (OmegaSum <= InitInp%WvHiCOffS) ) THEN - ! Only perform calculations if the difference frequency is in the right range - IF ( (OmegaSum >= InitInp%WvLowCOffS) .AND. (OmegaSum <= InitInp%WvHiCOffS) ) THEN + ! Find the wave amplitude at frequency omega + aWaveElevC1 = CMPLX( InitInp%WaveElevC0(1,J), InitInp%WaveElevC0(2,J), SiKi ) / InitInp%NStepWave2 - ! Find the wave amplitude at frequency omega - aWaveElevC1 = CMPLX( InitInp%WaveElevC0(1,J), InitInp%WaveElevC0(2,J)) / InitInp%NStepWave2 + ! Set the (omega1,omega2,beta1,beta2) point we are looking for. + Coord4 = (/ REAL(Omega1,SiKi), REAL(Omega1,SiKi), InitInp%WaveDirArr(J), InitInp%WaveDirArr(J) /) - ! Set the (omega1,omega2,beta1,beta2) point we are looking for. - Coord4 = (/ Omega1, Omega1, InitInp%WaveDirArr(J), InitInp%WaveDirArr(J) /) + ! Apply local Z rotation to heading angle (degrees) to put wave direction into the local (rotated) body frame + Coord4(3) = Coord4(3) - RotateZdegOffset + Coord4(4) = Coord4(4) - RotateZdegOffset - ! get the interpolated value for F(omega1,omega2,beta1,beta2) --> QTF_Value - CALL WAMIT_Interp4D_Cplx( Coord4, TmpData4D, SumQTFData%Data4D%WvFreq1, SumQTFData%Data4D%WvFreq2, & - SumQTFData%Data4D%WvDir1, SumQTFData%Data4D%WvDir2, LastIndex4, QTF_Value, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,'SumQTF_InitCalc') - IF (ErrStat >= AbortErrLev ) THEN - IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) - RETURN - ENDIF + ! get the interpolated value for F(omega1,omega2,beta1,beta2) --> QTF_Value + CALL WAMIT_Interp4D_Cplx( Coord4, TmpData4D, SumQTFData%Data4D%WvFreq1, SumQTFData%Data4D%WvFreq2, & + SumQTFData%Data4D%WvDir1, SumQTFData%Data4D%WvDir2, LastIndex4, QTF_Value, ErrStatTmp, ErrMsgTmp ) + CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) + IF (ErrStat >= AbortErrLev ) THEN + IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) + RETURN + ENDIF - ! Set the value of the first term in the frequency domain - Term1ArrayC(2*J) = aWaveElevC1 * aWaveElevC1 * QTF_Value + !-------------------------- + ! Phase shift due to offset + !-------------------------- + if (p%NBodyMod == 2) then + !> The phase shift due to an (x,y) offset for second order difference frequencies is of the form + !! \f$ exp[-\imath ( k(\omega_1) ( X cos(\beta(w_1)) + Y sin(\beta(w_1)) ) + !! 1 k(\omega_2) ( X cos(\beta(w_2)) + Y sin(\beta(w_2)) ) ) ]\f$. + !! For the first term, \f$ \omega_1 = \omega_2 \$f. + ! NOTE: the phase shift applies to the aWaveElevC of the incoming wave. Including it here instead + ! of above is mathematically equivalent, but only because each frequency has only one wave + ! direction associated with it through the equal energy approach used in multidirectional waves. + WaveNmbr1 = WaveNumber ( REAL(Omega1,SiKi), InitInp%Gravity, InitInp%WtrDpth ) ! SiKi returned + TmpReal1 = WaveNmbr1 * ( InitInp%PtfmRefxt(1)*cos(InitInp%WaveDirArr(J)*D2R) + InitInp%PtfmRefyt(1)*sin(InitInp%WaveDirArr(J)*D2R) ) - ENDIF ! Check on the limits - ENDDO ! First term calculation + ! Set the phase shift for the set of sum frequencies + PhaseShiftXY = CMPLX( cos(TmpReal1 + TmpReal1), -sin(TmpReal1 + TmpReal1) ) + ! For similicity, apply to the QTF_Value (mathematically equivalent to applying to the wave elevations) + QTF_Value = QTF_Value*PhaseShiftXY + endif ! Phaseshift for NBodyMod==2 - !--------------------------------------------------------------------------------- - ! Calculate the second term. - ! In this term, we are are now stepping through the sum frequencies. The inner - ! sum essentially covers all the off diagonal terms (omega_m /= omega_n). The limits - ! on the outer integral that is the FFT run through the full frequency range that - ! we are using + ! Set the value of the first term in the frequency domain + Term1ArrayC(2*J,ThisDim) = aWaveElevC1 * aWaveElevC1 * QTF_Value - ! Set an initial search index for the 4D array interpolation - LastIndex4 = (/0,0,0,0/) + ENDIF ! Check on the limits + ENDDO ! First term calculation - ! Initialize the temporary arrays for each term to zero. - Term2ArrayC = CMPLX(0.0_SiKi,0.0_SiKi) + !--------------------------------------------------------------------------------- + ! Calculate the second term. + ! In this term, we are are now stepping through the sum frequencies. The inner + ! sum essentially covers all the off diagonal terms (omega_m /= omega_n). The limits + ! on the outer integral that is the FFT run through the full frequency range that + ! we are using - ! Check the limits for the high frequency cutoff. If WvHiCOffS is less than the - ! maximum frequency possible with the value of WaveDT (omega_max = pi/WaveDT = NStepWave2*WaveDOmega), - ! then we are good. If the WvHiCOff > 1/2 omega_max, then we will be potentially - ! throwing away information. However, remember the following: - ! WaveDT Omega_max wavelength - ! (s) (rad/s) (m) - ! .25 4 Pi < 1 - ! 0.5 2 Pi 1 - ! 1.0 Pi 10 - ! so, we don't need a really small WaveDT - !This section has been removed since it is kind of annoying. - ! IF ( InitInp%WvHiCOffS > InitInp%NStepWave2*InitInp%WaveDOmega ) THEN - ! CALL SetErrStat( ErrID_Warn,' The high frequency cutoff for second order wave forces, WvHiCOffS, '// & - ! 'is larger than the Nyquist frequency for the given time step of WaveDT. The Nyquist frequency '// & - ! '(highest frequency) that can be computed is OmegaMax = PI/WaveDT = '// & - ! TRIM(Num2LStr(InitInp%NStepWave2*InitInp%WaveDOmega))// & - ! ' radians/second. If you need those frequencies, decrease WaveDT. For reference, 2*PI '// & - ! 'radians/second corresponds to a wavelength of ~1 meter.',& - ! ErrStat,ErrMsg,'SumQTF_InitCalc') - ! ENDIF + ! Set an initial search index for the 4D array interpolation + LastIndex4 = (/0,0,0,0/) + ! Check the limits for the high frequency cutoff. If WvHiCOffS is less than the + ! maximum frequency possible with the value of WaveDT (omega_max = pi/WaveDT = NStepWave2*WaveDOmega), + ! then we are good. If the WvHiCOff > 1/2 omega_max, then we will be potentially + ! throwing away information. However, remember the following: + ! WaveDT Omega_max wavelength + ! (s) (rad/s) (m) + ! .25 4 Pi < 1 + ! 0.5 2 Pi 1 + ! 1.0 Pi 10 + ! so, we don't need a really small WaveDT + !This section has been removed since it is kind of annoying. + ! IF ( InitInp%WvHiCOffS > InitInp%NStepWave2*InitInp%WaveDOmega ) THEN + ! CALL SetErrStat( ErrID_Warn,' The high frequency cutoff for second order wave forces, WvHiCOffS, '// & + ! 'is larger than the Nyquist frequency for the given time step of WaveDT. The Nyquist frequency '// & + ! '(highest frequency) that can be computed is OmegaMax = PI/WaveDT = '// & + ! TRIM(Num2LStr(InitInp%NStepWave2*InitInp%WaveDOmega))// & + ! ' radians/second. If you need those frequencies, decrease WaveDT. For reference, 2*PI '// & + ! 'radians/second corresponds to a wavelength of ~1 meter.',& + ! ErrStat,ErrMsg,RoutineName) + ! ENDIF - ! Outer loop to create the Term2ArrayC. This is stepwise through the sum frequencies. - DO J=1,InitInp%NStepWave2 - ! Calculate the frequency -- This is the sum frequency. - OmegaSum = J * InitInp%WaveDOmega + ! Outer loop to create the Term2ArrayC. This is stepwise through the sum frequencies. + DO J=1,InitInp%NStepWave2 + ! Calculate the frequency -- This is the sum frequency. + OmegaSum = J * InitInp%WaveDOmega - ! Set the \f$ H^+ \f$ term to zero before we start - TmpHPlusC = CMPLX(0.0_SiKi,0.0_SiKi) - ! Only perform calculations if the difference frequency is in the right range - IF ( (OmegaSum >= InitInp%WvLowCOffS) .AND. (OmegaSum <= InitInp%WvHiCOffS) ) THEN + ! Set the \f$ H^+ \f$ term to zero before we start + TmpHPlusC = CMPLX(0.0_SiKi,0.0_SiKi,SiKi) - !> Now do the inner sum. We are going to perform a sum up to the maximum frequency that we - !! can support (Nyquist frequency) for the given WaveDOmega and NStepWave2 (WaveOmegaMax = - !! NStepWave2 * WaveDOmega = Pi / WaveDT rad/second). Note that this means the largest diagonal - !! frequency we use is \f$ \omega = \Delta\omega * \f$ _NStepwave_/4. - !! So, we essentially end up running into the sampling limit. If we want higher frequency - !! terms, we need to use a smaller stepsize. - DO K=0,FLOOR(Real(J-1)/2.0_SiKi) + ! Only perform calculations if the difference frequency is in the right range + IF ( (OmegaSum >= InitInp%WvLowCOffS) .AND. (OmegaSum <= InitInp%WvHiCOffS) ) THEN - ! Calculate the frequency pair - Omega1 = K * InitInp%WaveDOmega - Omega2 = (J-K) * InitInp%WaveDOmega + !> Now do the inner sum. We are going to perform a sum up to the maximum frequency that we + !! can support (Nyquist frequency) for the given WaveDOmega and NStepWave2 (WaveOmegaMax = + !! NStepWave2 * WaveDOmega = Pi / WaveDT rad/second). Note that this means the largest diagonal + !! frequency we use is \f$ \omega = \Delta\omega * \f$ _NStepwave_/4. + !! So, we essentially end up running into the sampling limit. If we want higher frequency + !! terms, we need to use a smaller stepsize. - ! Find the wave amplitude at frequency omega. Remove the NStepWave2 normalization built into WaveElevC0 from Waves module - aWaveElevC1 = CMPLX( InitInp%WaveElevC0(1, K), InitInp%WaveElevC0(2, K)) / InitInp%NStepWave2 - aWaveElevC2 = CMPLX( InitInp%WaveElevC0(1,J-K), InitInp%WaveElevC0(2,J-K)) / InitInp%NStepWave2 + DO K=0,FLOOR(Real(J-1)/2.0_SiKi) - ! Set the (omega1,omega2,beta1,beta2) point we are looking for. - Coord4 = (/ Omega1, Omega2, InitInp%WaveDirArr(K), InitInp%WaveDirArr(J-K) /) + ! Calculate the frequency pair + Omega1 = K * InitInp%WaveDOmega + Omega2 = (J-K) * InitInp%WaveDOmega - ! get the interpolated value for F(omega1,omega2,beta1,beta2) --> QTF_Value - CALL WAMIT_Interp4D_Cplx( Coord4, TmpData4D, SumQTFData%Data4D%WvFreq1, SumQTFData%Data4D%WvFreq2, & - SumQTFData%Data4D%WvDir1, SumQTFData%Data4D%WvDir2, LastIndex4, QTF_Value, ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,'SumQTF_InitCalc') - IF (ErrStat >= AbortErrLev ) THEN - IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) - RETURN - ENDIF + ! Find the wave amplitude at frequency omega. Remove the NStepWave2 normalization built into WaveElevC0 from Waves module + aWaveElevC1 = CMPLX( InitInp%WaveElevC0(1, K), InitInp%WaveElevC0(2, K), SiKi ) / InitInp%NStepWave2 + aWaveElevC2 = CMPLX( InitInp%WaveElevC0(1,J-K), InitInp%WaveElevC0(2,J-K), SiKi ) / InitInp%NStepWave2 - ! Set the value of the first term in the frequency domain. - TmpHPlusC = TmpHPlusC + aWaveElevC1 * aWaveElevC2 * QTF_Value + ! Set the (omega1,omega2,beta1,beta2) point we are looking for. + Coord4 = (/ REAL(Omega1,SiKi), REAL(Omega2,SiKi), InitInp%WaveDirArr(K), InitInp%WaveDirArr(J-K) /) - ENDDO + ! Apply local Z rotation to heading angle (degrees) to put wave direction into the local (rotated) body frame + Coord4(3) = Coord4(3) - RotateZdegOffset + Coord4(4) = Coord4(4) - RotateZdegOffset + + ! get the interpolated value for F(omega1,omega2,beta1,beta2) --> QTF_Value + CALL WAMIT_Interp4D_Cplx( Coord4, TmpData4D, SumQTFData%Data4D%WvFreq1, SumQTFData%Data4D%WvFreq2, & + SumQTFData%Data4D%WvDir1, SumQTFData%Data4D%WvDir2, LastIndex4, QTF_Value, ErrStatTmp, ErrMsgTmp ) + CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) + IF (ErrStat >= AbortErrLev ) THEN + IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) + RETURN + ENDIF + + !-------------------------- + ! Phase shift due to offset + !-------------------------- + if (p%NBodyMod == 2) then + !> The phase shift due to an (x,y) offset for second order difference frequencies is of the form + !! \f$ exp[-\imath ( k(\omega_1) ( X cos(\beta(w_1)) + Y sin(\beta(w_1)) ) + !! - k(\omega_2) ( X cos(\beta(w_2)) + Y sin(\beta(w_2)) ) ) ]\f$ + ! NOTE: the phase shift applies to the aWaveElevC of the incoming wave. Including it here instead + ! of above is mathematically equivalent, but only because each frequency has only one wave + ! direction associated with it through the equal energy approach used in multidirectional waves. + + WaveNmbr1 = WaveNumber ( REAL(Omega1,SiKi), InitInp%Gravity, InitInp%WtrDpth ) ! SiKi returned + WaveNmbr2 = WaveNumber ( REAL(Omega2,SiKi), InitInp%Gravity, InitInp%WtrDpth ) ! SiKi returned + TmpReal1 = WaveNmbr1 * ( InitInp%PtfmRefxt(1)*cos(InitInp%WaveDirArr(K)*D2R) + InitInp%PtfmRefyt(1)*sin(InitInp%WaveDirArr(K)*D2R) ) + TmpReal2 = WaveNmbr2 * ( InitInp%PtfmRefxt(1)*cos(InitInp%WaveDirArr(J-K)*D2R) + InitInp%PtfmRefyt(1)*sin(InitInp%WaveDirArr(J-K)*D2R) ) + + ! Set the phase shift for the set of sum frequencies + PhaseShiftXY = CMPLX( cos(TmpReal1 + TmpReal2), -sin(TmpReal1 + TmpReal2) ) + + QTF_Value = QTF_Value*PhaseShiftXY + + endif ! Phaseshift for NBodyMod==2 + + ! Set the value of the first term in the frequency domain. + TmpHPlusC = TmpHPlusC + aWaveElevC1 * aWaveElevC2 * QTF_Value + + ENDDO + + ! Save the value from the summation. + Term2ArrayC(J,ThisDim) = TmpHPlusC + + ENDIF ! Check on the limits + + ENDDO ! Second term calculation -- frequency step on the sum frequency + ENDIF ! Load component to calculate + ENDDO ! ThisDim -- current dimension + + + !---------------------------------------------------- + ! Rotate back to global frame + !---------------------------------------------------- + + ! Set rotation + ! NOTE: RotateZMatrixT is the rotation from local to global. + RotateZMatrixT(:,1) = (/ cos(InitInp%PtfmRefztRot(IBody)), -sin(InitInp%PtfmRefztRot(IBody)) /) + RotateZMatrixT(:,2) = (/ sin(InitInp%PtfmRefztRot(IBody)), cos(InitInp%PtfmRefztRot(IBody)) /) + + ! Loop through all the frequencies + DO J=1,InitInp%NStepWave2 + + ! Apply the rotation to get back to global frame -- term 1 + Term1ArrayC(J,1:2) = MATMUL(RotateZMatrixT, Term1ArrayC(J,1:2)) + Term1ArrayC(J,4:5) = MATMUL(RotateZMatrixT, Term1ArrayC(J,4:5)) - ! Save the value from the summation. - Term2ArrayC(J) = TmpHPlusC + ! Apply the rotation to get back to global frame -- term 2 + Term2ArrayC(J,1:2) = MATMUL(RotateZMatrixT, Term2ArrayC(J,1:2)) + Term2ArrayC(J,4:5) = MATMUL(RotateZMatrixT, Term2ArrayC(J,4:5)) + ENDDO ! J=1,InitInp%NStepWave2 - ENDIF ! Check on the limits - ENDDO ! Second term calculation -- frequency step on the sum frequency + !---------------------------------------------------- + ! Apply the FFT to get time domain results + !---------------------------------------------------- + DO ThisDim=1,6 + Idx = (IBody-1)*6+ThisDim ! Now we apply the FFT to the result of the sum. - CALL ApplyFFT_cx( Term1Array(:), Term1ArrayC(:), FFT_Data, ErrStatTmp ) + 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.', & - ErrStat,ErrMsg,'SumQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) RETURN END IF ! Now we apply the FFT to the result of the sum. - CALL ApplyFFT_cx( Term2Array(:), Term2ArrayC(:), FFT_Data, ErrStatTmp ) + 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.', & - ErrStat,ErrMsg,'SumQTF_InitCalc') + ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) RETURN ENDIF ! Now we add the two terms together. The 0.5 multiplier on is because the double sided FFT was used. - DO J=0,InitInp%NStepWave-1 !bjj: Term1Array and Term2Array don't set the last element, so we can get over-flow errors here. SumQTFForce(InitInp%NStepWave,I) gets overwritten later, so I'm setting the array bounds to be -1. - SumQTFForce(J,I) = 0.5_SiKi*(REAL(Term1Array(J) + 2*Term2Array(J))) + DO J=0,InitInp%NStepWave-1 !bjj: Term1Array and Term2Array don't set the last element, so we can get over-flow errors here. SumQTFForce(InitInp%NStepWave,Idx) gets overwritten later, so Idx'm setting the array bounds to be -1. + SumQTFForce(J,Idx) = 0.5_SiKi*(REAL(Term1Array(J) + 2*Term2Array(J), SiKi)) ENDDO - ! Copy the last first term to the last so that it is cyclic - SumQTFForce(InitInp%NStepWave,I) = SumQTFForce(0,I) + ! Copy the last first term to the first so that it is cyclic + SumQTFForce(InitInp%NStepWave,Idx) = SumQTFForce(0,Idx) - ENDIF ! Load component to calculate - ENDDO + ENDDO ! ThisDim -- current dimension + ENDDO ! IBody -- current WAMIT body ! 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,'SumQTF_InitCalc') + CALL SetErrStat(ErrStatTmp,'Error occured while cleaning up after the FFTs.', ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpData4D)) DEALLOCATE(TmpData4D,STAT=ErrStatTmp) RETURN @@ -2684,12 +3067,13 @@ END SUBROUTINE SumQTF_InitCalc !! !! This subroutine also populates the InitOut and creates the filenames for each of the calculation types. !! - SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, DiffQTFData, SumQTFData, ErrStat, ErrMsg ) + SUBROUTINE CheckInitInput( InitInp, Interval, InitOut, p, MnDriftData, NewmanAppData, DiffQTFData, SumQTFData, ErrStat, ErrMsg ) IMPLICIT NONE ! Passed variables. TYPE(WAMIT2_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization routine + REAL(DbKi), INTENT(IN ) :: Interval !< Coupling interval in seconds: don't change it from the glue code provided value. TYPE(WAMIT2_InitOutputType), INTENT(INOUT) :: InitOut !< The output from the init routine TYPE(WAMIT2_ParameterType), INTENT( OUT) :: p !< The parameters @@ -2708,6 +3092,7 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff ! Temporary Error Variables INTEGER(IntKi) :: ErrStatTmp !< Temporary variable for the local error status CHARACTER(2048) :: ErrMsgTmp !< Temporary error message variable + CHARACTER(*), PARAMETER :: RoutineName = 'CheckInitInput' !> ## Subroutine contents @@ -2759,7 +3144,7 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff IF ( ( InitInp%MnDrift /= 0 .AND. InitInp%NewmanApp /= 0 ) .OR. & ( InitInp%DiffQTF /= 0 .AND. InitInp%NewmanApp /= 0 ) .OR. & ( InitInp%MnDrift /= 0 .AND. InitInp%DiffQTF /= 0 ) ) THEN - CALL SetErrStat( ErrID_Fatal, ' Only one of MnDrift, NewmanApp, or DiffQTF can be non-zero.', ErrStat, ErrMsg, 'CheckInitInput') + CALL SetErrStat( ErrID_Fatal, ' Only one of MnDrift, NewmanApp, or DiffQTF can be non-zero.', ErrStat, ErrMsg, RoutineName) END IF IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp @@ -2773,18 +3158,22 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff IF ( InitInp%MnDriftF ) THEN ! Should be false in this case, so if true there is a problem CALL SetErrStat( ErrID_Fatal, ' Programming error in call to WAMIT2_Init: '//NewLine// & ' MnDriftF flag should be set to false by calling program for MnDrift = 0.'//NewLine// & - ' --> This should have been checked by the calling program.',ErrStat, ErrMsg, 'CheckInitInput') + ' --> This should have been checked by the calling program.',ErrStat, ErrMsg, RoutineName) END IF ELSE IF( InitInp%MnDrift >= 7 .AND. InitInp%MnDrift <= 12 ) THEN ! Valid values IF ( .not. InitInp%MnDriftF ) THEN ! Should be true in this case, so if false there is a problem CALL SetErrStat( ErrID_Fatal, ' Programming error in call to WAMIT2_Init: '//NewLine// & ' MnDriftF flag should be set to true by calling program for MnDrift /= 0.'//NewLine// & - ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, 'CheckInitInput') + ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, RoutineName) + END IF + IF ( InitInp%NBody > 1 .AND. InitInp%MnDrift == 8 ) THEN + CALL SetErrStat( ErrID_Fatal, ' Mean drift calculation cannot be used with input file type 8 when more than 1 WAMIT body is present.', & + ErrStat, ErrMsg, RoutineName) END IF ELSE CALL SetErrStat( ErrID_Fatal, ' Programming Error in call to WAMIT2_Init: '//NewLine// & ' MnDrift can only have values of 0, 7, 8, 9, 10, 11, or 12. '//NewLine// & - ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, 'CheckInitInput') + ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, RoutineName) END IF IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp @@ -2797,21 +3186,23 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff IF ( InitInp%NewmanAppF ) THEN ! Should be false in this case, so if true there is a problem CALL SetErrStat( ErrID_Fatal, ' Programming error in call to WAMIT2_Init: '//NewLine// & ' NewmanAppF flag should be set to false by calling program for NewmanApp = 0.'//NewLine// & - ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, 'CheckInitInput') + ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, RoutineName) END IF ELSE IF( InitInp%NewmanApp >= 7 .AND. InitInp%NewmanApp <= 12 ) THEN ! Valid values IF ( InitInp%NewmanAppF .eqv. .FALSE. ) THEN ! Should be true in this case, so if false there is a problem CALL SetErrStat( ErrID_Fatal, ' Programming error in call to WAMIT2_Init: '//NewLine// & ' NewmanAppF flag should be set to true by calling program for NewmanApp /= 0.'//NewLine// & - ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, 'CheckInitInput') + ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, RoutineName) + END IF + IF ( InitInp%NBody > 1 .AND. InitInp%NewmanApp == 8 ) THEN + CALL SetErrStat( ErrID_Fatal, ' Newman''s approximation cannot be used with input file type 8 when more than 1 WAMIT body is present.', & + ErrStat, ErrMsg, RoutineName) END IF ELSE CALL SetErrStat( ErrID_Fatal, ' Programming Error in call to WAMIT2_Init: '//NewLine// & ' NewmanApp can only have values of 0, 7, 8, 9, 10, 11, or 12. '//NewLine// & - ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, 'CheckInitInput') + ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, RoutineName) END IF - - IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp RETURN @@ -2824,18 +3215,18 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff IF ( InitInp%DiffQTFF .eqv. .TRUE. ) THEN ! Should be false in this case, so if true there is a problem CALL SetErrStat( ErrID_Fatal, ' Programming error in call to WAMIT2_Init: '//NewLine// & ' DiffQTFF flag should be set to false by calling program for DiffQTF = 0.'//NewLine// & - ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, 'CheckInitInput') + ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, RoutineName) END IF ELSE IF( InitInp%DiffQTF >= 10 .AND. InitInp%DiffQTF <= 12 ) THEN ! Valid values IF ( InitInp%DiffQTFF .eqv. .FALSE. ) THEN ! Should be true in this case, so if false there is a problem CALL SetErrStat( ErrID_Fatal, ' Programming error in call to WAMIT2_Init: '//NewLine// & ' DiffQTFF flag should be set to true by calling program for DiffQTF /= 0.'//NewLine// & - ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, 'CheckInitInput') + ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, RoutineName) END IF ELSE CALL SetErrStat( ErrID_Fatal, ' Programming Error in call to WAMIT2_Init: '//NewLine// & ' DiffQTF can only have values of 0, 10, 11, or 12. '//NewLine// & - ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, 'CheckInitInput') + ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, RoutineName) END IF IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp @@ -2849,18 +3240,18 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff IF ( InitInp%SumQTFF .eqv. .TRUE. ) THEN ! Should be false in this case, so if true there is a problem CALL SetErrStat( ErrID_Fatal, ' Programming error in call to WAMIT2_Init: '//NewLine// & ' SumQTFF flag should be set to false by calling program for SumQTF = 0.'//NewLine// & - ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, 'CheckInitInput') + ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, RoutineName) END IF ELSE IF( InitInp%SumQTF >= 10 .AND. InitInp%SumQTF <= 12 ) THEN ! Valid values IF ( InitInp%SumQTFF .eqv. .FALSE. ) THEN ! Should be true in this case, so if false there is a problem CALL SetErrStat( ErrID_Fatal, ' Programming error in call to WAMIT2_Init: '//NewLine// & ' SumQTFF flag should be set to true by calling program for SumQTF /= 0.'//NewLine// & - ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, 'CheckInitInput') + ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, RoutineName) END IF ELSE CALL SetErrStat( ErrID_Fatal, ' Programming Error in call to WAMIT2_Init: '//NewLine// & ' SumQTF can only have values of 0, 10, 11, or 12. '//NewLine// & - ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, 'CheckInitInput') + ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, RoutineName) END IF IF ( ErrStat >= AbortErrLev ) THEN CALL CleanUp @@ -2881,7 +3272,7 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff IF ( ( InitInp%WvHiCOffD < InitInp%WvLowCOffD ) .OR. ( InitInp%WvLowCOffD < 0.0 ) ) THEN CALL SetErrStat( ErrID_Fatal, ' Programming Error in call to WAMIT2_Init: '//NewLine// & ' WvHiCOffD must be larger than WvLowCOffD. Both must be positive.'// & - ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, 'CheckInitInput') + ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, RoutineName) CALL CleanUp RETURN END IF @@ -2894,7 +3285,7 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff IF ( ( InitInp%WvHiCOffS < InitInp%WvLowCOffS ) .OR. ( InitInp%WvLowCOffS < 0.0 ) ) THEN CALL SetErrStat( ErrID_Fatal, ' Programming Error in call to WAMIT2_Init: '//NewLine// & ' WvHiCOffS must be larger than WvLowCOffS. Both must be positive.'// & - ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, 'CheckInitInput') + ' --> This should have been checked by the calling program.', ErrStat, ErrMsg, RoutineName) CALL CleanUp RETURN END IF @@ -2923,7 +3314,7 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff ENDIF IF ( TmpFileExist .eqv. .FALSE. ) THEN CALL SetErrStat( ErrID_Fatal, ' Cannot find the WAMIT file '//TRIM(MnDriftData%Filename)// & - ' required by the MnDrift option.', ErrStat, ErrMsg, 'CheckInitInput') + ' required by the MnDrift option.', ErrStat, ErrMsg, RoutineName) CALL CLeanup RETURN END IF @@ -2947,7 +3338,7 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff ENDIF IF ( TmpFileExist .eqv. .FALSE. ) THEN CALL SetErrStat( ErrID_Fatal, ' Cannot find the WAMIT file '//TRIM(NewmanAppData%Filename)// & - ' required by the NewmanApp option.', ErrStat, ErrMsg, 'CheckInitInput') + ' required by the NewmanApp option.', ErrStat, ErrMsg, RoutineName) CALL CleanUp RETURN END IF @@ -2964,7 +3355,7 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff INQUIRE( file=TRIM(DiffQTFData%Filename), exist=TmpFileExist ) IF ( TmpFileExist .eqv. .FALSE. ) THEN CALL SetErrStat( ErrID_Fatal, ' Cannot find the WAMIT file '//TRIM(DiffQTFData%Filename)// & - ' required by the DiffQTF option.', ErrStat, ErrMsg, 'CheckInitInput') + ' required by the DiffQTF option.', ErrStat, ErrMsg, RoutineName) CALL CleanUp RETURN END IF @@ -2981,7 +3372,7 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff INQUIRE( file=TRIM(SumQTFData%Filename), exist=TmpFileExist ) IF ( .not. TmpFileExist ) THEN CALL SetErrStat( ErrID_Fatal, ' Cannot find the WAMIT file '//TRIM(SumQTFData%Filename)// & - ' required by the SumQTF option.', ErrStat, ErrMsg, 'CheckInitInput') + ' required by the SumQTF option.', ErrStat, ErrMsg, RoutineName) CALL CleanUp RETURN END IF @@ -3000,7 +3391,7 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff CALL SetErrStat( ErrID_Fatal, ' Programming error in call to WAMIT2_Init:'//NewLine// & ' --> Expected array for WaveElevC0 to be of size 2x'//TRIM(Num2LStr(InitInp%NStepWave2 + 1))// & ' (2x(NStepWave2+1)), but instead received array of size '// & - TRIM(Num2LStr(SIZE(InitInp%WaveElevC0,1)))//'x'//TRIM(Num2LStr(SIZE(InitInp%WaveElevC0,2)))//'.', ErrStat, ErrMsg, 'CheckInitInput') + TRIM(Num2LStr(SIZE(InitInp%WaveElevC0,1)))//'x'//TRIM(Num2LStr(SIZE(InitInp%WaveElevC0,2)))//'.', ErrStat, ErrMsg, RoutineName) CALL CleanUp RETURN END IF @@ -3022,14 +3413,20 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff p%DT = Interval ! Timestep from calling program - ! Allocate array for the WaveTime information -- array of times to generate output for. NOTE: can't use MOVE_ALLOC since InitInp is intent in. - CALL AllocAry( p%WaveTime, SIZE(InitInp%WaveTime,1), 'array to hold WaveTime', ErrStatTmp, ErrMsgTmp ) - IF ( ErrStatTmp /= ErrID_None ) THEN - CALL SetErrStat( ErrID_Fatal, ErrMsgTmp, ErrStat, ErrMsg, 'CheckInitInput') - RETURN - ENDIF - p%WaveTime = InitInp%WaveTime + !-------------------------------------------------------------------------------- + !> 3. WAMIT body related information + !-------------------------------------------------------------------------------- + + p%NBody = InitInp%NBody ! Number of bodies WAMIT2 sees + p%NBodyMod = InitInp%NBodyMod ! How multiple bodys are treated + + ! This module's implementation requires that if NBodyMod = 2 or 3, then there is one instance of a WAMIT module for each body, therefore, HydroDyn may have NBody > 1, but this WAMIT module will have NBody = 1 + if ( (p%NBodyMod > 1) .and. (p%NBody > 1) ) then + CALL SetErrStat( ErrID_Fatal, "DEVELOPER ERROR: If NBodyMod = 2 or 3, then NBody for the a WAMIT2 object must be equal to 1", ErrStat, ErrMsg, RoutineName) + CALL CleanUp + return + end if !-------------------------------------------------------------------------------- @@ -3058,43 +3455,18 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff IF (InitInp%MnDriftF) THEN ! if the flag is true, we are doing this calculation IF (InitInp%MnDrift == 8) THEN ! the .8 files are not complete - p%MnDriftDims(1) = InitInp%PtfmSgF2 - p%MnDriftDims(2) = InitInp%PtfmSwF2 + p%MnDriftDims(1) = .TRUE. + p%MnDriftDims(2) = .TRUE. p%MnDriftDims(3) = .FALSE. ! the .8 files don't contain this dimension p%MnDriftDims(4) = .FALSE. ! the .8 files don't contain this dimension p%MnDriftDims(5) = .FALSE. ! the .8 files don't contain this dimension - p%MnDriftDims(6) = InitInp%PtfmYF2 - !> Now warn me that we changed the calculations in this case... - IF (InitInp%PtfmHvF2) THEN - CALL SetErrStat( ErrID_Warn, ' WARNING: the .8 WAMIT output file does not contain information for second order forces '//& - 'in the heave direction. No second order heave forces will be calculated within the mean drift calculations.'//NewLine, & - ErrStat, ErrMsg, 'CheckInitInput') - ENDIF - IF (InitInp%PtfmRF2) THEN - CALL SetErrStat( ErrID_Warn, ' WARNING: the .8 WAMIT output file does not contain information for second order forces '//& - 'for platform roll. No second order roll forces will be calculated within the mean drift calculations.'//NewLine, & - ErrStat, ErrMsg, 'CheckInitInput') - ENDIF - IF (InitInp%PtfmPF2) THEN - CALL SetErrStat( ErrID_Warn, ' WARNING: the .8 WAMIT output file does not contain information for second order forces '//& - 'for platform pitch. No second order pitching forces will be calculated within the mean drift calculations.'//NewLine, & - ErrStat, ErrMsg, 'CheckInitInput') - ENDIF + p%MnDriftDims(6) = .TRUE. ELSE - p%MnDriftDims(1) = InitInp%PtfmSgF2 - p%MnDriftDims(2) = InitInp%PtfmSwF2 - p%MnDriftDims(3) = InitInp%PtfmHvF2 - p%MnDriftDims(4) = InitInp%PtfmRF2 - p%MnDriftDims(5) = InitInp%PtfmPF2 - p%MnDriftDims(6) = InitInp%PtfmYF2 + p%MnDriftDims = .TRUE. ENDIF ELSE p%MnDriftDims(:) = .FALSE. ! Set all dimensions to false unless we are actually calculating something ENDIF - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp - RETURN - ENDIF @@ -3102,63 +3474,27 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff IF (InitInp%NewmanAppF) THEN ! if the flag is true, we are doing this calculation IF (InitInp%NewmanApp == 8) THEN ! the .8 files are not complete - p%NewmanAppDims(1) = InitInp%PtfmSgF2 - p%NewmanAppDims(2) = InitInp%PtfmSwF2 + p%NewmanAppDims(1) = .TRUE. + p%NewmanAppDims(2) = .TRUE. p%NewmanAppDims(3) = .FALSE. ! the .8 files don't contain this dimension p%NewmanAppDims(4) = .FALSE. ! the .8 files don't contain this dimension p%NewmanAppDims(5) = .FALSE. ! the .8 files don't contain this dimension - p%NewmanAppDims(6) = InitInp%PtfmYF2 - !> Now warn me that we changed the calculations in this case... - IF (InitInp%PtfmHvF2) THEN - CALL SetErrStat( ErrID_Warn, ' Warning: the .8 WAMIT output file does not contain information that can be used for '//& - 'second order force calculations of platform heave.'//NewLine// & - " No second order heave forces will be calculated within the Newman's Approximation calculations.", ErrStat, ErrMsg, 'CheckInitInput') - ENDIF - IF (InitInp%PtfmRF2) THEN - CALL SetErrStat( ErrID_Warn, ' Warning: the .8 WAMIT output file does not contain information that can be used for '//& - 'second order force calculations of platform roll.'//NewLine// & - " No second order roll forces will be calculated within the Newman's Approximation calculations.", ErrStat, ErrMsg, 'CheckInitInput') - ENDIF - IF (InitInp%PtfmPF2) THEN - CALL SetErrStat( ErrID_Warn, ' Warning: the .8 WAMIT output file does not contain information that can be used for '//& - 'second order force calculations of platform pitch.'//NewLine// & - " No second order pitching forces will be calculated within the Newman's Approximation calculations.", & - ErrStat, ErrMsg, 'CheckInitInput') - ENDIF + p%NewmanAppDims(6) = .TRUE. ELSE - p%NewmanAppDims(1) = InitInp%PtfmSgF2 - p%NewmanAppDims(2) = InitInp%PtfmSwF2 - p%NewmanAppDims(3) = InitInp%PtfmHvF2 - p%NewmanAppDims(4) = InitInp%PtfmRF2 - p%NewmanAppDims(5) = InitInp%PtfmPF2 - p%NewmanAppDims(6) = InitInp%PtfmYF2 + p%NewmanAppDims = .TRUE. ENDIF ELSE p%NewmanAppDims(:) = .FALSE. ! Set all dimensions to false unless we are actually calculating something ENDIF - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp - RETURN - ENDIF !> 3. For the Difference QTF method, IF (InitInp%DiffQTFF) THEN ! if the flag is true, we are doing this calculation - p%DiffQTFDims(1) = InitInp%PtfmSgF2 - p%DiffQTFDims(2) = InitInp%PtfmSwF2 - p%DiffQTFDims(3) = InitInp%PtfmHvF2 - p%DiffQTFDims(4) = InitInp%PtfmRF2 - p%DiffQTFDims(5) = InitInp%PtfmPF2 - p%DiffQTFDims(6) = InitInp%PtfmYF2 + p%DiffQTFDims = .TRUE. ! Also set the MnDrift flags. We will be passing data from the DiffQTF method to the MnDrift method for the first term - p%MnDriftDims(1) = InitInp%PtfmSgF2 - p%MnDriftDims(2) = InitInp%PtfmSwF2 - p%MnDriftDims(3) = InitInp%PtfmHvF2 - p%MnDriftDims(4) = InitInp%PtfmRF2 - p%MnDriftDims(5) = InitInp%PtfmPF2 - p%MnDriftDims(6) = InitInp%PtfmYF2 + p%MnDriftDims = .TRUE. ELSE p%DiffQTFDims(:) = .FALSE. ! Set all dimensions to false unless we are actually calculating something ENDIF @@ -3167,12 +3503,7 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff !> 4. For the Summation QTF method, IF (InitInp%SumQTFF) THEN ! if the flag is true, we are doing this calculation - p%SumQTFDims(1) = InitInp%PtfmSgF2 - p%SumQTFDims(2) = InitInp%PtfmSwF2 - p%SumQTFDims(3) = InitInp%PtfmHvF2 - p%SumQTFDims(4) = InitInp%PtfmRF2 - p%SumQTFDims(5) = InitInp%PtfmPF2 - p%SumQTFDims(6) = InitInp%PtfmYF2 + p%SumQTFDims = .TRUE. ELSE p%SumQTFDims(:) = .FALSE. ! Set all dimensions to false unless we are actually calculating something ENDIF @@ -3202,18 +3533,18 @@ SUBROUTINE CheckInitInput( InitInp, InitOut, p, MnDriftData, NewmanAppData, Diff !-------------------------------------------------------------------------------- ! Allocate array for the WaveExtcn2. - ALLOCATE( p%WaveExctn2(0:InitInp%NStepWave,6), STAT=ErrStatTmp) + ALLOCATE( p%WaveExctn2(0:InitInp%NStepWave,6*p%NBody), STAT=ErrStatTmp) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,'Cannot allocate array p%WaveExctn2 to store '// & 'the 2nd order force data.', ErrStat,ErrMsg,'CheckInitInp') IF (ErrStat >= AbortErrLev ) RETURN - - !-------------------------------------------------------------------------------- - !> FAST channel output - !-------------------------------------------------------------------------------- - - p%NumOuts = InitInp%NumOuts - p%NumOutAll = InitInp%NumOutAll +! +! !-------------------------------------------------------------------------------- +! !> FAST channel output +! !-------------------------------------------------------------------------------- +! +! p%NumOuts = InitInp%NumOuts +! p%NumOutAll = InitInp%NumOutAll END SUBROUTINE CheckInitInput @@ -3238,11 +3569,12 @@ END SUBROUTINE CheckInitInput !! !! At the end of all this, we check the data for completeness and set the flags accordingly. !! - SUBROUTINE Read_DataFile3D( Filename3D, Data3D, ErrStat, Errmsg ) + SUBROUTINE Read_DataFile3D( InitInp, Filename3D, Data3D, ErrStat, Errmsg ) IMPLICIT NONE ! Passed variables. + TYPE(WAMIT2_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization routine CHARACTER(*), INTENT(IN ) :: Filename3D !< Name of the file containing the 3D data TYPE(W2_InitData3D_Type), INTENT(INOUT) :: Data3D !< 3D QTF data INTEGER(IntKi), INTENT( OUT) :: ErrStat !< The error value @@ -3300,7 +3632,6 @@ SUBROUTINE Read_DataFile3D( Filename3D, Data3D, ErrStat, Errmsg ) ErrStatTmp = ErrID_None ErrMsg = '' ErrMsgTmp = '' - Data3D%DataIsSparse = .TRUE. ! Assume the data is sparse, then change this after checking on the dimensions of interest. HaveZeroFreq1 = .FALSE. ! If we find a zero frequency, we will set this to true @@ -3493,7 +3824,7 @@ SUBROUTINE Read_DataFile3D( Filename3D, Data3D, ErrStat, Errmsg ) ELSE IF ( RawData3D(I,1) < 0 ) THEN ! Leave it alone. We will have to fix it afterwards. ELSE - RawData3D(I,1) = TwoPi/RawData3D(I,1) ! First column is Tau1 + RawData3D(I,1) = TwoPi_S/RawData3D(I,1) ! First column is Tau1 ENDIF ENDDO @@ -3595,9 +3926,14 @@ SUBROUTINE Read_DataFile3D( Filename3D, Data3D, ErrStat, Errmsg ) CALL UniqueRealValues( RawData3D(:,4), TmpRealArr, K, ErrStatTmp,ErrMsgTmp ) CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) - ! If the value of K is more than 6, we have some serious issues - IF ( K > 6 ) CALL SetErrStat( ErrID_Fatal, ' More than 6 load components found in column 4 of '// & - TRIM(Filename3D)//'.', ErrStat,ErrMsg,RoutineName) + ! Now figure out how many bodies there are. Each body will have up to 6 components. The component + ! column can be up to 6*N where N is the number of bodies in the file. We will assume that we don't + ! skip groups of bodies. + Data3D%NumBodies = ceiling((maxval(TmpRealArr)-0.1_ReKi) / 6.0_ReKi) ! Account for any uncertainty in the number + IF ( Data3D%NumBodies < 1 ) CALL SetErrStat( ErrID_Fatal, ' No WAMIT bodies found (no positive load component numbers in column 4) in '// & + TRIM(Filename3D)//'.', ErrStat,ErrMsg,RoutineName ) + IF ( Data3D%NumBodies > 1 ) CALL SetErrStat( ErrID_Info, ' Found data for '//TRIM(Num2LStr(Data3D%NumBodies))//' WAMIT bodies in '// & + TRIM(Filename3D)//'.', ErrStat,ErrMsg,RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN IF (ALLOCATED(TmpRealArr)) DEALLOCATE(TmpRealArr,STAT=ErrStatTmp) IF (ALLOCATED(RawData3D)) DEALLOCATE(RawData3D,STAT=ErrStatTmp) @@ -3608,13 +3944,21 @@ SUBROUTINE Read_DataFile3D( Filename3D, Data3D, ErrStat, Errmsg ) RETURN ENDIF + + ! Now that we know how many bodies are in the file, allocate the size of the arrays + CALL AllocAry( Data3D%DataIsSparse, 6*Data3D%NumBodies, ' Array for tracking which dimension indices are sparsely populated', ErrStatTmp, ErrMsgTmp ) + CALL AllocAry( Data3D%LoadComponents, 6*Data3D%NumBodies, ' Array for tracking which dimension indices contain information', ErrStatTmp, ErrMsgTmp ) + Data3D%DataIsSparse = .TRUE. ! Assume the data is sparse, then change this after checking on the dimensions of interest. + + ! Now check the values we got back and set the LoadComponents flags for those with data. The ! load component direction must be between 1 and 6 (translational: 1,2,3; rotational: 4,5,6). Data3D%LoadComponents = .FALSE. DO I=1,K - IF ( NINT(TmpRealArr(I)) < 1 .OR. NINT(TmpRealArr(K)) > 6 ) THEN + IF ( NINT(TmpRealArr(I)) < 1 .OR. NINT(TmpRealArr(K)) > 6*Data3D%NumBodies ) THEN CALL SetErrStat( ErrID_Fatal, ' Load components listed in column 4 of '//TRIM(Filename3D)// & - ' must be between 1 and 6.', ErrStat,ErrMsg,RoutineName) + ' must be between 1 and '//TRIM(Num2LStr(6*Data3D%NumBodies))//' for '//TRIM(Num2LStr(Data3D%NumBodies))// & + ' WAMIT bodies.', ErrStat,ErrMsg,RoutineName) IF (ALLOCATED(TmpRealArr)) DEALLOCATE(TmpRealArr,STAT=ErrStatTmp) IF (ALLOCATED(RawData3D)) DEALLOCATE(RawData3D,STAT=ErrStatTmp) IF (ALLOCATED(RawData3DTmp)) DEALLOCATE(RawData3DTmp,STAT=ErrStatTmp) @@ -3634,9 +3978,9 @@ SUBROUTINE Read_DataFile3D( Filename3D, Data3D, ErrStat, Errmsg ) ! Now we need to figure out if the zero frequency was given in the file. If so, we change NumWvFreq1 to - ! NumWvFreq1+2. If not, change to NumWvFreq1+4. We will add on the inifinite frequency value and + ! NumWvFreq1+2. If not, change to NumWvFreq1+4. We will add on the inifinite frequency value and ! zero out all values not in the input frequency range. The inifinite frequency value will be set to HUGE - ! and we'll add/subtract epsilon to the first non-zero frequency entered so that we can achieve a step + ! and we'll add/subtract epsilon to the first non-zero frequency entered so that we can achieve a step ! change for zeroing the values outside the input frequency range. IF (HaveZeroFreq1) THEN Data3D%NumWvFreq1 = Data3D%NumWvFreq1+2 @@ -3666,12 +4010,12 @@ SUBROUTINE Read_DataFile3D( Filename3D, Data3D, ErrStat, Errmsg ) ! Populate the wave frequencies with what we read in Data3D%WvFreq1( WvFreq1LoIdx:WvFreq1HiIdx ) = TmpWvFreq1 - ! If no zero frequency was supplied, add the two points for step-change before first entered frequency + ! If no zero frequency was supplied, add the two points for step-change before first entered frequency IF ( .NOT. HaveZeroFreq1) THEN Data3D%WvFreq1( 1 ) = 0.0_SiKi Data3D%WvFreq1( 2 ) = MAX( TmpWvFreq1(1) - 10.0_SiKi*EPSILON(0.0_SiKi), 0.0_SiKi ) ! make sure the Frequencies are still monotonically increasing ENDIF - + ! add the two points for step-change after last entered frequency Data3D%WvFreq1( Data3D%NumWvFreq1-1 ) = Data3D%WvFreq1(Data3D%NumWvFreq1-2) + 10.0_SiKi*EPSILON(0.0_SiKi) Data3D%WvFreq1( Data3D%NumWvFreq1 ) = HUGE(1.0_SiKi)/5 ! floating overflow occurs later with arithmetic so I divided by a small constant @@ -3834,7 +4178,7 @@ SUBROUTINE Read_DataFile3D( Filename3D, Data3D, ErrStat, Errmsg ) ! Store the data after dimensionalizing Data3D%DataSet( TmpCoord(1), TmpCoord(2), TmpCoord(3), TmpCoord(4) ) = & - InitInp%RhoXg * InitInp%WAMITULEN**K * CMPLX(RawData3D(I,7),RawData3D(I,8)) + REAL(InitInp%RhoXg * InitInp%WAMITULEN**K,SiKi) * CMPLX(RawData3D(I,7),RawData3D(I,8),SiKi) ! Set flag indicating that this value has been inserted. Data3D%DataMask( TmpCoord(1), TmpCoord(2), TmpCoord(3), TmpCoord(4) ) = .TRUE. @@ -3857,7 +4201,7 @@ SUBROUTINE Read_DataFile3D( Filename3D, Data3D, ErrStat, Errmsg ) !! to be performed only when \f$ \omega_1 = \omega_2 \f$. ! Loop over the wave components, but only perform calculations on the ones that have values - DO L=1,6 + DO L=1,6*Data3D%NumBodies IF (Data3D%LoadComponents(L)) THEN ! Only do this for the load components that exist DO I=1,Data3D%NumWvFreq1 ! Frequencies @@ -3897,19 +4241,19 @@ SUBROUTINE Read_DataFile3D( Filename3D, Data3D, ErrStat, Errmsg ) !---------------------------------------------------------------------------------- - !> We added two frequencies for the \f$ omega = 0 \f$ term if it did not exist, + !> We added two frequencies for the \f$ omega = 0 \f$ term if it did not exist, !! and added two frequencies for the infinite frequency term on the end of the array, - !! to create step changes outside the entered frequency ranges. We need to populate + !! to create step changes outside the entered frequency ranges. We need to populate !! the these new terms (set to zero). !---------------------------------------------------------------------------------- IF (.NOT. HaveZeroFreq1) THEN Data3D%DataSet( 1:2,:,:,:) = CMPLX(0.0_SiKi,0.0_SiKi) ! Set the values to zero for everything before entered frequency range Data3D%DataMask(1:2,:,:,:) = .TRUE. ! Set the mask for these first two frequencies - ENDIF + ENDIF Data3D%DataSet( Data3D%NumWvFreq1-1:Data3D%NumWvFreq1,:,:,:) = CMPLX(0.0_SiKi,0.0_SiKi) ! Set the values for the last two frequencies to zero (everything higher than the last non-infinite frequency) - Data3D%DataMask(Data3D%NumWvFreq1-1:Data3D%NumWvFreq1,:,:,:) = .TRUE. ! Set the mask for the last two frequencies - + Data3D%DataMask(Data3D%NumWvFreq1-1:Data3D%NumWvFreq1,:,:,:) = .TRUE. ! Set the mask for the last two frequencies + !---------------------------------------------------------------------------------- !> Find out if the data is sparse or full. Verification that the requested component @@ -3918,7 +4262,7 @@ SUBROUTINE Read_DataFile3D( Filename3D, Data3D, ErrStat, Errmsg ) !! for only the values of k that have data in them. !---------------------------------------------------------------------------------- - DO L=1,6 ! Loop over force component directions + DO L=1,6*Data3D%NumBodies ! Loop over force component directions TmpSparseFlag = .FALSE. ! Change this to true if any empty values are found IF (Data3D%LoadComponents(L)) THEN ! Only if we found data for that component DO I=1,Data3D%NumWvFreq1 @@ -3975,11 +4319,12 @@ END SUBROUTINE Read_DataFile3D !! !! At the end of all this, we check the data for completeness and set the flags accordingly. !! - SUBROUTINE Read_DataFile4D( Filename4D, Data4D, ErrStat, Errmsg ) + SUBROUTINE Read_DataFile4D( InitInp, Filename4D, Data4D, ErrStat, Errmsg ) IMPLICIT NONE ! Passed variables. + TYPE(WAMIT2_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization routine CHARACTER(*), INTENT(IN ) :: Filename4D !< Name of the file containing the 4D data TYPE(W2_InitData4D_Type), INTENT(INOUT) :: Data4D !< 4D QTF data INTEGER(IntKi), INTENT( OUT) :: ErrStat !< The error value @@ -4044,7 +4389,6 @@ SUBROUTINE Read_DataFile4D( Filename4D, Data4D, ErrStat, Errmsg ) ErrStatTmp = ErrID_None ErrMsg = '' ErrMsgTmp = '' - Data4D%DataIsSparse = .TRUE. ! Assume the data is sparse, then change this after checking on the dimensions of interest. HaveZeroFreq1 = .FALSE. ! If we find a zero frequency, we will set this to true HaveZeroFreq2 = .FALSE. ! If we find a zero frequency, we will set this to true @@ -4240,14 +4584,14 @@ SUBROUTINE Read_DataFile4D( Filename4D, Data4D, ErrStat, Errmsg ) ELSE IF ( RawData4D(I,1) < 0 ) THEN ! Leave it alone. We will have to fix it afterwards. ELSE - RawData4D(I,1) = TwoPi/RawData4D(I,1) ! First column is Tau1 + RawData4D(I,1) = TwoPi_S/RawData4D(I,1) ! First column is Tau1 ENDIF IF ( EqualRealNos(RawData4D(I,2), 0.0_SiKi) ) THEN ! Leave it alone. We will have to fix it afterwards. ELSE IF ( RawData4D(I,2) < 0 ) THEN ! Leave it alone. We will have to fix it afterwards. ELSE - RawData4D(I,2) = TwoPi/RawData4D(I,2) ! First column is Tau2 + RawData4D(I,2) = TwoPi_S/RawData4D(I,2) ! First column is Tau2 ENDIF ENDDO @@ -4371,29 +4715,42 @@ SUBROUTINE Read_DataFile4D( Filename4D, Data4D, ErrStat, Errmsg ) ! Find out which load components are actually in use CALL UniqueRealValues( RawData4D(:,5), TmpRealArr, K, ErrStatTmp,ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) - ! If the value of K is more than 6, we have some serious issues - IF ( K > 6 ) CALL SetErrStat( ErrID_Fatal, ' More than 6 load components found in column 4 of '// & - TRIM(Filename4D)//'.', ErrStat,ErrMsg,RoutineName) + ! Now figure out how many bodies there are. Each body will have up to 6 components. The component + ! column can be up to 6*N where N is the number of bodies in the file. We will assume that we don't + ! skip groups of bodies. + Data4D%NumBodies = ceiling((maxval(TmpRealArr)-0.1_ReKi) / 6.0_ReKi) ! Account for any uncertainty in the number + IF ( Data4D%NumBodies < 1 ) CALL SetErrStat( ErrID_Fatal, ' No WAMIT bodies found (no positive load component numbers in column 4) in '// & + TRIM(Filename4D)//'.', ErrStat,ErrMsg,RoutineName ) + IF ( Data4D%NumBodies > 1 ) CALL SetErrStat( ErrID_Info, ' Found data for '//TRIM(Num2LStr(Data4D%NumBodies))//' WAMIT bodies in '// & + TRIM(Filename4D)//'.', ErrStat,ErrMsg,RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN + IF (ALLOCATED(TmpRealArr)) DEALLOCATE(TmpRealArr,STAT=ErrStatTmp) IF (ALLOCATED(RawData4D)) DEALLOCATE(RawData4D,STAT=ErrStatTmp) IF (ALLOCATED(RawData4DTmp)) DEALLOCATE(RawData4DTmp,STAT=ErrStatTmp) - IF (ALLOCATED(TmpRealArr)) DEALLOCATE(TmpRealArr,STAT=ErrStatTmp) IF (ALLOCATED(TmpDataRow)) DEALLOCATE(TmpDataRow,STAT=ErrStatTmp) IF (ALLOCATED(TmpWvFreq1)) DEALLOCATE(TmpWvFreq1,STAT=ErrStatTmp) - IF (ALLOCATED(TmpWvFreq2)) DEALLOCATE(TmpWvFreq2,STAT=ErrStatTmp) CALL CleanUp RETURN ENDIF + + ! Now that we know how many bodies are in the file, allocate the size of the arrays + CALL AllocAry( Data4D%DataIsSparse, 6*Data4D%NumBodies, ' Array for tracking which dimension indices are sparsely populated', ErrStatTmp, ErrMsgTmp ) + CALL AllocAry( Data4D%LoadComponents, 6*Data4D%NumBodies, ' Array for tracking which dimension indices contain information', ErrStatTmp, ErrMsgTmp ) + Data4D%DataIsSparse = .TRUE. ! Assume the data is sparse, then change this after checking on the dimensions of interest. + + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) + + ! Now check the values we got back and set the LoadComponents flags for those with data. The ! load component direction must be between 1 and 6 (translational: 1,2,3; rotational: 4,5,6). Data4D%LoadComponents = .FALSE. DO I=1,K - IF ( NINT(TmpRealArr(I)) < 1 .OR. NINT(TmpRealArr(K)) > 6 ) THEN + IF ( NINT(TmpRealArr(I)) < 1 .OR. NINT(TmpRealArr(K)) > 6*Data4D%NumBodies ) THEN CALL SetErrStat( ErrID_Fatal, ' Load components listed in column 4 of '//TRIM(Filename4D)// & - ' must be between 1 and 6.', ErrStat,ErrMsg,RoutineName) + ' must be between 1 and '//TRIM(Num2LStr(6*Data4D%NumBodies))//' for '//TRIM(Num2LStr(Data4D%NumBodies))// & + ' WAMIT bodies.', ErrStat,ErrMsg,RoutineName) IF (ALLOCATED(RawData4D)) DEALLOCATE(RawData4D,STAT=ErrStatTmp) IF (ALLOCATED(RawData4DTmp)) DEALLOCATE(RawData4DTmp,STAT=ErrStatTmp) IF (ALLOCATED(TmpRealArr)) DEALLOCATE(TmpRealArr,STAT=ErrStatTmp) @@ -4412,9 +4769,9 @@ SUBROUTINE Read_DataFile4D( Filename4D, Data4D, ErrStat, Errmsg ) ! Now we need to figure out if the zero frequency was given in the file. If so, we change NumWvFreq1 to - ! NumWvFreq1+2. If not, change to NumWvFreq1+4. We will add on the inifinite frequency value and + ! NumWvFreq1+2. If not, change to NumWvFreq1+4. We will add on the inifinite frequency value and ! zero out all values not in the input frequency range. The inifinite frequency value will be set to HUGE - ! and we'll add/subtract epsilon to the first non-zero frequency entered so that we can achieve a step + ! and we'll add/subtract epsilon to the first non-zero frequency entered so that we can achieve a step ! change for zeroing the values outside the input frequency range. IF (HaveZeroFreq1) THEN Data4D%NumWvFreq1 = Data4D%NumWvFreq1+2 @@ -4475,12 +4832,12 @@ SUBROUTINE Read_DataFile4D( Filename4D, Data4D, ErrStat, Errmsg ) ! Populate the wave frequencies with what we read in Data4D%WvFreq1( WvFreq1LoIdx:WvFreq1HiIdx ) = TmpWvFreq1 - ! If no zero frequency was supplied, add the two points for step-change before first entered frequency + ! If no zero frequency was supplied, add the two points for step-change before first entered frequency IF ( .NOT. HaveZeroFreq1) THEN Data4D%WvFreq1( 1 ) = 0.0_SiKi Data4D%WvFreq1( 2 ) = MAX( TmpWvFreq1(1) - 10.0_SiKi*EPSILON(0.0_SiKi), 0.0_SiKi ) ! make sure the Frequencies are still monotonically increasing ENDIF - + ! add the two points for step-change after last entered frequency Data4D%WvFreq1( Data4D%NumWvFreq1-1 ) = Data4D%WvFreq1(Data4D%NumWvFreq1-2) + 10.0_SiKi*EPSILON(0.0_SiKi) Data4D%WvFreq1( Data4D%NumWvFreq1 ) = HUGE(1.0_SiKi)/5 ! floating overflow occurs later with arithmetic so I divided by a small constant @@ -4490,12 +4847,12 @@ SUBROUTINE Read_DataFile4D( Filename4D, Data4D, ErrStat, Errmsg ) ! Populate the wave frequencies with what we read in Data4D%WvFreq2( WvFreq2LoIdx:WvFreq2HiIdx ) = TmpWvFreq2 - ! If no zero frequency was supplied, add the two points for step-change before first entered frequency + ! If no zero frequency was supplied, add the two points for step-change before first entered frequency IF ( .NOT. HaveZeroFreq2) THEN Data4D%WvFreq2( 1 ) = 0.0_SiKi Data4D%WvFreq2( 2 ) = MAX( TmpWvFreq2(1) - 10.0_SiKi*EPSILON(0.0_SiKi), 0.0_SiKi ) ! make sure the Frequencies are still monotonically increasing ENDIF - + ! add the two points for step-change after last entered frequency Data4D%WvFreq2( Data4D%NumWvFreq2-1 ) = Data4D%WvFreq2(Data4D%NumWvFreq2-2) + 10.0_SiKi*EPSILON(0.0_SiKi) Data4D%WvFreq2( Data4D%NumWvFreq2 ) = HUGE(1.0_SiKi)/5 ! floating overflow occurs later with arithmetic so I divided by a small constant @@ -4583,7 +4940,7 @@ SUBROUTINE Read_DataFile4D( Filename4D, Data4D, ErrStat, Errmsg ) CALL CleanUp RETURN ENDIF - TmpCoord(1) = TmpCoord(1) + ( WvFreq1LoIdx - 1 ) ! shift to the point in the Data3D%WvFreq1 array by adding the zero frequency step function + TmpCoord(1) = TmpCoord(1) + ( WvFreq1LoIdx - 1 ) ! shift to the point in the Data4D%WvFreq1 array by adding the zero frequency step function ! Find the location in the WvFreq2 array that this point corresponds to. We will check only between the ! cutoffs that were added to the frequency range. This is contained within TmpWvFreq2 from reading in. @@ -4599,7 +4956,7 @@ SUBROUTINE Read_DataFile4D( Filename4D, Data4D, ErrStat, Errmsg ) CALL CleanUp RETURN ENDIF - TmpCoord(2) = TmpCoord(2) + ( WvFreq2LoIdx - 1 ) ! shift to the point in the Data3D%WvFreq2 array by adding the zero frequency step function + TmpCoord(2) = TmpCoord(2) + ( WvFreq2LoIdx - 1 ) ! shift to the point in the Data4D%WvFreq2 array by adding the zero frequency step function ! Find the location in the WvDir1 array that this point corresponds to. CALL LocateStp( RawData4D(I,3), Data4D%WvDir1, TmpCoord(3), Data4D%NumWvDir1 ) @@ -4680,7 +5037,7 @@ SUBROUTINE Read_DataFile4D( Filename4D, Data4D, ErrStat, Errmsg ) ! Store the data after dimensionalizing Data4D%DataSet( TmpCoord(1), TmpCoord(2), TmpCoord(3), TmpCoord(4), TmpCoord(5) ) = & - InitInp%RhoXg * InitInp%WAMITULEN**K * CMPLX(RawData4D(I,8),RawData4D(I,9)) + REAL(InitInp%RhoXg * InitInp%WAMITULEN**K,SiKi) * CMPLX(RawData4D(I,8),RawData4D(I,9),SiKi) ! Set flag indicating that this value has been inserted. Data4D%DataMask( TmpCoord(1), TmpCoord(2), TmpCoord(3), TmpCoord(4), TmpCoord(5) ) = .TRUE. @@ -4771,26 +5128,26 @@ SUBROUTINE Read_DataFile4D( Filename4D, Data4D, ErrStat, Errmsg ) !---------------------------------------------------------------------------------- - !> We added two frequencies for the \f$ omega = 0 \f$ term if it did not exist, + !> We added two frequencies for the \f$ omega = 0 \f$ term if it did not exist, !! and added two frequencies for the infinite frequency term on the end of the array, - !! to create step changes outside the entered frequency ranges. We need to populate + !! to create step changes outside the entered frequency ranges. We need to populate !! the these new terms (set to zero). !---------------------------------------------------------------------------------- IF (.NOT. HaveZeroFreq1) THEN - Data4D%DataSet( 1:2,:,:,:,:) = CMPLX(0.0_SiKi,0.0_SiKi) ! Set the values to zero for everything before entered frequency range + Data4D%DataSet( 1:2,:,:,:,:) = CMPLX(0.0,0.0,SiKi) ! Set the values to zero for everything before entered frequency range Data4D%DataMask(1:2,:,:,:,:) = .TRUE. ! Set the mask for these first two frequencies - ENDIF - Data4D%DataSet( Data4D%NumWvFreq1-1:Data4D%NumWvFreq1,:,:,:,:) = CMPLX(0.0_SiKi,0.0_SiKi) ! Set the values for the last two frequencies to zero (everything higher than the last non-infinite frequency) - Data4D%DataMask(Data4D%NumWvFreq1-1:Data4D%NumWvFreq1,:,:,:,:) = .TRUE. ! Set the mask for the last two frequencies + ENDIF + Data4D%DataSet( Data4D%NumWvFreq1-1:Data4D%NumWvFreq1,:,:,:,:) = CMPLX(0.0,0.0,SiKi) ! Set the values for the last two frequencies to zero (everything higher than the last non-infinite frequency) + Data4D%DataMask(Data4D%NumWvFreq1-1:Data4D%NumWvFreq1,:,:,:,:) = .TRUE. ! Set the mask for the last two frequencies IF (.NOT. HaveZeroFreq2) THEN - Data4D%DataSet( :,1:2,:,:,:) = CMPLX(0.0_SiKi,0.0_SiKi) ! Set the values to zero for everything before entered frequency range + Data4D%DataSet( :,1:2,:,:,:) = CMPLX(0.0,0.0,SiKi) ! Set the values to zero for everything before entered frequency range Data4D%DataMask(:,1:2,:,:,:) = .TRUE. ! Set the mask for these first two frequencies - ENDIF - Data4D%DataSet( :,Data4D%NumWvFreq2-1:Data4D%NumWvFreq2,:,:,:) = CMPLX(0.0_SiKi,0.0_SiKi) ! Set the values for the last two frequencies to zero (everything higher than the last non-infinite frequency) - Data4D%DataMask(:,Data4D%NumWvFreq2-1:Data4D%NumWvFreq2,:,:,:) = .TRUE. ! Set the mask for the last two frequencies - + ENDIF + Data4D%DataSet( :,Data4D%NumWvFreq2-1:Data4D%NumWvFreq2,:,:,:) = CMPLX(0.0,0.0,SiKi) ! Set the values for the last two frequencies to zero (everything higher than the last non-infinite frequency) + Data4D%DataMask(:,Data4D%NumWvFreq2-1:Data4D%NumWvFreq2,:,:,:) = .TRUE. ! Set the mask for the last two frequencies + !---------------------------------------------------------------------------------- !> Find out if the data is sparse or full. Verification that the requested component @@ -4799,7 +5156,7 @@ SUBROUTINE Read_DataFile4D( Filename4D, Data4D, ErrStat, Errmsg ) !! for only the values of k that have data in them. !---------------------------------------------------------------------------------- - DO M=1,6 ! Loop over force component directions + DO M=1,6*Data4D%NumBodies ! Loop over force component directions TmpSparseFlag = .FALSE. ! Change this to true if any empty values are found IF (Data4D%LoadComponents(M)) THEN ! Only if we found data for that component DO I=1,Data4D%NumWvFreq1 @@ -4854,7 +5211,7 @@ SUBROUTINE Read_DataFile4D( Filename4D, Data4D, ErrStat, Errmsg ) IF (Data4D%NumWvFreq1 /= Data4D%NumWvFreq2) THEN TmpDiagComplete = .FALSE. ELSE ! Same number of frequencies, so we can proceed. - DO M=1,6 ! Loop over force component directions + DO M=1,6*Data4D%NumBodies ! Loop over force component directions ! If we have data for this component, and it is sparse, proceed to check it. IF (Data4D%LoadComponents(M) .AND. Data4D%DataIsSparse(M)) THEN @@ -4897,7 +5254,7 @@ END SUBROUTINE Read_DataFile4D - !> This subroutine counts the number of uniqe values in an array and returns a sorted array of them. + !> This subroutine counts the number of unique values in an array and returns a sorted array of them. !! This is called by the _Read_DataFile3D_ and _Read_DataFile4D_ routines. SUBROUTINE UniqueRealValues( DataArrayIn, DataArrayOut, NumUnique, ErrStat, ErrMsg ) IMPLICIT NONE @@ -5207,6 +5564,7 @@ SUBROUTINE ReadRealNumberFromString(StringToParse, ValueRead, StrRead, IsRealNum CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message including message from ReadNum INTEGER(IntKi), INTENT( OUT) :: IOErrStat !< Error status from the internal read. Useful for diagnostics. + CHARACTER(2048) :: ErrMsgTmp !< Temporary variable for holding the error message returned from a CALL statement ! Initialize some things @@ -5224,7 +5582,7 @@ SUBROUTINE ReadRealNumberFromString(StringToParse, ValueRead, StrRead, IsRealNum IsRealNum = .TRUE. else IsRealNum = .FALSE. - ValueRead = NaN ! This is NaN as defined in the NWTC_Num. + ValueRead = NaN_S ! This is NaN as defined in the NWTC_Num. ErrMsg = 'Not a real number. '//TRIM(ErrMsgTmp)//NewLine ErrSTat = ErrID_Severe endif @@ -5290,7 +5648,7 @@ SUBROUTINE ReadRealNumber(UnitNum, FileName, VarName, VarRead, StrRead, IsRealNu IsRealNum = .TRUE. else IsRealNum = .FALSE. - VarRead = NaN ! This is NaN as defined in the NWTC_Num. + VarRead = NaN_S ! This is NaN as defined in the NWTC_Num. ErrMsg = 'Not a real number. '//TRIM(ErrMsgTmp)//NewLine ErrStat = ErrStatTmp ! The ErrStatTmp returned by the ReadNum routine is an ErrID level. endif @@ -5411,10 +5769,11 @@ END SUBROUTINE WAMIT2_UpdateStates !---------------------------------------------------------------------------------------------------------------------------------- !> Routine for computing outputs, used in both loose and tight coupling. -SUBROUTINE WAMIT2_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) +SUBROUTINE WAMIT2_CalcOutput( Time, WaveTime, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) !.................................................................................................................................. REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds + real(SiKi), intent(in ) :: WaveTime(:) !< Array of wave kinematic time samples, (sec) TYPE(WAMIT2_InputType), INTENT(IN ) :: u !< Inputs at Time TYPE(WAMIT2_ParameterType), INTENT(IN ) :: p !< Parameters TYPE(WAMIT2_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time @@ -5430,10 +5789,9 @@ SUBROUTINE WAMIT2_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, E ! Local Variables: - INTEGER(IntKi) :: I ! Generic index -! INTEGER(IntKi) :: J ! Generic index -! INTEGER(IntKi) :: K ! Generic index - REAL(ReKi) :: AllOuts(MaxWAMIT2Outputs) + INTEGER(IntKi) :: I ! Generic index + INTEGER(IntKi) :: IBody ! Index to body number + INTEGER(IntKi) :: indxStart ! Starting index ! Initialize ErrStat @@ -5452,35 +5810,27 @@ SUBROUTINE WAMIT2_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, E END IF - ! Compute the 2nd order load contribution from incident waves: - DO I = 1,6 ! Loop through all wave excitation forces and moments - m%F_Waves2(I) = InterpWrappedStpReal ( REAL(Time, SiKi), p%WaveTime(:), p%WaveExctn2(:,I), & - m%LastIndWave, p%NStepWave + 1 ) - END DO ! I - All wave excitation forces and moments + do iBody = 1, p%NBody + indxStart = (iBody-1)*6 + DO I = 1,6 ! Loop through all wave excitation forces and moments + m%F_Waves2(indxStart+I) = InterpWrappedStpReal ( REAL(Time, SiKi), WaveTime(:), p%WaveExctn2(:,indxStart+I), & + m%LastIndWave(IBody), p%NStepWave + 1 ) + END DO ! I - All wave excitation forces and moments - ! Copy results to the output point mesh - DO I=1,3 - y%Mesh%Force(I,1) = m%F_Waves2(I) - END DO - DO I=1,3 - y%Mesh%Moment(I,1) = m%F_Waves2(I+3) - END DO - - - - ! Map the calculated results into the AllOuts Array - CALL WMT2Out_MapOutputs(Time, y, m%F_Waves2, AllOuts, ErrStat, ErrMsg) - + ! Copy results to the output point mesh + DO I=1,3 + y%Mesh%Force(I,IBody) = m%F_Waves2(indxStart+I) + END DO + DO I=1,3 + y%Mesh%Moment(I,IBody) = m%F_Waves2(indxStart+I+3) + END DO - ! Put the output data in the OutData array - DO I = 1,p%NumOuts - y%WriteOutput(I) = p%OutParam(I)%SignM * AllOuts( p%OutParam(I)%Indx ) - END DO + enddo END SUBROUTINE WAMIT2_CalcOutput @@ -5618,6 +5968,7 @@ SUBROUTINE Copy_InitData4Dto3D( Data4D, Data3D, ErrStat, ErrMsg ) INTEGER(IntKi) :: L !< Generic counter INTEGER(IntKi) :: ErrStatTmp !< Temporary error status for calls CHARACTER(2048) :: ErrMsgTmp !< Temporary error message for calls + CHARACTER(*), PARAMETER :: RoutineName = 'Copy_InitData4Dto3D' ! Initialize the error handling @@ -5629,20 +5980,20 @@ SUBROUTINE Copy_InitData4Dto3D( Data4D, Data3D, ErrStat, ErrMsg ) ! Make sure we aren't trying to copy 4D sum frequency data in to a 3D type that only holds information for difference frequencies IF ( Data4D%IsSumForce ) THEN - CALL SetErrStat( ErrID_Fatal, ' Attempted to copy 4D sum-frequency data into a 3D difference frequency type.', ErrStat, ErrMsg,'Copy_InitData4Dto3D') + CALL SetErrStat( ErrID_Fatal, ' Attempted to copy 4D sum-frequency data into a 3D difference frequency type.', ErrStat, ErrMsg,RoutineName) RETURN ENDIF ! Make sure the dimensions work IF ( Data4D%NumWvFreq1 /= Data4D%NumWvFreq2 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Attempted to copy 4D data to 3D data when NumFreq1 /= NumFreq2.', ErrStat, ErrMsg,'Copy_InitData4Dto3D') + CALL SetErrStat( ErrID_Fatal, ' Attempted to copy 4D data to 3D data when NumFreq1 /= NumFreq2.', ErrStat, ErrMsg,RoutineName) RETURN ENDIF ! Make sure that the frequencies actually match each other DO I=1,Data4D%NumWvFreq1 IF ( .NOT. EqualRealNos(Data4D%WvFreq1(I), Data4D%WvFreq2(I)) ) THEN - CALL SetErrStat( ErrID_Fatal, ' Attempted to copy 4D data to 3D data when wave frequencies are not the same.', ErrStat, ErrMsg,'Copy_InitData4Dto3D') + CALL SetErrStat( ErrID_Fatal, ' Attempted to copy 4D data to 3D data when wave frequencies are not the same.', ErrStat, ErrMsg,RoutineName) RETURN ENDIF ENDDO @@ -5656,7 +6007,7 @@ SUBROUTINE Copy_InitData4Dto3D( Data4D, Data3D, ErrStat, ErrMsg ) IF (ALLOCATED(Data3D%WvDir1)) ErrStatTmp = ErrID_Fatal IF (ALLOCATED(Data3D%WvDir2)) ErrStatTmp = ErrID_Fatal IF ( ErrStatTmp >= ErrID_Fatal ) THEN - CALL SetErrStat( ErrID_Fatal, ' Attempted to copy 4D data into a populated 3D dataset.', ErrStat, ErrMsg,'Copy_InitData4Dto3D') + CALL SetErrStat( ErrID_Fatal, ' Attempted to copy 4D data into a populated 3D dataset.', ErrStat, ErrMsg,RoutineName) ENDIF @@ -5665,22 +6016,26 @@ SUBROUTINE Copy_InitData4Dto3D( Data4D, Data3D, ErrStat, ErrMsg ) Data3D%NumWvFreq1 = Data4D%NumWvFreq1 Data3D%NumWvDir1 = Data4D%NumWvDir1 Data3D%NumWvDir2 = Data4D%NumWvDir2 - Data3D%LoadComponents = Data4D%LoadComponents + Data3D%NumBodies = Data4D%NumBodies ! Now allocate the storage arrays ALLOCATE( Data3D%DataSet( Data3D%NumWvFreq1, Data3D%NumWvDir1, Data3D%NumWvDir2, 6 ), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,'Cannot allocate array Data3D%DataSet to store '// & - 'the 3D 2nd order WAMIT data.', ErrStat,ErrMsg,'Copy_InitData4Dto3D') + 'the 3D 2nd order WAMIT data.', ErrStat,ErrMsg,RoutineName) ALLOCATE( Data3D%DataMask( Data3D%NumWvFreq1, Data3D%NumWvDir1, Data3D%NumWvDir2, 6 ), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,'Cannot allocate array Data3D%DataMask to store '// & - 'the information on the 3D 2nd order WAMIT data.', ErrStat,ErrMsg,'Copy_InitData4Dto3D') + 'the information on the 3D 2nd order WAMIT data.', ErrStat,ErrMsg,RoutineName) CALL AllocAry( Data3D%WvFreq1, Data3D%NumWvFreq1, 'Data3D WvFreq array', ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'Copy_InitData4Dto3D' ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) CALL AllocAry( Data3D%WvDir1, Data3D%NumWvDir1, 'Data3D WvDir1 array', ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'Copy_InitData4Dto3D' ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) CALL AllocAry( Data3D%WvDir2, Data3D%NumWvDir2, 'Data3D WvDir2 array', ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'Copy_InitData4Dto3D' ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) + CALL AllocAry( Data3D%LoadComponents, 6*Data3D%NumBodies, 'Data3D LoadComponents array', ErrStatTmp, ErrMsgTmp ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) + CALL AllocAry( Data3D%DataIsSparse, 6*Data3D%NumBodies, 'Data3D DataIsSparse array', ErrStatTmp, ErrMsgTmp ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Destroy_InitData3D( Data3D ) @@ -5692,6 +6047,7 @@ SUBROUTINE Copy_InitData4Dto3D( Data4D, Data3D, ErrStat, ErrMsg ) Data3D%WvFreq1 = Data4D%WvFreq1 Data3D%WvDir1 = Data4D%WvDir1 Data3D%WvDir2 = Data4D%WvDir2 + Data3D%LoadComponents = Data4D%LoadComponents DO I=1,Data3D%NumWvFreq1 Data3D%DataSet(I,:,:,:) = Data4D%DataSet(I,I,:,:,:) @@ -5712,7 +6068,7 @@ SUBROUTINE Copy_InitData4Dto3D( Data4D, Data3D, ErrStat, ErrMsg ) !! for only the values of k that have data in them. !---------------------------------------------------------------------------------- - DO L=1,6 ! Loop over force component directions + DO L=1,6*Data3D%NumBodies ! Loop over force component directions TmpSparseFlag = .FALSE. ! Change this to true if any empty values are found IF (Data3D%LoadComponents(L)) THEN ! Only if we found data for that component DO I=1,Data3D%NumWvFreq1 diff --git a/modules/hydrodyn/src/WAMIT2.txt b/modules/hydrodyn/src/WAMIT2.txt index 4226c37ca4..9a500b34ab 100644 --- a/modules/hydrodyn/src/WAMIT2.txt +++ b/modules/hydrodyn/src/WAMIT2.txt @@ -20,6 +20,12 @@ param WAMIT2/WAMIT2 unused INTEGER MaxWAMIT2Ou typedef WAMIT2/WAMIT2 InitInputType LOGICAL HasWAMIT - - - ".TRUE. if using WAMIT model, .FALSE. otherwise" - typedef ^ ^ CHARACTER(1024) WAMITFile - - - "Root of the filename for WAMIT2 outputs" - typedef ^ ^ INTEGER UnSum - - - "The unit number for the HydroDyn summary file" - +typedef ^ ^ INTEGER NBody - - - "[>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6]" - +typedef ^ ^ INTEGER NBodyMod - - - "Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1]" - +typedef ^ ^ ReKi PtfmRefxt {:} - - "The xt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1; must be 0.0 if NBodyMod=2 ]" (m) +typedef ^ ^ ReKi PtfmRefyt {:} - - "The yt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1; must be 0.0 if NBodyMod=2 ]" (m) +typedef ^ ^ ReKi PtfmRefzt {:} - - "The zt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1; must be 0.0 if NBodyMod=2 ]" (m) +typedef ^ ^ R8Ki PtfmRefztRot {:} - - "The rotation about zt of the body reference frame(s) from xt/yt" radians typedef ^ ^ ReKi WAMITULEN - - - "WAMIT unit length scale" - typedef ^ ^ ReKi RhoXg - - - "Density * Gravity -- from the Waves module." - @@ -27,6 +33,8 @@ typedef ^ ^ INTEGER NStepWave typedef ^ ^ INTEGER NStepWave2 - - - "NStepWave / 2" - typedef ^ ^ ReKi WaveDOmega - - - "Frequency step for incident wave calculations" (rad/s) typedef ^ ^ ReKi WtrDens - - - "Water density" (kg/m^3) +typedef ^ ^ ReKi Gravity - - - "Supplied by Driver: Gravitational acceleration" (m/s^2) +typedef ^ ^ SiKi WtrDpth - - - "Water depth (positive-valued)" (m) typedef ^ ^ SiKi WaveElevC0 {:}{:} - - "Discrete Fourier transform of the instantaneous elevation of incident waves at the platform reference point. First column is real part, second column is imaginary part" (meters) typedef ^ ^ SiKi WaveDir - - - "Mean incident wave propagation heading direction" (degrees) @@ -36,20 +44,8 @@ typedef ^ ^ SiKi WaveDirMin typedef ^ ^ SiKi WaveDirMax - - - "Maximum wave direction from Waves module" - typedef ^ ^ SiKi WaveTime {:} - - "Simulation times at which the instantaneous second order loads associated with the incident waves are determined" sec -typedef ^ ^ CHARACTER(ChanLen) OutList {27} - - "This should really be dimensioned with MaxOutPts" - -typedef ^ ^ LOGICAL OutAll - - - "" - -typedef ^ ^ INTEGER NumOuts - - - "" - -typedef ^ ^ INTEGER NumOutAll - - - "" - typedef ^ ^ INTEGER WaveMod - - - "The wave model to use. This is for error checking -- ideally this would be done in the main calling routine, not here." - -typedef ^ ^ LOGICAL PtfmSgF2 - - - "Supplied by Driver: Platform horizontal surge translation force (flag)" - -typedef ^ ^ LOGICAL PtfmSwF2 - - - "Supplied by Driver: Platform horizontal sway translation force (flag)" - -typedef ^ ^ LOGICAL PtfmHvF2 - - - "Supplied by Driver: Platform vertical heave translation force (flag)" - -typedef ^ ^ LOGICAL PtfmRF2 - - - "Supplied by Driver: Platform roll tilt rotation force (flag)" - -typedef ^ ^ LOGICAL PtfmPF2 - - - "Supplied by Driver: Platform pitch tilt rotation force (flag)" - -typedef ^ ^ LOGICAL PtfmYF2 - - - "Supplied by Driver: Platform yaw rotation force (flag)" - - - #[note: only one of MnDriff / NewmanApp / DiffQTF can be non-zero typedef ^ ^ INTEGER MnDrift - - - "Calculate the mean drift force {0: no mean drift; [7,8,9,10,11, or 12]: WAMIT file to use}" - typedef ^ ^ INTEGER NewmanApp - - - "Slow drift forces computed with Newman approximation from WAMIT file:{0: No slow drift; [7,8,9,10,11, or 12]: WAMIT file to use}" - @@ -69,9 +65,7 @@ typedef ^ ^ ReKi WvHiCOffS # Define outputs from the initialization routine here: # -#typedef ^ InitOutputType MeshType OutputMesh - - - "" - -typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {:} - - "" - -typedef ^ ^ CHARACTER(ChanLen) WriteOutputUnt {:} - - "" - +typedef ^ InitOutputType ReKi NULLVAL - - - "" - # ..... States .................................................................................................................... @@ -94,7 +88,7 @@ typedef ^ OtherStateType IntKi DummyOtherS # ..... Misc/Optimization variables................................................................................................. # Define any data that are used only for efficiency purposes (these variables are not associated with time): # e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType INTEGER LastIndWave - - - "Index for last interpolation step of 2nd order forces" - +typedef ^ MiscVarType INTEGER LastIndWave : - - "Index for last interpolation step of 2nd order forces" - typedef ^ ^ ReKi F_Waves2 {6} - - "2nd order force from this timestep" - @@ -106,6 +100,8 @@ typedef ^ ^ ReKi F_Waves2 typedef ^ ParameterType SiKi WaveTime {:} - - "Simulation times at which the instantaneous second order loads associated with the incident waves are determined" sec typedef ^ ^ IntKi NStepWave - - - "Number of wave time steps" - typedef ^ ^ DbKi DT - - - "" - +typedef ^ ^ INTEGER NBody - - - "[>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6]" - +typedef ^ ^ INTEGER NBodyMod - - - "Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1]" - #The 2nd order force time series typedef ^ ^ SiKi WaveExctn2 {:}{:} - - "Time series of the resulting 2nd order force (first index is timestep, second index is load component)" (N) @@ -142,4 +138,3 @@ typedef ^ InputType MeshType Mesh # ..... Outputs ................................................................................................................... # Define outputs that are contained on the mesh here: typedef ^ OutputType MeshType Mesh - - - "Loads at the platform reference point in the inertial frame" - -typedef ^ ^ ReKi WriteOutput {:} - - "" - diff --git a/modules/hydrodyn/src/WAMIT2_Output.f90 b/modules/hydrodyn/src/WAMIT2_Output.f90 deleted file mode 100644 index c77b4ebe02..0000000000 --- a/modules/hydrodyn/src/WAMIT2_Output.f90 +++ /dev/null @@ -1,561 +0,0 @@ -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2013-2015 National Renewable Energy Laboratory -! -! This file is part of HydroDyn. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** -MODULE WAMIT2_Output - - ! This MODULE stores variables used for output. - - USE NWTC_Library - USE WAMIT2_Types - !USE HydroDyn_Output_Types -! USE Waves - IMPLICIT NONE - - PRIVATE - - ! Indices for computing output channels: - ! NOTES: - ! (1) These parameters are in the order stored in "OutListParameters.xlsx" - ! (2) Array AllOuts() must be dimensioned to the value of the largest output parameter - - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - - ! WAMIT2 Body Forces: - - INTEGER(IntKi), PARAMETER :: WavesF2xi = 1 - INTEGER(IntKi), PARAMETER :: WavesF2yi = 2 - INTEGER(IntKi), PARAMETER :: WavesF2zi = 3 - INTEGER(IntKi), PARAMETER :: WavesM2xi = 4 - INTEGER(IntKi), PARAMETER :: WavesM2yi = 5 - INTEGER(IntKi), PARAMETER :: WavesM2zi = 6 - - - -!End of code generated by Matlab script - - - INTEGER, PARAMETER :: FWaves2(6) = (/WavesF2xi,WavesF2yi,WavesF2zi,WavesM2xi,WavesM2yi,WavesM2zi/) - - - -! This code was generated by hand. - CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(6) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically - "WAVESF2XI ","WAVESF2YI ","WAVESF2ZI ","WAVESM2XI ","WAVESM2YI ","WAVESM2ZI "/) - INTEGER(IntKi), PARAMETER :: ParamIndxAry(6) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) - WavesF2xi , WavesF2yi , WavesF2zi , WavesM2xi , WavesM2yi , WavesM2zi /) - CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(6) = (/ & ! This lists the units corresponding to the allowed parameters - "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) "/) - - - REAL(ReKi) :: AllOuts(MaxWAMIT2Outputs) ! Array of all possible outputs - - ! ..... Public Subroutines ................................................................................................... - PUBLIC :: WMT2OUT_MapOutputs - PUBLIC :: WMT2OUT_WriteOutputNames - PUBLIC :: WMT2OUT_WriteOutputUnits - PUBLIC :: WMT2OUT_WriteOutputs - PUBLIC :: WMT2OUT_Init - PUBLIC :: WMT2OUT_DestroyParam - PUBLIC :: GetWAMIT2Channels - -CONTAINS - - - - -!==================================================================================================== -SUBROUTINE WMT2OUT_MapOutputs( CurrentTime, y, F_Waves2, AllOuts, ErrStat, ErrMsg ) -! This subroutine writes the data stored in the y variable to the correct indexed postions in WriteOutput -! This is called by WAMIT2_CalcOutput() at each time step. -!---------------------------------------------------------------------------------------------------- - REAL(DbKi), INTENT( IN ) :: CurrentTime ! Current simulation time in seconds - TYPE(WAMIT2_OutputType), INTENT( INOUT ) :: y ! WAMIT2's output data - REAL(ReKi), INTENT( IN ) :: F_Waves2(6) - REAL(ReKi), INTENT( OUT ) :: AllOuts(MaxWAMIT2Outputs) - INTEGER(IntKi), INTENT( OUT ) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - INTEGER :: I - - ErrStat = ErrID_None - ErrMsg = "" - - - ! TODO: use y%mesh for the forces instead of individual parameters - - AllOuts(FWaves2) = F_Waves2 - - - - - -END SUBROUTINE WMT2OUT_MapOutputs - - -!==================================================================================================== - -SUBROUTINE WMT2OUT_WriteOutputNames( UnOutFile, p, ErrStat, ErrMsg ) - - INTEGER, INTENT( IN ) :: UnOutFile ! file unit for the output file - TYPE(WAMIT2_ParameterType), INTENT( IN ) :: p ! WAMIT2 module's parameter data - INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - CHARACTER(200) :: Frmt ! a string to hold a format statement - INTEGER :: I ! Generic loop counter - - ErrStat = ErrID_None - ErrMsg = "" - - Frmt = '(A8,'//TRIM(Int2LStr(p%NumOuts))//'(:,A,'//TRIM( p%OutSFmt )//'))' - - WRITE(UnOutFile,Frmt) 'Time', ( p%Delim, TRIM( p%OutParam(I)%Name ), I=1,p%NumOuts ) - -END SUBROUTINE WMT2OUT_WriteOutputNames - -!==================================================================================================== - - -SUBROUTINE WMT2OUT_WriteOutputUnits( UnOutFile, p, ErrStat, ErrMsg ) - - INTEGER, INTENT( IN ) :: UnOutFile ! file unit for the output file - TYPE(WAMIT2_ParameterType), INTENT( IN ) :: p ! WAMIT2 module's parameter data - INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - CHARACTER(200) :: Frmt ! a string to hold a format statement - INTEGER :: I ! Generic loop counter - - ErrStat = ErrID_None - ErrMsg = "" - - Frmt = '(A8,'//TRIM(Int2LStr(p%NumOuts))//'(:,A,'//TRIM( p%OutSFmt )//'))' - - WRITE(UnOutFile,Frmt) '(sec)', ( p%Delim, TRIM( p%OutParam(I)%Units ), I=1,p%NumOuts ) - -END SUBROUTINE WMT2OUT_WriteOutputUnits - -!==================================================================================================== -SUBROUTINE WMT2OUT_WriteOutputs( UnOutFile, Time, y, p, ErrStat, ErrMsg ) -! This subroutine writes the data stored in WriteOutputs (and indexed in OutParam) to the file -! opened in WMT2OUT_Init() -!---------------------------------------------------------------------------------------------------- - - ! Passed variables - INTEGER , INTENT( IN ) :: UnOutFile - REAL(DbKi), INTENT( IN ) :: Time ! Time for this output - TYPE(WAMIT2_OutputType), INTENT( INOUT ) :: y ! WAMIT2's output data - TYPE(WAMIT2_ParameterType),INTENT( IN ) :: p ! WAMIT2 parameter data - INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - ! Local variables -! REAL(ReKi) :: OutData (0:p%NumOuts) ! an output array - INTEGER :: I ! Generic loop counter - CHARACTER(200) :: Frmt ! a string to hold a format statement - - - - ! Initialize ErrStat and determine if it makes any sense to write output - - IF ( .NOT. ALLOCATED( p%OutParam ) .OR. UnOutFile < 0 ) THEN - ErrMsg = ' No WAMIT2 outputs written. The OutParam array must be allocated and there must be a valid output file identifier before we can write outputs.' - ErrStat = ErrID_Warn - RETURN - ELSE - ErrStat = ErrID_None - ErrMsg = '' - END IF - - - - - - ! Write the output parameters to the file - - Frmt = '(F8.3,'//TRIM(Int2LStr(p%NumOuts))//'(:,A,'//TRIM( p%OutFmt )//'))' - !Frmt = '('//TRIM( p%OutFmt )//','//TRIM(Int2LStr(p%NumOuts))//'(:,A,'//TRIM( p%OutFmt )//'))' - - WRITE(UnOutFile,Frmt) Time, ( p%Delim, y%WriteOutput(I), I=1,p%NumOuts ) - - - RETURN - - -END SUBROUTINE WMT2OUT_WriteOutputs - - - -!==================================================================================================== -SUBROUTINE WMT2OUT_Init( InitInp, y, p, InitOut, ErrStat, ErrMsg ) -! This subroutine initialized the output module, checking if the output parameter list (OutList) -! contains valid names, and opening the output file if there are any requested outputs -!---------------------------------------------------------------------------------------------------- - - - - ! Passed variables - - - TYPE(WAMIT2_InitInputType ), INTENT( IN ) :: InitInp ! data needed to initialize the output module - TYPE(WAMIT2_OutputType), INTENT( INOUT ) :: y ! This module's internal data - TYPE(WAMIT2_ParameterType), INTENT( INOUT ) :: p - TYPE(WAMIT2_InitOutputType), INTENT( OUT ) :: InitOut - INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - ! Local variables - INTEGER :: I ! Generic loop counter -! INTEGER :: J ! Generic loop counter -! INTEGER :: Indx ! Counts the current index into the WaveKinNd array -! CHARACTER(1024) :: OutFileName ! The name of the output file including the full path. -! CHARACTER(200) :: Frmt ! a string to hold a format statement - - !------------------------------------------------------------------------------------------------- - ! Initialize local variables - !------------------------------------------------------------------------------------------------- - - - ErrStat = ErrID_None - ErrMsg = "" - - - - - !------------------------------------------------------------------------------------------------- - ! Check that the variables in OutList are valid - !------------------------------------------------------------------------------------------------- - - - CALL WMT2OUT_ChkOutLst( InitInp%OutList(1:p%NumOuts), y, p, ErrStat, ErrMsg ) - IF ( ErrStat /= 0 ) RETURN - - - IF ( ALLOCATED( p%OutParam ) .AND. p%NumOuts > 0 ) THEN ! Output has been requested so let's open an output file - - ALLOCATE( y%WriteOutput( p%NumOuts ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for WriteOutput array.' - ErrStat = ErrID_Fatal - RETURN - END IF - y%WriteOutput = 0.0_ReKi - - ALLOCATE ( InitOut%WriteOutputHdr(p%NumOuts), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for WriteOutputHdr array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - ALLOCATE ( InitOut%WriteOutputUnt(p%NumOuts), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for WriteOutputHdr array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - DO I = 1,p%NumOuts - - InitOut%WriteOutputHdr(I) = TRIM( p%OutParam(I)%Name ) - InitOut%WriteOutputUnt(I) = TRIM( p%OutParam(I)%Units ) - - END DO - - END IF ! there are any requested outputs - - RETURN - -END SUBROUTINE WMT2OUT_Init - - -!==================================================================================================== -FUNCTION GetWAMIT2Channels ( NUserOutputs, UserOutputs, OutList, foundMask, ErrStat, ErrMsg ) -! This routine checks the names of inputted output channels, checks to see if they -! below to the list of available WAMIT2 channels. - -!---------------------------------------------------------------------------------------------------- - INTEGER, INTENT( IN ) :: NUserOutputs ! Number of user-specified output channels - CHARACTER(ChanLen), INTENT( IN ) :: UserOutputs (:) ! An array holding the names of the requested output channels. - CHARACTER(ChanLen), INTENT( OUT ) :: OutList (:) ! An array holding the names of the matched WAMIT2 output channels. - LOGICAL, INTENT( INOUT ) :: foundMask (:) ! A mask indicating whether a user requested channel belongs to a module's output channels. - INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - INTEGER GetWAMIT2Channels ! The number of channels found in this module - - ! Local variables. - - INTEGER :: I ! Generic loop-counting index. - INTEGER :: count ! Generic loop-counting index. - INTEGER :: INDX ! Index for valid arrays - - CHARACTER(ChanLen) :: OutListTmp ! A string to temporarily hold OutList(I). - CHARACTER(28), PARAMETER :: OutPFmt = "( I4, 3X,A 10,1 X, A10 )" ! Output format parameter output list. -! LOGICAL :: InvalidOutput(MaxWAMIT2Outputs) ! This array determines if the output channel is valid for this configuration - LOGICAL :: CheckOutListAgain - - LOGICAL :: newFoundMask (NUserOutputs) ! A Mask indicating whether a user requested channel belongs to a modules output channels. - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - GetWAMIT2Channels = 0 - - newFoundMask = .FALSE. - - - DO I = 1,NUserOutputs - IF (.NOT. foundMask(I) ) THEN - OutListTmp = UserOutputs(I) - - CheckOutListAgain = .FALSE. - - ! Reverse the sign (+/-) of the output channel if the user prefixed the - ! channel name with a '-', '_', 'm', or 'M' character indicating "minus". - - - - IF ( INDEX( '-_', OutListTmp(1:1) ) > 0 ) THEN - - OutListTmp = OutListTmp(2:) - ELSE IF ( INDEX( 'mM', OutListTmp(1:1) ) > 0 ) THEN ! We'll assume this is a variable name for now, (if not, we will check later if OutListTmp(2:) is also a variable name) - CheckOutListAgain = .TRUE. - - END IF - - CALL Conv2UC( OutListTmp ) ! Convert OutListTmp to upper case - - - Indx = IndexCharAry( OutListTmp(1:9), ValidParamAry ) - - IF ( CheckOutListAgain .AND. Indx < 1 ) THEN ! Let's assume that "M" really meant "minus" and then test again - ! ex, 'MTipDxc1' causes the sign of TipDxc1 to be switched. - OutListTmp = OutListTmp(2:) - - Indx = IndexCharAry( OutListTmp(1:9), ValidParamAry ) - END IF - - IF ( Indx > 0 ) THEN - newFoundMask(I) = .TRUE. - foundMask(I) = .TRUE. - GetWAMIT2Channels = GetWAMIT2Channels + 1 - - !ELSE - ! foundMask(I) = .FALSE. - END IF - END IF -END DO - - -IF ( GetWAMIT2Channels > 0 ) THEN - - count = 1 - ! Test that num channels does not exceed max possible channels due to size of OutList - !ALLOCATE ( OutList(GetWAMITChannels) , STAT=ErrStat ) - IF ( ErrStat /= 0 ) THEN - ErrMsg = ' Error allocating memory for the OutList array in the GetWAMIT2Channels function.' - ErrStat = ErrID_Fatal - RETURN - END IF - - DO I = 1,NUserOutputs - IF ( newFoundMask(I) ) THEN - OutList(count) = UserOutputs(I) - count = count + 1 - END IF - - END DO - -END IF - - -END FUNCTION GetWAMIT2Channels - - -!==================================================================================================== -SUBROUTINE WMT2OUT_ChkOutLst( OutList, y, p, ErrStat, ErrMsg ) -! This routine checks the names of inputted output channels, checks to see if any of them are ill- -! conditioned (returning an error if so), and assigns the OutputDataType settings (i.e, the index, -! name, and units of the output channels). -! Note that the Wamit module must be initialized prior to calling this function (if it -! is being used) so that it can correctly determine if the Lines outputs are valid. -!---------------------------------------------------------------------------------------------------- - - - - ! Passed variables - - TYPE(WAMIT2_OutputType), INTENT( INOUT ) :: y ! This module's internal data - TYPE(WAMIT2_ParameterType), INTENT( INOUT ) :: p ! parameter data for this instance of the WAMIT2 platform module - CHARACTER(ChanLen), INTENT( IN ) :: OutList (:) ! An array holding the names of the requested output channels. - INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - ! Local variables. - - INTEGER :: I ! Generic loop-counting index. -! INTEGER :: J ! Generic loop-counting index. - INTEGER :: INDX ! Index for valid arrays - - CHARACTER(ChanLen) :: OutListTmp ! A string to temporarily hold OutList(I). - CHARACTER(28), PARAMETER :: OutPFmt = "( I4, 3X,A 10,1 X, A10 )" ! Output format parameter output list. - - - ! 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 09-Jan-2013 14:53:03. - - LOGICAL :: InvalidOutput(MaxWAMIT2Outputs) ! This array determines if the output channel is valid for this configuration - - LOGICAL :: CheckOutListAgain - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - - InvalidOutput = .FALSE. - -!End of code generated by Matlab script - - !------------------------------------------------------------------------------------------------- - ! ALLOCATE the OutParam array - !------------------------------------------------------------------------------------------------- - ALLOCATE ( p%OutParam(p%NumOuts) , STAT=ErrStat ) - IF ( ErrStat /= 0 ) THEN - ErrMsg = ' Error allocating memory for the OutParam array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - - - - DO I = 1,p%NumOuts - - p%OutParam(I)%Name = OutList(I) - OutListTmp = OutList(I) - - - ! Reverse the sign (+/-) of the output channel if the user prefixed the - ! channel name with a '-', '_', 'm', or 'M' character indicating "minus". - - CheckOutListAgain = .FALSE. - - IF ( INDEX( '-_', OutListTmp(1:1) ) > 0 ) THEN - p%OutParam(I)%SignM = -1 ! ex, '-TipDxc1' causes the sign of TipDxc1 to be switched. - OutListTmp = OutListTmp(2:) - ELSE IF ( INDEX( 'mM', OutListTmp(1:1) ) > 0 ) THEN ! We'll assume this is a variable name for now, (if not, we will check later if OutListTmp(2:) is also a variable name) - CheckOutListAgain = .TRUE. - p%OutParam(I)%SignM = 1 - ELSE - p%OutParam(I)%SignM = 1 - END IF - - CALL Conv2UC( OutListTmp ) ! Convert OutListTmp to upper case - - - Indx = IndexCharAry( OutListTmp(1:9), ValidParamAry ) - - IF ( CheckOutListAgain .AND. Indx < 1 ) THEN ! Let's assume that "M" really meant "minus" and then test again - p%OutParam(I)%SignM = -1 ! ex, 'MTipDxc1' causes the sign of TipDxc1 to be switched. - OutListTmp = OutListTmp(2:) - - Indx = IndexCharAry( OutListTmp(1:9), ValidParamAry ) - END IF - - IF ( Indx > 0 ) THEN - p%OutParam(I)%Indx = ParamIndxAry(Indx) - IF ( InvalidOutput( ParamIndxAry(Indx) ) ) THEN - p%OutParam(I)%Units = 'INVALID' - p%OutParam(I)%Indx = 1 - p%OutParam(I)%SignM = 0 - ELSE - p%OutParam(I)%Units = ParamUnitsAry(Indx) - END IF - ELSE - ErrMsg = p%OutParam(I)%Name//' is not an available output channel.' - ErrStat = ErrID_Fatal -! RETURN - p%OutParam(I)%Units = 'INVALID' - p%OutParam(I)%Indx = 1 - p%OutParam(I)%SignM = 0 ! this will print all zeros - END IF - - END DO - - - RETURN -END SUBROUTINE WMT2OUT_ChkOutLst - - -!==================================================================================================== -SUBROUTINE WMT2OUT_DestroyParam ( p, ErrStat, ErrMsg ) -! This function cleans up after running the WAMIT2 output module. It closes the output file, -! releases memory, and resets the number of outputs requested to 0. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables - - TYPE(WAMIT2_ParameterType), INTENT( INOUT ) :: p ! parameter data for this instance of the WAMIT2 module - INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - -! ! Internal variables - LOGICAL :: Err - - - !------------------------------------------------------------------------------------------------- - ! Initialize error information - !------------------------------------------------------------------------------------------------- - ErrStat = ErrID_None - ErrMsg = "" - Err = .FALSE. - - - - !------------------------------------------------------------------------------------------------- - ! Deallocate arrays - !------------------------------------------------------------------------------------------------- - IF ( ALLOCATED( p%OutParam ) ) DEALLOCATE ( p%OutParam, STAT=ErrStat ) - IF ( ErrStat /= 0 ) Err = .TRUE. - - !------------------------------------------------------------------------------------------------- - ! Reset number of outputs - !------------------------------------------------------------------------------------------------- - p%NumOuts = 0 - p%UnOutFile = -1 - - !p%WaveKinNd = -1 ! set this array to "invalid" - - !------------------------------------------------------------------------------------------------- - ! Make sure ErrStat is non-zero if an error occurred - !------------------------------------------------------------------------------------------------- - IF ( Err ) ErrStat = ErrID_Fatal - - RETURN - -END SUBROUTINE WMT2OUT_DestroyParam -!==================================================================================================== - - -END MODULE WAMIT2_Output diff --git a/modules/hydrodyn/src/WAMIT2_Types.f90 b/modules/hydrodyn/src/WAMIT2_Types.f90 index af1cddd8dd..27627976a3 100644 --- a/modules/hydrodyn/src/WAMIT2_Types.f90 +++ b/modules/hydrodyn/src/WAMIT2_Types.f90 @@ -39,12 +39,20 @@ MODULE WAMIT2_Types LOGICAL :: HasWAMIT !< .TRUE. if using WAMIT model, .FALSE. otherwise [-] CHARACTER(1024) :: WAMITFile !< Root of the filename for WAMIT2 outputs [-] INTEGER(IntKi) :: UnSum !< The unit number for the HydroDyn summary file [-] + INTEGER(IntKi) :: NBody !< [>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6] [-] + INTEGER(IntKi) :: NBodyMod !< Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1] [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PtfmRefxt !< The xt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1; must be 0.0 if NBodyMod=2 ] [(m)] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PtfmRefyt !< The yt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1; must be 0.0 if NBodyMod=2 ] [(m)] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PtfmRefzt !< The zt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1; must be 0.0 if NBodyMod=2 ] [(m)] + REAL(R8Ki) , DIMENSION(:), ALLOCATABLE :: PtfmRefztRot !< The rotation about zt of the body reference frame(s) from xt/yt [radians] REAL(ReKi) :: WAMITULEN !< WAMIT unit length scale [-] REAL(ReKi) :: RhoXg !< Density * Gravity -- from the Waves module. [-] INTEGER(IntKi) :: NStepWave !< Total number of frequency components = total number of time steps in the incident wave [-] INTEGER(IntKi) :: NStepWave2 !< NStepWave / 2 [-] REAL(ReKi) :: WaveDOmega !< Frequency step for incident wave calculations [(rad/s)] REAL(ReKi) :: WtrDens !< Water density [(kg/m^3)] + REAL(ReKi) :: Gravity !< Supplied by Driver: Gravitational acceleration [(m/s^2)] + REAL(SiKi) :: WtrDpth !< Water depth (positive-valued) [(m)] REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: WaveElevC0 !< Discrete Fourier transform of the instantaneous elevation of incident waves at the platform reference point. First column is real part, second column is imaginary part [(meters)] REAL(SiKi) :: WaveDir !< Mean incident wave propagation heading direction [(degrees)] LOGICAL :: WaveMultiDir !< Indicates the waves are multidirectional -- set by HydroDyn_Input [-] @@ -52,17 +60,7 @@ MODULE WAMIT2_Types REAL(SiKi) :: WaveDirMin !< Minimum wave direction from Waves module [-] REAL(SiKi) :: WaveDirMax !< Maximum wave direction from Waves module [-] REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveTime !< Simulation times at which the instantaneous second order loads associated with the incident waves are determined [sec] - CHARACTER(ChanLen) , DIMENSION(1:27) :: OutList !< This should really be dimensioned with MaxOutPts [-] - LOGICAL :: OutAll !< [-] - INTEGER(IntKi) :: NumOuts !< [-] - INTEGER(IntKi) :: NumOutAll !< [-] INTEGER(IntKi) :: WaveMod !< The wave model to use. This is for error checking -- ideally this would be done in the main calling routine, not here. [-] - LOGICAL :: PtfmSgF2 !< Supplied by Driver: Platform horizontal surge translation force (flag) [-] - LOGICAL :: PtfmSwF2 !< Supplied by Driver: Platform horizontal sway translation force (flag) [-] - LOGICAL :: PtfmHvF2 !< Supplied by Driver: Platform vertical heave translation force (flag) [-] - LOGICAL :: PtfmRF2 !< Supplied by Driver: Platform roll tilt rotation force (flag) [-] - LOGICAL :: PtfmPF2 !< Supplied by Driver: Platform pitch tilt rotation force (flag) [-] - LOGICAL :: PtfmYF2 !< Supplied by Driver: Platform yaw rotation force (flag) [-] INTEGER(IntKi) :: MnDrift !< Calculate the mean drift force {0: no mean drift; [7,8,9,10,11, or 12]: WAMIT file to use} [-] INTEGER(IntKi) :: NewmanApp !< Slow drift forces computed with Newman approximation from WAMIT file:{0: No slow drift; [7,8,9,10,11, or 12]: WAMIT file to use} [-] INTEGER(IntKi) :: DiffQTF !< Full Difference-Frequency forces computed with full QTF's from WAMIT file: {0: No diff-QTF; [10,11, or 12]: WAMIT file to use} [-] @@ -81,8 +79,7 @@ MODULE WAMIT2_Types ! ======================= ! ========= WAMIT2_InitOutputType ======= TYPE, PUBLIC :: WAMIT2_InitOutputType - CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< [-] - CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputUnt !< [-] + REAL(ReKi) :: NULLVAL !< [-] END TYPE WAMIT2_InitOutputType ! ======================= ! ========= WAMIT2_ContinuousStateType ======= @@ -107,7 +104,7 @@ MODULE WAMIT2_Types ! ======================= ! ========= WAMIT2_MiscVarType ======= TYPE, PUBLIC :: WAMIT2_MiscVarType - INTEGER(IntKi) :: LastIndWave !< Index for last interpolation step of 2nd order forces [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: LastIndWave !< Index for last interpolation step of 2nd order forces [-] REAL(ReKi) , DIMENSION(1:6) :: F_Waves2 !< 2nd order force from this timestep [-] END TYPE WAMIT2_MiscVarType ! ======================= @@ -116,6 +113,8 @@ MODULE WAMIT2_Types REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveTime !< Simulation times at which the instantaneous second order loads associated with the incident waves are determined [sec] INTEGER(IntKi) :: NStepWave !< Number of wave time steps [-] REAL(DbKi) :: DT !< [-] + INTEGER(IntKi) :: NBody !< [>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6] [-] + INTEGER(IntKi) :: NBodyMod !< Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1] [-] REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: WaveExctn2 !< Time series of the resulting 2nd order force (first index is timestep, second index is load component) [(N)] LOGICAL , DIMENSION(1:6) :: MnDriftDims !< Flags for which dimensions to calculate in MnDrift calculations [-] LOGICAL , DIMENSION(1:6) :: NewmanAppDims !< Flags for which dimensions to calculate in NewmanApp calculations [-] @@ -142,7 +141,6 @@ MODULE WAMIT2_Types ! ========= WAMIT2_OutputType ======= TYPE, PUBLIC :: WAMIT2_OutputType TYPE(MeshType) :: Mesh !< Loads at the platform reference point in the inertial frame [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WriteOutput !< [-] END TYPE WAMIT2_OutputType ! ======================= CONTAINS @@ -165,12 +163,64 @@ SUBROUTINE WAMIT2_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, E DstInitInputData%HasWAMIT = SrcInitInputData%HasWAMIT DstInitInputData%WAMITFile = SrcInitInputData%WAMITFile DstInitInputData%UnSum = SrcInitInputData%UnSum + DstInitInputData%NBody = SrcInitInputData%NBody + DstInitInputData%NBodyMod = SrcInitInputData%NBodyMod +IF (ALLOCATED(SrcInitInputData%PtfmRefxt)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmRefxt,1) + i1_u = UBOUND(SrcInitInputData%PtfmRefxt,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmRefxt)) THEN + ALLOCATE(DstInitInputData%PtfmRefxt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmRefxt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmRefxt = SrcInitInputData%PtfmRefxt +ENDIF +IF (ALLOCATED(SrcInitInputData%PtfmRefyt)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmRefyt,1) + i1_u = UBOUND(SrcInitInputData%PtfmRefyt,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmRefyt)) THEN + ALLOCATE(DstInitInputData%PtfmRefyt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmRefyt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmRefyt = SrcInitInputData%PtfmRefyt +ENDIF +IF (ALLOCATED(SrcInitInputData%PtfmRefzt)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmRefzt,1) + i1_u = UBOUND(SrcInitInputData%PtfmRefzt,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmRefzt)) THEN + ALLOCATE(DstInitInputData%PtfmRefzt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmRefzt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmRefzt = SrcInitInputData%PtfmRefzt +ENDIF +IF (ALLOCATED(SrcInitInputData%PtfmRefztRot)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmRefztRot,1) + i1_u = UBOUND(SrcInitInputData%PtfmRefztRot,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmRefztRot)) THEN + ALLOCATE(DstInitInputData%PtfmRefztRot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmRefztRot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmRefztRot = SrcInitInputData%PtfmRefztRot +ENDIF DstInitInputData%WAMITULEN = SrcInitInputData%WAMITULEN DstInitInputData%RhoXg = SrcInitInputData%RhoXg DstInitInputData%NStepWave = SrcInitInputData%NStepWave DstInitInputData%NStepWave2 = SrcInitInputData%NStepWave2 DstInitInputData%WaveDOmega = SrcInitInputData%WaveDOmega DstInitInputData%WtrDens = SrcInitInputData%WtrDens + DstInitInputData%Gravity = SrcInitInputData%Gravity + DstInitInputData%WtrDpth = SrcInitInputData%WtrDpth IF (ALLOCATED(SrcInitInputData%WaveElevC0)) THEN i1_l = LBOUND(SrcInitInputData%WaveElevC0,1) i1_u = UBOUND(SrcInitInputData%WaveElevC0,1) @@ -213,17 +263,7 @@ SUBROUTINE WAMIT2_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, E END IF DstInitInputData%WaveTime = SrcInitInputData%WaveTime ENDIF - DstInitInputData%OutList = SrcInitInputData%OutList - DstInitInputData%OutAll = SrcInitInputData%OutAll - DstInitInputData%NumOuts = SrcInitInputData%NumOuts - DstInitInputData%NumOutAll = SrcInitInputData%NumOutAll DstInitInputData%WaveMod = SrcInitInputData%WaveMod - DstInitInputData%PtfmSgF2 = SrcInitInputData%PtfmSgF2 - DstInitInputData%PtfmSwF2 = SrcInitInputData%PtfmSwF2 - DstInitInputData%PtfmHvF2 = SrcInitInputData%PtfmHvF2 - DstInitInputData%PtfmRF2 = SrcInitInputData%PtfmRF2 - DstInitInputData%PtfmPF2 = SrcInitInputData%PtfmPF2 - DstInitInputData%PtfmYF2 = SrcInitInputData%PtfmYF2 DstInitInputData%MnDrift = SrcInitInputData%MnDrift DstInitInputData%NewmanApp = SrcInitInputData%NewmanApp DstInitInputData%DiffQTF = SrcInitInputData%DiffQTF @@ -249,6 +289,18 @@ SUBROUTINE WAMIT2_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(InitInputData%PtfmRefxt)) THEN + DEALLOCATE(InitInputData%PtfmRefxt) +ENDIF +IF (ALLOCATED(InitInputData%PtfmRefyt)) THEN + DEALLOCATE(InitInputData%PtfmRefyt) +ENDIF +IF (ALLOCATED(InitInputData%PtfmRefzt)) THEN + DEALLOCATE(InitInputData%PtfmRefzt) +ENDIF +IF (ALLOCATED(InitInputData%PtfmRefztRot)) THEN + DEALLOCATE(InitInputData%PtfmRefztRot) +ENDIF IF (ALLOCATED(InitInputData%WaveElevC0)) THEN DEALLOCATE(InitInputData%WaveElevC0) ENDIF @@ -298,12 +350,36 @@ SUBROUTINE WAMIT2_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Int_BufSz = Int_BufSz + 1 ! HasWAMIT Int_BufSz = Int_BufSz + 1*LEN(InData%WAMITFile) ! WAMITFile Int_BufSz = Int_BufSz + 1 ! UnSum + Int_BufSz = Int_BufSz + 1 ! NBody + Int_BufSz = Int_BufSz + 1 ! NBodyMod + Int_BufSz = Int_BufSz + 1 ! PtfmRefxt allocated yes/no + IF ( ALLOCATED(InData%PtfmRefxt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmRefxt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PtfmRefxt) ! PtfmRefxt + END IF + Int_BufSz = Int_BufSz + 1 ! PtfmRefyt allocated yes/no + IF ( ALLOCATED(InData%PtfmRefyt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmRefyt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PtfmRefyt) ! PtfmRefyt + END IF + Int_BufSz = Int_BufSz + 1 ! PtfmRefzt allocated yes/no + IF ( ALLOCATED(InData%PtfmRefzt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmRefzt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PtfmRefzt) ! PtfmRefzt + END IF + Int_BufSz = Int_BufSz + 1 ! PtfmRefztRot allocated yes/no + IF ( ALLOCATED(InData%PtfmRefztRot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmRefztRot upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%PtfmRefztRot) ! PtfmRefztRot + END IF Re_BufSz = Re_BufSz + 1 ! WAMITULEN Re_BufSz = Re_BufSz + 1 ! RhoXg Int_BufSz = Int_BufSz + 1 ! NStepWave Int_BufSz = Int_BufSz + 1 ! NStepWave2 Re_BufSz = Re_BufSz + 1 ! WaveDOmega Re_BufSz = Re_BufSz + 1 ! WtrDens + Re_BufSz = Re_BufSz + 1 ! Gravity + Re_BufSz = Re_BufSz + 1 ! WtrDpth Int_BufSz = Int_BufSz + 1 ! WaveElevC0 allocated yes/no IF ( ALLOCATED(InData%WaveElevC0) ) THEN Int_BufSz = Int_BufSz + 2*2 ! WaveElevC0 upper/lower bounds for each dimension @@ -323,17 +399,7 @@ SUBROUTINE WAMIT2_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Int_BufSz = Int_BufSz + 2*1 ! WaveTime upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WaveTime) ! WaveTime END IF - Int_BufSz = Int_BufSz + SIZE(InData%OutList)*LEN(InData%OutList) ! OutList - Int_BufSz = Int_BufSz + 1 ! OutAll - Int_BufSz = Int_BufSz + 1 ! NumOuts - Int_BufSz = Int_BufSz + 1 ! NumOutAll Int_BufSz = Int_BufSz + 1 ! WaveMod - Int_BufSz = Int_BufSz + 1 ! PtfmSgF2 - Int_BufSz = Int_BufSz + 1 ! PtfmSwF2 - Int_BufSz = Int_BufSz + 1 ! PtfmHvF2 - Int_BufSz = Int_BufSz + 1 ! PtfmRF2 - Int_BufSz = Int_BufSz + 1 ! PtfmPF2 - Int_BufSz = Int_BufSz + 1 ! PtfmYF2 Int_BufSz = Int_BufSz + 1 ! MnDrift Int_BufSz = Int_BufSz + 1 ! NewmanApp Int_BufSz = Int_BufSz + 1 ! DiffQTF @@ -383,6 +449,70 @@ SUBROUTINE WAMIT2_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er END DO ! I IntKiBuf(Int_Xferred) = InData%UnSum Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NBody + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NBodyMod + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%PtfmRefxt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmRefxt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmRefxt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmRefxt,1), UBOUND(InData%PtfmRefxt,1) + ReKiBuf(Re_Xferred) = InData%PtfmRefxt(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PtfmRefyt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmRefyt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmRefyt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmRefyt,1), UBOUND(InData%PtfmRefyt,1) + ReKiBuf(Re_Xferred) = InData%PtfmRefyt(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PtfmRefzt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmRefzt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmRefzt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmRefzt,1), UBOUND(InData%PtfmRefzt,1) + ReKiBuf(Re_Xferred) = InData%PtfmRefzt(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PtfmRefztRot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmRefztRot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmRefztRot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmRefztRot,1), UBOUND(InData%PtfmRefztRot,1) + DbKiBuf(Db_Xferred) = InData%PtfmRefztRot(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF ReKiBuf(Re_Xferred) = InData%WAMITULEN Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%RhoXg @@ -395,6 +525,10 @@ SUBROUTINE WAMIT2_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%WtrDens Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Gravity + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%WtrDpth + Re_Xferred = Re_Xferred + 1 IF ( .NOT. ALLOCATED(InData%WaveElevC0) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -453,32 +587,8 @@ SUBROUTINE WAMIT2_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Re_Xferred = Re_Xferred + 1 END DO END IF - DO i1 = LBOUND(InData%OutList,1), UBOUND(InData%OutList,1) - DO I = 1, LEN(InData%OutList) - IntKiBuf(Int_Xferred) = ICHAR(InData%OutList(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - IntKiBuf(Int_Xferred) = TRANSFER(InData%OutAll, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NumOuts - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NumOutAll - Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%WaveMod Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmSgF2, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmSwF2, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmHvF2, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmRF2, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmPF2, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmYF2, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%MnDrift Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NewmanApp @@ -545,6 +655,82 @@ SUBROUTINE WAMIT2_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, END DO ! I OutData%UnSum = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + OutData%NBody = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NBodyMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmRefxt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmRefxt)) DEALLOCATE(OutData%PtfmRefxt) + ALLOCATE(OutData%PtfmRefxt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmRefxt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmRefxt,1), UBOUND(OutData%PtfmRefxt,1) + OutData%PtfmRefxt(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmRefyt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmRefyt)) DEALLOCATE(OutData%PtfmRefyt) + ALLOCATE(OutData%PtfmRefyt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmRefyt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmRefyt,1), UBOUND(OutData%PtfmRefyt,1) + OutData%PtfmRefyt(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmRefzt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmRefzt)) DEALLOCATE(OutData%PtfmRefzt) + ALLOCATE(OutData%PtfmRefzt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmRefzt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmRefzt,1), UBOUND(OutData%PtfmRefzt,1) + OutData%PtfmRefzt(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmRefztRot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmRefztRot)) DEALLOCATE(OutData%PtfmRefztRot) + ALLOCATE(OutData%PtfmRefztRot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmRefztRot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmRefztRot,1), UBOUND(OutData%PtfmRefztRot,1) + OutData%PtfmRefztRot(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END IF OutData%WAMITULEN = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%RhoXg = ReKiBuf(Re_Xferred) @@ -557,6 +743,10 @@ SUBROUTINE WAMIT2_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = Re_Xferred + 1 OutData%WtrDens = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%Gravity = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%WtrDpth = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveElevC0 not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -624,34 +814,8 @@ SUBROUTINE WAMIT2_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = Re_Xferred + 1 END DO END IF - i1_l = LBOUND(OutData%OutList,1) - i1_u = UBOUND(OutData%OutList,1) - DO i1 = LBOUND(OutData%OutList,1), UBOUND(OutData%OutList,1) - DO I = 1, LEN(OutData%OutList) - OutData%OutList(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - OutData%OutAll = TRANSFER(IntKiBuf(Int_Xferred), OutData%OutAll) - Int_Xferred = Int_Xferred + 1 - OutData%NumOuts = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%NumOutAll = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 OutData%WaveMod = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%PtfmSgF2 = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmSgF2) - Int_Xferred = Int_Xferred + 1 - OutData%PtfmSwF2 = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmSwF2) - Int_Xferred = Int_Xferred + 1 - OutData%PtfmHvF2 = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmHvF2) - Int_Xferred = Int_Xferred + 1 - OutData%PtfmRF2 = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmRF2) - Int_Xferred = Int_Xferred + 1 - OutData%PtfmPF2 = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmPF2) - Int_Xferred = Int_Xferred + 1 - OutData%PtfmYF2 = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmYF2) - Int_Xferred = Int_Xferred + 1 OutData%MnDrift = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%NewmanApp = IntKiBuf(Int_Xferred) @@ -690,37 +854,13 @@ SUBROUTINE WAMIT2_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_CopyInitOutput' ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(SrcInitOutputData%WriteOutputHdr)) THEN - i1_l = LBOUND(SrcInitOutputData%WriteOutputHdr,1) - i1_u = UBOUND(SrcInitOutputData%WriteOutputHdr,1) - IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputHdr)) THEN - ALLOCATE(DstInitOutputData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInitOutputData%WriteOutputHdr = SrcInitOutputData%WriteOutputHdr -ENDIF -IF (ALLOCATED(SrcInitOutputData%WriteOutputUnt)) THEN - i1_l = LBOUND(SrcInitOutputData%WriteOutputUnt,1) - i1_u = UBOUND(SrcInitOutputData%WriteOutputUnt,1) - IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputUnt)) THEN - ALLOCATE(DstInitOutputData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInitOutputData%WriteOutputUnt = SrcInitOutputData%WriteOutputUnt -ENDIF + DstInitOutputData%NULLVAL = SrcInitOutputData%NULLVAL END SUBROUTINE WAMIT2_CopyInitOutput SUBROUTINE WAMIT2_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) @@ -732,12 +872,6 @@ SUBROUTINE WAMIT2_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN - DEALLOCATE(InitOutputData%WriteOutputHdr) -ENDIF -IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN - DEALLOCATE(InitOutputData%WriteOutputUnt) -ENDIF END SUBROUTINE WAMIT2_DestroyInitOutput SUBROUTINE WAMIT2_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -775,16 +909,7 @@ SUBROUTINE WAMIT2_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! WriteOutputHdr allocated yes/no - IF ( ALLOCATED(InData%WriteOutputHdr) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! WriteOutputHdr upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputHdr)*LEN(InData%WriteOutputHdr) ! WriteOutputHdr - END IF - Int_BufSz = Int_BufSz + 1 ! WriteOutputUnt allocated yes/no - IF ( ALLOCATED(InData%WriteOutputUnt) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! WriteOutputUnt upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputUnt)*LEN(InData%WriteOutputUnt) ! WriteOutputUnt - END IF + Re_BufSz = Re_BufSz + 1 ! NULLVAL IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -812,40 +937,8 @@ SUBROUTINE WAMIT2_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Db_Xferred = 1 Int_Xferred = 1 - IF ( .NOT. ALLOCATED(InData%WriteOutputHdr) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutputHdr,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputHdr,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%WriteOutputHdr,1), UBOUND(InData%WriteOutputHdr,1) - DO I = 1, LEN(InData%WriteOutputHdr) - IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputHdr(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - END IF - IF ( .NOT. ALLOCATED(InData%WriteOutputUnt) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutputUnt,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputUnt,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%WriteOutputUnt,1), UBOUND(InData%WriteOutputUnt,1) - DO I = 1, LEN(InData%WriteOutputUnt) - IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputUnt(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - END IF + ReKiBuf(Re_Xferred) = InData%NULLVAL + Re_Xferred = Re_Xferred + 1 END SUBROUTINE WAMIT2_PackInitOutput SUBROUTINE WAMIT2_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -861,7 +954,6 @@ SUBROUTINE WAMIT2_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat INTEGER(IntKi) :: Db_Xferred INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_UnPackInitOutput' @@ -875,46 +967,8 @@ SUBROUTINE WAMIT2_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputHdr not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%WriteOutputHdr)) DEALLOCATE(OutData%WriteOutputHdr) - ALLOCATE(OutData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%WriteOutputHdr,1), UBOUND(OutData%WriteOutputHdr,1) - DO I = 1, LEN(OutData%WriteOutputHdr) - OutData%WriteOutputHdr(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputUnt not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%WriteOutputUnt)) DEALLOCATE(OutData%WriteOutputUnt) - ALLOCATE(OutData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%WriteOutputUnt,1), UBOUND(OutData%WriteOutputUnt,1) - DO I = 1, LEN(OutData%WriteOutputUnt) - OutData%WriteOutputUnt(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - END IF + OutData%NULLVAL = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE WAMIT2_UnPackInitOutput SUBROUTINE WAMIT2_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg ) @@ -1432,7 +1486,18 @@ SUBROUTINE WAMIT2_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(SrcMiscData%LastIndWave)) THEN + i1_l = LBOUND(SrcMiscData%LastIndWave,1) + i1_u = UBOUND(SrcMiscData%LastIndWave,1) + IF (.NOT. ALLOCATED(DstMiscData%LastIndWave)) THEN + ALLOCATE(DstMiscData%LastIndWave(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%LastIndWave.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstMiscData%LastIndWave = SrcMiscData%LastIndWave +ENDIF DstMiscData%F_Waves2 = SrcMiscData%F_Waves2 END SUBROUTINE WAMIT2_CopyMisc @@ -1445,6 +1510,9 @@ SUBROUTINE WAMIT2_DestroyMisc( MiscData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(MiscData%LastIndWave)) THEN + DEALLOCATE(MiscData%LastIndWave) +ENDIF END SUBROUTINE WAMIT2_DestroyMisc SUBROUTINE WAMIT2_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1482,7 +1550,11 @@ SUBROUTINE WAMIT2_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! LastIndWave + Int_BufSz = Int_BufSz + 1 ! LastIndWave allocated yes/no + IF ( ALLOCATED(InData%LastIndWave) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LastIndWave upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%LastIndWave) ! LastIndWave + END IF Re_BufSz = Re_BufSz + SIZE(InData%F_Waves2) ! F_Waves2 IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -1511,8 +1583,21 @@ SUBROUTINE WAMIT2_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = InData%LastIndWave + IF ( .NOT. ALLOCATED(InData%LastIndWave) ) THEN + IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LastIndWave,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LastIndWave,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LastIndWave,1), UBOUND(InData%LastIndWave,1) + IntKiBuf(Int_Xferred) = InData%LastIndWave(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF DO i1 = LBOUND(InData%F_Waves2,1), UBOUND(InData%F_Waves2,1) ReKiBuf(Re_Xferred) = InData%F_Waves2(i1) Re_Xferred = Re_Xferred + 1 @@ -1546,8 +1631,24 @@ SUBROUTINE WAMIT2_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%LastIndWave = IntKiBuf(Int_Xferred) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LastIndWave not allocated Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LastIndWave)) DEALLOCATE(OutData%LastIndWave) + ALLOCATE(OutData%LastIndWave(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LastIndWave.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LastIndWave,1), UBOUND(OutData%LastIndWave,1) + OutData%LastIndWave(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF i1_l = LBOUND(OutData%F_Waves2,1) i1_u = UBOUND(OutData%F_Waves2,1) DO i1 = LBOUND(OutData%F_Waves2,1), UBOUND(OutData%F_Waves2,1) @@ -1586,6 +1687,8 @@ SUBROUTINE WAMIT2_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrM ENDIF DstParamData%NStepWave = SrcParamData%NStepWave DstParamData%DT = SrcParamData%DT + DstParamData%NBody = SrcParamData%NBody + DstParamData%NBodyMod = SrcParamData%NBodyMod IF (ALLOCATED(SrcParamData%WaveExctn2)) THEN i1_l = LBOUND(SrcParamData%WaveExctn2,1) i1_u = UBOUND(SrcParamData%WaveExctn2,1) @@ -1697,6 +1800,8 @@ SUBROUTINE WAMIT2_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg END IF Int_BufSz = Int_BufSz + 1 ! NStepWave Db_BufSz = Db_BufSz + 1 ! DT + Int_BufSz = Int_BufSz + 1 ! NBody + Int_BufSz = Int_BufSz + 1 ! NBodyMod Int_BufSz = Int_BufSz + 1 ! WaveExctn2 allocated yes/no IF ( ALLOCATED(InData%WaveExctn2) ) THEN Int_BufSz = Int_BufSz + 2*2 ! WaveExctn2 upper/lower bounds for each dimension @@ -1786,6 +1891,10 @@ SUBROUTINE WAMIT2_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_Xferred = Int_Xferred + 1 DbKiBuf(Db_Xferred) = InData%DT Db_Xferred = Db_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NBody + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NBodyMod + Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%WaveExctn2) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -1941,6 +2050,10 @@ SUBROUTINE WAMIT2_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Int_Xferred = Int_Xferred + 1 OutData%DT = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 + OutData%NBody = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NBodyMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveExctn2 not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -2289,7 +2402,6 @@ SUBROUTINE WAMIT2_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, E CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_CopyOutput' @@ -2299,18 +2411,6 @@ SUBROUTINE WAMIT2_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, E CALL MeshCopy( SrcOutputData%Mesh, DstOutputData%Mesh, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN -IF (ALLOCATED(SrcOutputData%WriteOutput)) THEN - i1_l = LBOUND(SrcOutputData%WriteOutput,1) - i1_u = UBOUND(SrcOutputData%WriteOutput,1) - IF (.NOT. ALLOCATED(DstOutputData%WriteOutput)) THEN - ALLOCATE(DstOutputData%WriteOutput(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%WriteOutput.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstOutputData%WriteOutput = SrcOutputData%WriteOutput -ENDIF END SUBROUTINE WAMIT2_CopyOutput SUBROUTINE WAMIT2_DestroyOutput( OutputData, ErrStat, ErrMsg ) @@ -2323,9 +2423,6 @@ SUBROUTINE WAMIT2_DestroyOutput( OutputData, ErrStat, ErrMsg ) ErrStat = ErrID_None ErrMsg = "" CALL MeshDestroy( OutputData%Mesh, ErrStat, ErrMsg ) -IF (ALLOCATED(OutputData%WriteOutput)) THEN - DEALLOCATE(OutputData%WriteOutput) -ENDIF END SUBROUTINE WAMIT2_DestroyOutput SUBROUTINE WAMIT2_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2381,11 +2478,6 @@ SUBROUTINE WAMIT2_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 1 ! WriteOutput allocated yes/no - IF ( ALLOCATED(InData%WriteOutput) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! WriteOutput upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%WriteOutput) ! WriteOutput - END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -2441,21 +2533,6 @@ SUBROUTINE WAMIT2_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - IF ( .NOT. ALLOCATED(InData%WriteOutput) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutput,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutput,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%WriteOutput,1), UBOUND(InData%WriteOutput,1) - ReKiBuf(Re_Xferred) = InData%WriteOutput(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF END SUBROUTINE WAMIT2_PackOutput SUBROUTINE WAMIT2_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -2471,7 +2548,6 @@ SUBROUTINE WAMIT2_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er INTEGER(IntKi) :: Db_Xferred INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_UnPackOutput' @@ -2525,24 +2601,6 @@ SUBROUTINE WAMIT2_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutput not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%WriteOutput)) DEALLOCATE(OutData%WriteOutput) - ALLOCATE(OutData%WriteOutput(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutput.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%WriteOutput,1), UBOUND(OutData%WriteOutput,1) - OutData%WriteOutput(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF END SUBROUTINE WAMIT2_UnPackOutput @@ -2778,8 +2836,6 @@ SUBROUTINE WAMIT2_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, Err REAL(DbKi) :: ScaleFactor ! temporary for extrapolation/interpolation INTEGER(IntKi) :: ErrStat2 ! local errors CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors - INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts - INTEGER :: i1 ! dim1 counter variable for arrays ! Initialize ErrStat ErrStat = ErrID_None ErrMsg = "" @@ -2796,12 +2852,6 @@ SUBROUTINE WAMIT2_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, Err ScaleFactor = t_out / t(2) CALL MeshExtrapInterp1(y1%Mesh, y2%Mesh, tin, y_out%Mesh, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) -IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN - DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) - b = -(y1%WriteOutput(i1) - y2%WriteOutput(i1)) - y_out%WriteOutput(i1) = y1%WriteOutput(i1) + b * ScaleFactor - END DO -END IF ! check if allocated END SUBROUTINE WAMIT2_Output_ExtrapInterp1 @@ -2837,8 +2887,6 @@ SUBROUTINE WAMIT2_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, INTEGER(IntKi) :: ErrStat2 ! local errors CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_Output_ExtrapInterp2' - INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts - INTEGER :: i1 ! dim1 counter variable for arrays ! Initialize ErrStat ErrStat = ErrID_None ErrMsg = "" @@ -2861,13 +2909,6 @@ SUBROUTINE WAMIT2_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) CALL MeshExtrapInterp2(y1%Mesh, y2%Mesh, y3%Mesh, tin, y_out%Mesh, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) -IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN - DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) - b = (t(3)**2*(y1%WriteOutput(i1) - y2%WriteOutput(i1)) + t(2)**2*(-y1%WriteOutput(i1) + y3%WriteOutput(i1)))* scaleFactor - c = ( (t(2)-t(3))*y1%WriteOutput(i1) + t(3)*y2%WriteOutput(i1) - t(2)*y3%WriteOutput(i1) ) * scaleFactor - y_out%WriteOutput(i1) = y1%WriteOutput(i1) + b + c * t_out - END DO -END IF ! check if allocated END SUBROUTINE WAMIT2_Output_ExtrapInterp2 END MODULE WAMIT2_Types diff --git a/modules/hydrodyn/src/WAMIT_Output.f90 b/modules/hydrodyn/src/WAMIT_Output.f90 deleted file mode 100644 index 51fb78d93e..0000000000 --- a/modules/hydrodyn/src/WAMIT_Output.f90 +++ /dev/null @@ -1,589 +0,0 @@ -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2013-2015 National Renewable Energy Laboratory -! -! This file is part of HydroDyn. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** -MODULE WAMIT_Output - - ! This MODULE stores variables used for output. - - USE NWTC_Library - USE WAMIT_Types - !USE HydroDyn_Output_Types - USE Waves - IMPLICIT NONE - - PRIVATE - - ! Indices for computing output channels: - ! NOTES: - ! (1) These parameters are in the order stored in "OutListParameters.xlsx" - ! (2) Array AllOuts() must be dimensioned to the value of the largest output parameter - - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 1 - - ! WAMIT Body Forces: - - INTEGER(IntKi), PARAMETER :: WavesF1xi = 1 - INTEGER(IntKi), PARAMETER :: WavesF1yi = 2 - INTEGER(IntKi), PARAMETER :: WavesF1zi = 3 - INTEGER(IntKi), PARAMETER :: WavesM1xi = 4 - INTEGER(IntKi), PARAMETER :: WavesM1yi = 5 - INTEGER(IntKi), PARAMETER :: WavesM1zi = 6 - INTEGER(IntKi), PARAMETER :: HdrStcFxi = 7 - INTEGER(IntKi), PARAMETER :: HdrStcFyi = 8 - INTEGER(IntKi), PARAMETER :: HdrStcFzi = 9 - INTEGER(IntKi), PARAMETER :: HdrStcMxi = 10 - INTEGER(IntKi), PARAMETER :: HdrStcMyi = 11 - INTEGER(IntKi), PARAMETER :: HdrStcMzi = 12 - INTEGER(IntKi), PARAMETER :: RdtnFxi = 13 - INTEGER(IntKi), PARAMETER :: RdtnFyi = 14 - INTEGER(IntKi), PARAMETER :: RdtnFzi = 15 - INTEGER(IntKi), PARAMETER :: RdtnMxi = 16 - INTEGER(IntKi), PARAMETER :: RdtnMyi = 17 - INTEGER(IntKi), PARAMETER :: RdtnMzi = 18 - - - -!End of code generated by Matlab script - - - INTEGER, PARAMETER :: FWaves1(6) = (/WavesF1xi,WavesF1yi,WavesF1zi,WavesM1xi,WavesM1yi,WavesM1zi/) - INTEGER, PARAMETER :: FHdrSttc(6) = (/HdrStcFxi,HdrStcFyi,HdrStcFzi,HdrStcMxi,HdrStcMyi,HdrStcMzi/) - INTEGER, PARAMETER :: FRdtn(6) = (/RdtnFxi,RdtnFyi,RdtnFzi,RdtnMxi,RdtnMyi,RdtnMzi/) - - - - ! 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 21-Mar-2013 08:13:04. - CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(18) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically - "HDRSTCFXI","HDRSTCFYI","HDRSTCFZI","HDRSTCMXI","HDRSTCMYI","HDRSTCMZI", & - "RDTNFXI ","RDTNFYI ","RDTNFZI ","RDTNMXI ","RDTNMYI ","RDTNMZI ", & - "WAVESF1XI","WAVESF1YI","WAVESF1ZI","WAVESM1XI","WAVESM1YI","WAVESM1ZI"/) - INTEGER(IntKi), PARAMETER :: ParamIndxAry(18) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) - HdrStcFxi , HdrStcFyi , HdrStcFzi , HdrStcMxi , HdrStcMyi , HdrStcMzi , & - RdtnFxi , RdtnFyi , RdtnFzi , RdtnMxi , RdtnMyi , RdtnMzi , & - WavesF1xi, WavesF1yi, WavesF1zi, WavesM1xi, WavesM1yi, WavesM1zi/) - CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(18) = (/ & ! This lists the units corresponding to the allowed parameters - "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & - "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & - "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) "/) - - - REAL(ReKi) :: AllOuts(MaxWAMITOutputs) ! Array of all possible outputs - - ! ..... Public Subroutines ................................................................................................... - PUBLIC :: WMTOUT_MapOutputs - PUBLIC :: WMTOUT_WriteOutputNames - PUBLIC :: WMTOUT_WriteOutputUnits - PUBLIC :: WMTOUT_WriteOutputs - PUBLIC :: WMTOUT_Init - PUBLIC :: WMTOUT_DestroyParam - PUBLIC :: GetWAMITChannels - -CONTAINS - - - - -!==================================================================================================== -SUBROUTINE WMTOUT_MapOutputs( CurrentTime, y, F_Waves1, F_HS, F_Rdtn, F_PtfmAM, AllOuts, ErrStat, ErrMsg ) -! This subroutine writes the data stored in the y variable to the correct indexed postions in WriteOutput -! This is called by WAMIT_CalcOutput() at each time step. -!---------------------------------------------------------------------------------------------------- - REAL(DbKi), INTENT( IN ) :: CurrentTime ! Current simulation time in seconds - TYPE(WAMIT_OutputType), INTENT( INOUT ) :: y ! WAMIT's output data - REAL(ReKi), INTENT( IN ) :: F_Waves1(6) - REAL(ReKi), INTENT( IN ) :: F_HS(6) - REAL(ReKi), INTENT( IN ) :: F_Rdtn(6) - REAL(ReKi), INTENT( IN ) :: F_PtfmAM(6) - REAL(ReKi), INTENT( OUT ) :: AllOuts(MaxWAMITOutputs) - INTEGER(IntKi), INTENT( OUT ) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - -! INTEGER :: I - - ErrStat = ErrID_None - ErrMsg = "" - - - ! TODO: use y%mesh for the forces instead of individual parameters - - !AllOuts(Time) = REAL(CurrentTime,ReKi) - AllOuts(FWaves1) = F_Waves1 - AllOuts(FHdrSttc) = F_HS - AllOuts(FRdtn) = F_Rdtn + F_PtfmAM - - - - - -END SUBROUTINE WMTOUT_MapOutputs - - -!==================================================================================================== - -SUBROUTINE WMTOUT_WriteOutputNames( UnOutFile, p, ErrStat, ErrMsg ) - - INTEGER, INTENT( IN ) :: UnOutFile ! file unit for the output file - TYPE(WAMIT_ParameterType), INTENT( IN ) :: p ! WAMIT module's parameter data - INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - CHARACTER(200) :: Frmt ! a string to hold a format statement - INTEGER :: I ! Generic loop counter - - ErrStat = ErrID_None - ErrMsg = "" - - Frmt = '(A8,'//TRIM(Int2LStr(p%NumOuts))//'(:,A,'//TRIM( p%OutSFmt )//'))' - - WRITE(UnOutFile,Frmt) 'Time', ( p%Delim, TRIM( p%OutParam(I)%Name ), I=1,p%NumOuts ) - -END SUBROUTINE WMTOUT_WriteOutputNames - -!==================================================================================================== - - -SUBROUTINE WMTOUT_WriteOutputUnits( UnOutFile, p, ErrStat, ErrMsg ) - - INTEGER, INTENT( IN ) :: UnOutFile ! file unit for the output file - TYPE(WAMIT_ParameterType), INTENT( IN ) :: p ! WAMIT module's parameter data - INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - CHARACTER(200) :: Frmt ! a string to hold a format statement - INTEGER :: I ! Generic loop counter - - ErrStat = ErrID_None - ErrMsg = "" - - Frmt = '(A8,'//TRIM(Int2LStr(p%NumOuts))//'(:,A,'//TRIM( p%OutSFmt )//'))' - - WRITE(UnOutFile,Frmt) '(sec)', ( p%Delim, TRIM( p%OutParam(I)%Units ), I=1,p%NumOuts ) - -END SUBROUTINE WMTOUT_WriteOutputUnits - -!==================================================================================================== -SUBROUTINE WMTOUT_WriteOutputs( UnOutFile, Time, y, p, ErrStat, ErrMsg ) -! This subroutine writes the data stored in WriteOutputs (and indexed in OutParam) to the file -! opened in WMTOUT_Init() -!---------------------------------------------------------------------------------------------------- - - ! Passed variables - INTEGER , INTENT( IN ) :: UnOutFile - REAL(DbKi), INTENT( IN ) :: Time ! Time for this output - TYPE(WAMIT_OutputType), INTENT( INOUT ) :: y ! WAMIT's output data - TYPE(WAMIT_ParameterType), INTENT( IN ) :: p ! WAMIT parameter data - INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - ! Local variables -! REAL(ReKi) :: OutData (0:p%NumOuts) ! an output array - INTEGER :: I ! Generic loop counter - CHARACTER(200) :: Frmt ! a string to hold a format statement - - - - ! Initialize ErrStat and determine if it makes any sense to write output - - IF ( .NOT. ALLOCATED( p%OutParam ) .OR. UnOutFile < 0 ) THEN - ErrMsg = ' No WAMIT outputs written. The OutParam array must be allocated and there must be a valid output file identifier before we can write outputs.' - ErrStat = ErrID_Warn - RETURN - ELSE - ErrStat = ErrID_None - ErrMsg = '' - END IF - - - - - - ! Write the output parameters to the file - - Frmt = '(F8.3,'//TRIM(Int2LStr(p%NumOuts))//'(:,A,'//TRIM( p%OutFmt )//'))' - !Frmt = '('//TRIM( p%OutFmt )//','//TRIM(Int2LStr(p%NumOuts))//'(:,A,'//TRIM( p%OutFmt )//'))' - - WRITE(UnOutFile,Frmt) Time, ( p%Delim, y%WriteOutput(I), I=1,p%NumOuts ) - - - RETURN - - -END SUBROUTINE WMTOUT_WriteOutputs - - - -!==================================================================================================== -SUBROUTINE WMTOUT_Init( InitInp, y, p, InitOut, ErrStat, ErrMsg ) -! This subroutine initialized the output module, checking if the output parameter list (OutList) -! contains valid names, and opening the output file if there are any requested outputs -!---------------------------------------------------------------------------------------------------- - - - - ! Passed variables - - - TYPE(WAMIT_InitInputType ), INTENT( IN ) :: InitInp ! data needed to initialize the output module - TYPE(WAMIT_OutputType), INTENT( INOUT ) :: y ! This module's internal data - TYPE(WAMIT_ParameterType), INTENT( INOUT ) :: p - TYPE(WAMIT_InitOutputType), INTENT( OUT ) :: InitOut - INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - ! Local variables - INTEGER :: I ! Generic loop counter -! INTEGER :: J ! Generic loop counter -! INTEGER :: Indx ! Counts the current index into the WaveKinNd array -! CHARACTER(1024) :: OutFileName ! The name of the output file including the full path. -! CHARACTER(200) :: Frmt ! a string to hold a format statement - - !------------------------------------------------------------------------------------------------- - ! Initialize local variables - !------------------------------------------------------------------------------------------------- - - - ErrStat = ErrID_None - ErrMsg = "" - - - - - !------------------------------------------------------------------------------------------------- - ! Check that the variables in OutList are valid - !------------------------------------------------------------------------------------------------- - - - CALL WMTOUT_ChkOutLst( InitInp%OutList(1:p%NumOuts), y, p, ErrStat, ErrMsg ) - IF ( ErrStat /= 0 ) RETURN - - - IF ( ALLOCATED( p%OutParam ) .AND. p%NumOuts > 0 ) THEN ! Output has been requested so let's open an output file - - ALLOCATE( y%WriteOutput( p%NumOuts ), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for WriteOutput array.' - ErrStat = ErrID_Fatal - RETURN - END IF - y%WriteOutput = 0.0_ReKi - - ALLOCATE ( InitOut%WriteOutputHdr(p%NumOuts), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for WriteOutputHdr array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - ALLOCATE ( InitOut%WriteOutputUnt(p%NumOuts), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for WriteOutputHdr array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - DO I = 1,p%NumOuts - - InitOut%WriteOutputHdr(I) = TRIM( p%OutParam(I)%Name ) - InitOut%WriteOutputUnt(I) = TRIM( p%OutParam(I)%Units ) - - END DO - - END IF ! there are any requested outputs - - RETURN - -END SUBROUTINE WMTOUT_Init - - -!==================================================================================================== -FUNCTION GetWAMITChannels ( NUserOutputs, UserOutputs, OutList, foundMask, ErrStat, ErrMsg ) -! This routine checks the names of inputted output channels, checks to see if they -! below to the list of available WAMIT channels. - -!---------------------------------------------------------------------------------------------------- - INTEGER, INTENT( IN ) :: NUserOutputs ! Number of user-specified output channels - CHARACTER(ChanLen), INTENT( IN ) :: UserOutputs (:) ! An array holding the names of the requested output channels. - CHARACTER(ChanLen), INTENT( OUT ) :: OutList (:) ! An array holding the names of the matched WAMIT output channels. - LOGICAL, INTENT( INOUT ) :: foundMask (:) ! A mask indicating whether a user requested channel belongs to a module's output channels. - INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - INTEGER GetWAMITChannels ! The number of channels found in this module - - ! Local variables. - - INTEGER :: I ! Generic loop-counting index. - INTEGER :: count ! Generic loop-counting index. - INTEGER :: INDX ! Index for valid arrays - - CHARACTER(ChanLen) :: OutListTmp ! A string to temporarily hold OutList(I). - CHARACTER(28), PARAMETER :: OutPFmt = "( I4, 3X,A 10,1 X, A10 )" ! Output format parameter output list. -! LOGICAL :: InvalidOutput(MaxWAMITOutputs) ! This array determines if the output channel is valid for this configuration - LOGICAL :: CheckOutListAgain - - LOGICAL :: newFoundMask (NUserOutputs) ! A Mask indicating whether a user requested channel belongs to a modules output channels. - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - GetWAMITChannels = 0 - - newFoundMask = .FALSE. - - - DO I = 1,NUserOutputs - IF (.NOT. foundMask(I) ) THEN - OutListTmp = UserOutputs(I) -! foundMask(I) = .FALSE. - CheckOutListAgain = .FALSE. - - ! Reverse the sign (+/-) of the output channel if the user prefixed the - ! channel name with a '-', '_', 'm', or 'M' character indicating "minus". - - - - IF ( INDEX( '-_', OutListTmp(1:1) ) > 0 ) THEN - - OutListTmp = OutListTmp(2:) - ELSE IF ( INDEX( 'mM', OutListTmp(1:1) ) > 0 ) THEN ! We'll assume this is a variable name for now, (if not, we will check later if OutListTmp(2:) is also a variable name) - CheckOutListAgain = .TRUE. - - END IF - - CALL Conv2UC( OutListTmp ) ! Convert OutListTmp to upper case - - - Indx = IndexCharAry( OutListTmp(1:9), ValidParamAry ) - - IF ( CheckOutListAgain .AND. Indx < 1 ) THEN ! Let's assume that "M" really meant "minus" and then test again - ! ex, 'MTipDxc1' causes the sign of TipDxc1 to be switched. - OutListTmp = OutListTmp(2:) - - Indx = IndexCharAry( OutListTmp(1:9), ValidParamAry ) - END IF - - IF ( Indx > 0 ) THEN - newfoundMask(I) = .TRUE. - foundMask(I) = .TRUE. - GetWAMITChannels = GetWAMITChannels + 1 - - !ELSE - ! foundMask(I) = .FALSE. - END IF - END IF -END DO - - -IF ( GetWAMITChannels > 0 ) THEN - - count = 1 - ! Test that num channels does not exceed max possible channels due to size of OutList - !ALLOCATE ( OutList(GetWAMITChannels) , STAT=ErrStat ) - IF ( ErrStat /= 0 ) THEN - ErrMsg = ' Error allocating memory for the OutList array in the GetWAMITChannels function.' - ErrStat = ErrID_Fatal - RETURN - END IF - - DO I = 1,NUserOutputs - IF ( newfoundMask(I) ) THEN - OutList(count) = UserOutputs(I) - count = count + 1 - END IF - - END DO - -END IF - -END FUNCTION GetWAMITChannels - - -!==================================================================================================== -SUBROUTINE WMTOUT_ChkOutLst( OutList, y, p, ErrStat, ErrMsg ) -! This routine checks the names of inputted output channels, checks to see if any of them are ill- -! conditioned (returning an error if so), and assigns the OutputDataType settings (i.e, the index, -! name, and units of the output channels). -! Note that the Wamit module must be initialized prior to calling this function (if it -! is being used) so that it can correctly determine if the Lines outputs are valid. -!---------------------------------------------------------------------------------------------------- - - - - ! Passed variables - - TYPE(WAMIT_OutputType), INTENT( INOUT ) :: y ! This module's internal data - TYPE(WAMIT_ParameterType), INTENT( INOUT ) :: p ! parameter data for this instance of the WAMIT platform module - CHARACTER(ChanLen), INTENT( IN ) :: OutList (:) ! An array holding the names of the requested output channels. - INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - ! Local variables. - - INTEGER :: I ! Generic loop-counting index. -! INTEGER :: J ! Generic loop-counting index. - INTEGER :: INDX ! Index for valid arrays - - CHARACTER(ChanLen) :: OutListTmp ! A string to temporarily hold OutList(I). - CHARACTER(28), PARAMETER :: OutPFmt = "( I4, 3X,A 10,1 X, A10 )" ! Output format parameter output list. - - - ! 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 09-Jan-2013 14:53:03. - - LOGICAL :: InvalidOutput(MaxWAMITOutputs) ! This array determines if the output channel is valid for this configuration - - LOGICAL :: CheckOutListAgain - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - - InvalidOutput = .FALSE. - -!End of code generated by Matlab script - - !------------------------------------------------------------------------------------------------- - ! ALLOCATE the OutParam array - !------------------------------------------------------------------------------------------------- - ALLOCATE ( p%OutParam(p%NumOuts) , STAT=ErrStat ) - IF ( ErrStat /= 0 ) THEN - ErrMsg = ' Error allocating memory for the OutParam array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - - - - DO I = 1,p%NumOuts - - p%OutParam(I)%Name = OutList(I) - OutListTmp = OutList(I) - - - ! Reverse the sign (+/-) of the output channel if the user prefixed the - ! channel name with a '-', '_', 'm', or 'M' character indicating "minus". - - CheckOutListAgain = .FALSE. - - IF ( INDEX( '-_', OutListTmp(1:1) ) > 0 ) THEN - p%OutParam(I)%SignM = -1 ! ex, '-TipDxc1' causes the sign of TipDxc1 to be switched. - OutListTmp = OutListTmp(2:) - ELSE IF ( INDEX( 'mM', OutListTmp(1:1) ) > 0 ) THEN ! We'll assume this is a variable name for now, (if not, we will check later if OutListTmp(2:) is also a variable name) - CheckOutListAgain = .TRUE. - p%OutParam(I)%SignM = 1 - ELSE - p%OutParam(I)%SignM = 1 - END IF - - CALL Conv2UC( OutListTmp ) ! Convert OutListTmp to upper case - - - Indx = IndexCharAry( OutListTmp(1:9), ValidParamAry ) - - IF ( CheckOutListAgain .AND. Indx < 1 ) THEN ! Let's assume that "M" really meant "minus" and then test again - p%OutParam(I)%SignM = -1 ! ex, 'MTipDxc1' causes the sign of TipDxc1 to be switched. - OutListTmp = OutListTmp(2:) - - Indx = IndexCharAry( OutListTmp(1:9), ValidParamAry ) - END IF - - IF ( Indx > 0 ) THEN - p%OutParam(I)%Indx = ParamIndxAry(Indx) - IF ( InvalidOutput( ParamIndxAry(Indx) ) ) THEN - p%OutParam(I)%Units = 'INVALID' - p%OutParam(I)%Indx = 1 - p%OutParam(I)%SignM = 0 - ELSE - p%OutParam(I)%Units = ParamUnitsAry(Indx) - END IF - ELSE - ErrMsg = p%OutParam(I)%Name//' is not an available output channel.' - ErrStat = ErrID_Fatal -! RETURN - p%OutParam(I)%Units = 'INVALID' - p%OutParam(I)%Indx = 1 - p%OutParam(I)%SignM = 0 ! this will print all zeros - END IF - - END DO - - - RETURN -END SUBROUTINE WMTOUT_ChkOutLst - - -!==================================================================================================== -SUBROUTINE WMTOUT_DestroyParam ( p, ErrStat, ErrMsg ) -! This function cleans up after running the WAMIT output module. It closes the output file, -! releases memory, and resets the number of outputs requested to 0. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables - - TYPE(WAMIT_ParameterType), INTENT( INOUT ) :: p ! parameter data for this instance of the WAMIT module - INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - -! ! Internal variables - LOGICAL :: Err - - - !------------------------------------------------------------------------------------------------- - ! Initialize error information - !------------------------------------------------------------------------------------------------- - ErrStat = ErrID_None - ErrMsg = "" - Err = .FALSE. - - - - !------------------------------------------------------------------------------------------------- - ! Deallocate arrays - !------------------------------------------------------------------------------------------------- - IF ( ALLOCATED( p%OutParam ) ) DEALLOCATE ( p%OutParam, STAT=ErrStat ) - IF ( ErrStat /= 0 ) Err = .TRUE. - - !------------------------------------------------------------------------------------------------- - ! Reset number of outputs - !------------------------------------------------------------------------------------------------- - p%NumOuts = 0 - p%UnOutFile = -1 - - !p%WaveKinNd = -1 ! set this array to "invalid" - - !------------------------------------------------------------------------------------------------- - ! Make sure ErrStat is non-zero if an error occurred - !------------------------------------------------------------------------------------------------- - IF ( Err ) ErrStat = ErrID_Fatal - - RETURN - -END SUBROUTINE WMTOUT_DestroyParam -!==================================================================================================== - - -END MODULE WAMIT_Output diff --git a/modules/hydrodyn/src/WAMIT_Types.f90 b/modules/hydrodyn/src/WAMIT_Types.f90 index b321d69848..d5f86e17dd 100644 --- a/modules/hydrodyn/src/WAMIT_Types.f90 +++ b/modules/hydrodyn/src/WAMIT_Types.f90 @@ -40,11 +40,19 @@ MODULE WAMIT_Types INTEGER(IntKi), PUBLIC, PARAMETER :: MaxWAMITOutputs = 18 ! [-] ! ========= WAMIT_InitInputType ======= TYPE, PUBLIC :: WAMIT_InitInputType - REAL(ReKi) :: PtfmVol0 !< [-] + INTEGER(IntKi) :: NBody !< [>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6] [-] + INTEGER(IntKi) :: NBodyMod !< Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1] [-] + REAL(ReKi) :: Gravity !< Supplied by Driver: Gravitational acceleration [(m/s^2)] + REAL(SiKi) :: WtrDpth !< Water depth (positive-valued) [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PtfmVol0 !< [-] LOGICAL :: HasWAMIT !< .TRUE. if using WAMIT model, .FALSE. otherwise [-] REAL(ReKi) :: WAMITULEN !< [-] - REAL(ReKi) :: PtfmCOBxt !< [-] - REAL(ReKi) :: PtfmCOByt !< [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PtfmRefxt !< The xt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1 ] [(m)] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PtfmRefyt !< The yt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1 ] [(m)] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PtfmRefzt !< The zt offset of the body reference point(s) from (0,0,0) [1 to NBody; only used when PotMod=1; must be 0.0 if NBodyMod=2 ] [(m)] + REAL(R8Ki) , DIMENSION(:), ALLOCATABLE :: PtfmRefztRot !< The rotation about zt of the body reference frame(s) from xt/yt [radians] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PtfmCOBxt !< [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PtfmCOByt !< [-] INTEGER(IntKi) :: RdtnMod !< [-] INTEGER(IntKi) :: ExctnMod !< [-] REAL(DbKi) :: RdtnTMax !< [-] @@ -70,8 +78,7 @@ MODULE WAMIT_Types ! ======================= ! ========= WAMIT_InitOutputType ======= TYPE, PUBLIC :: WAMIT_InitOutputType - CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< [-] - CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputUnt !< [-] + REAL(ReKi) :: NULLVAL !< [-] END TYPE WAMIT_InitOutputType ! ======================= ! ========= WAMIT_ContinuousStateType ======= @@ -105,11 +112,10 @@ MODULE WAMIT_Types ! ========= WAMIT_MiscVarType ======= TYPE, PUBLIC :: WAMIT_MiscVarType INTEGER(IntKi) :: LastIndWave !< [-] - REAL(ReKi) , DIMENSION(1:6) :: F_HS !< local variable in CalcOutput:Total load contribution from hydrostatics, including the effects of waterplane area and the center of buoyancy [(N, N-m)] - REAL(ReKi) , DIMENSION(1:6) :: F_Waves1 !< local variable in CalcOutput:Total load contribution from incident waves (i.e., the diffraction problem) [(N, N-m)] - REAL(ReKi) , DIMENSION(1:6) :: F_Rdtn !< local variable in CalcOutput:Total load contribution from wave radiation damping (i.e., the diffraction problem) [(N, N-m)] - REAL(ReKi) , DIMENSION(1:6) :: F_PtfmAdd !< local variable in CalcOutput:set to zero because this is calculated in HydroDyn now [-] - REAL(ReKi) , DIMENSION(1:6) :: F_PtfmAM !< local variable in CalcOutput: [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: F_HS !< local variable in CalcOutput:Total load contribution from hydrostatics, including the effects of waterplane area and the center of buoyancy [(N, N-m)] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: F_Waves1 !< local variable in CalcOutput:Total load contribution from incident waves (i.e., the diffraction problem) [(N, N-m)] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: F_Rdtn !< local variable in CalcOutput:Total load contribution from wave radiation damping (i.e., the diffraction problem) [(N, N-m)] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: F_PtfmAM !< local variable in CalcOutput: [-] TYPE(SS_Rad_MiscVarType) :: SS_Rdtn !< [-] TYPE(SS_Rad_InputType) :: SS_Rdtn_u !< [-] TYPE(SS_Rad_OutputType) :: SS_Rdtn_y !< [-] @@ -123,27 +129,19 @@ MODULE WAMIT_Types ! ======================= ! ========= WAMIT_ParameterType ======= TYPE, PUBLIC :: WAMIT_ParameterType - REAL(ReKi) , DIMENSION(1:6,1:6) :: HdroAdMsI !< [(sec)] - REAL(ReKi) , DIMENSION(1:6,1:6) :: HdroSttc !< [-] - REAL(ReKi) :: PtfmVol0 !< [-] - REAL(ReKi) :: PtfmCOBxt !< [-] - REAL(ReKi) :: PtfmCOByt !< [-] + INTEGER(IntKi) :: NBody !< [>=1; only used when PotMod=1. If NBodyMod=1, the WAMIT data contains a vector of size 6*NBody x 1 and matrices of size 6*NBody x 6*NBody; if NBodyMod>1, there are NBody sets of WAMIT data each with a vector of size 6 x 1 and matrices of size 6 x 6] [-] + INTEGER(IntKi) :: NBodyMod !< Body coupling model {1: include coupling terms between each body and NBody in HydroDyn equals NBODY in WAMIT, 2: neglect coupling terms between each body and NBODY=1 with XBODY=0 in WAMIT, 3: Neglect coupling terms between each body and NBODY=1 with XBODY=/0 in WAMIT} (switch) [only used when PotMod=1] [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F_HS_Moment_Offset !< The offset moment due to the COB being offset from the WAMIT body's local location {matrix 3xNBody} [N-m] + REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: HdroAdMsI !< [(sec)] + REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: HdroSttc !< [-] INTEGER(IntKi) :: RdtnMod !< [-] INTEGER(IntKi) :: ExctnMod !< [-] REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: WaveExctn !< [-] - REAL(ReKi) :: RhoXg !< [-] - REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveTime !< [-] INTEGER(IntKi) :: NStepWave !< [-] TYPE(Conv_Rdtn_ParameterType) :: Conv_Rdtn !< [-] TYPE(SS_Rad_ParameterType) :: SS_Rdtn !< [-] TYPE(SS_Exc_ParameterType) :: SS_Exctn !< [-] REAL(DbKi) :: DT !< [-] - LOGICAL :: PtfmSgF !< [-] - LOGICAL :: PtfmSwF !< [-] - LOGICAL :: PtfmHvF !< [-] - LOGICAL :: PtfmRF !< [-] - LOGICAL :: PtfmPF !< [-] - LOGICAL :: PtfmYF !< [-] TYPE(OutParmType) , DIMENSION(:), ALLOCATABLE :: OutParam !< [-] INTEGER(IntKi) :: NumOuts !< [-] INTEGER(IntKi) :: NumOutAll !< [-] @@ -161,7 +159,6 @@ MODULE WAMIT_Types ! ========= WAMIT_OutputType ======= TYPE, PUBLIC :: WAMIT_OutputType TYPE(MeshType) :: Mesh !< Loads at the WAMIT reference point in the inertial frame [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WriteOutput !< [-] END TYPE WAMIT_OutputType ! ======================= CONTAINS @@ -181,11 +178,96 @@ SUBROUTINE WAMIT_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Er ! ErrStat = ErrID_None ErrMsg = "" + DstInitInputData%NBody = SrcInitInputData%NBody + DstInitInputData%NBodyMod = SrcInitInputData%NBodyMod + DstInitInputData%Gravity = SrcInitInputData%Gravity + DstInitInputData%WtrDpth = SrcInitInputData%WtrDpth +IF (ALLOCATED(SrcInitInputData%PtfmVol0)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmVol0,1) + i1_u = UBOUND(SrcInitInputData%PtfmVol0,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmVol0)) THEN + ALLOCATE(DstInitInputData%PtfmVol0(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmVol0.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInitInputData%PtfmVol0 = SrcInitInputData%PtfmVol0 +ENDIF DstInitInputData%HasWAMIT = SrcInitInputData%HasWAMIT DstInitInputData%WAMITULEN = SrcInitInputData%WAMITULEN +IF (ALLOCATED(SrcInitInputData%PtfmRefxt)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmRefxt,1) + i1_u = UBOUND(SrcInitInputData%PtfmRefxt,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmRefxt)) THEN + ALLOCATE(DstInitInputData%PtfmRefxt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmRefxt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmRefxt = SrcInitInputData%PtfmRefxt +ENDIF +IF (ALLOCATED(SrcInitInputData%PtfmRefyt)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmRefyt,1) + i1_u = UBOUND(SrcInitInputData%PtfmRefyt,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmRefyt)) THEN + ALLOCATE(DstInitInputData%PtfmRefyt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmRefyt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmRefyt = SrcInitInputData%PtfmRefyt +ENDIF +IF (ALLOCATED(SrcInitInputData%PtfmRefzt)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmRefzt,1) + i1_u = UBOUND(SrcInitInputData%PtfmRefzt,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmRefzt)) THEN + ALLOCATE(DstInitInputData%PtfmRefzt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmRefzt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmRefzt = SrcInitInputData%PtfmRefzt +ENDIF +IF (ALLOCATED(SrcInitInputData%PtfmRefztRot)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmRefztRot,1) + i1_u = UBOUND(SrcInitInputData%PtfmRefztRot,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmRefztRot)) THEN + ALLOCATE(DstInitInputData%PtfmRefztRot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmRefztRot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%PtfmRefztRot = SrcInitInputData%PtfmRefztRot +ENDIF +IF (ALLOCATED(SrcInitInputData%PtfmCOBxt)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmCOBxt,1) + i1_u = UBOUND(SrcInitInputData%PtfmCOBxt,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmCOBxt)) THEN + ALLOCATE(DstInitInputData%PtfmCOBxt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmCOBxt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInitInputData%PtfmCOBxt = SrcInitInputData%PtfmCOBxt +ENDIF +IF (ALLOCATED(SrcInitInputData%PtfmCOByt)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmCOByt,1) + i1_u = UBOUND(SrcInitInputData%PtfmCOByt,1) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmCOByt)) THEN + ALLOCATE(DstInitInputData%PtfmCOByt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmCOByt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInitInputData%PtfmCOByt = SrcInitInputData%PtfmCOByt +ENDIF DstInitInputData%RdtnMod = SrcInitInputData%RdtnMod DstInitInputData%ExctnMod = SrcInitInputData%ExctnMod DstInitInputData%RdtnTMax = SrcInitInputData%RdtnTMax @@ -266,6 +348,27 @@ SUBROUTINE WAMIT_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(InitInputData%PtfmVol0)) THEN + DEALLOCATE(InitInputData%PtfmVol0) +ENDIF +IF (ALLOCATED(InitInputData%PtfmRefxt)) THEN + DEALLOCATE(InitInputData%PtfmRefxt) +ENDIF +IF (ALLOCATED(InitInputData%PtfmRefyt)) THEN + DEALLOCATE(InitInputData%PtfmRefyt) +ENDIF +IF (ALLOCATED(InitInputData%PtfmRefzt)) THEN + DEALLOCATE(InitInputData%PtfmRefzt) +ENDIF +IF (ALLOCATED(InitInputData%PtfmRefztRot)) THEN + DEALLOCATE(InitInputData%PtfmRefztRot) +ENDIF +IF (ALLOCATED(InitInputData%PtfmCOBxt)) THEN + DEALLOCATE(InitInputData%PtfmCOBxt) +ENDIF +IF (ALLOCATED(InitInputData%PtfmCOByt)) THEN + DEALLOCATE(InitInputData%PtfmCOByt) +ENDIF CALL Conv_Rdtn_DestroyInitInput( InitInputData%Conv_Rdtn, ErrStat, ErrMsg ) IF (ALLOCATED(InitInputData%WaveElev0)) THEN DEALLOCATE(InitInputData%WaveElev0) @@ -316,11 +419,47 @@ SUBROUTINE WAMIT_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! PtfmVol0 + Int_BufSz = Int_BufSz + 1 ! NBody + Int_BufSz = Int_BufSz + 1 ! NBodyMod + Re_BufSz = Re_BufSz + 1 ! Gravity + Re_BufSz = Re_BufSz + 1 ! WtrDpth + Int_BufSz = Int_BufSz + 1 ! PtfmVol0 allocated yes/no + IF ( ALLOCATED(InData%PtfmVol0) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmVol0 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PtfmVol0) ! PtfmVol0 + END IF Int_BufSz = Int_BufSz + 1 ! HasWAMIT Re_BufSz = Re_BufSz + 1 ! WAMITULEN - Re_BufSz = Re_BufSz + 1 ! PtfmCOBxt - Re_BufSz = Re_BufSz + 1 ! PtfmCOByt + Int_BufSz = Int_BufSz + 1 ! PtfmRefxt allocated yes/no + IF ( ALLOCATED(InData%PtfmRefxt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmRefxt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PtfmRefxt) ! PtfmRefxt + END IF + Int_BufSz = Int_BufSz + 1 ! PtfmRefyt allocated yes/no + IF ( ALLOCATED(InData%PtfmRefyt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmRefyt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PtfmRefyt) ! PtfmRefyt + END IF + Int_BufSz = Int_BufSz + 1 ! PtfmRefzt allocated yes/no + IF ( ALLOCATED(InData%PtfmRefzt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmRefzt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PtfmRefzt) ! PtfmRefzt + END IF + Int_BufSz = Int_BufSz + 1 ! PtfmRefztRot allocated yes/no + IF ( ALLOCATED(InData%PtfmRefztRot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmRefztRot upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%PtfmRefztRot) ! PtfmRefztRot + END IF + Int_BufSz = Int_BufSz + 1 ! PtfmCOBxt allocated yes/no + IF ( ALLOCATED(InData%PtfmCOBxt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmCOBxt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PtfmCOBxt) ! PtfmCOBxt + END IF + Int_BufSz = Int_BufSz + 1 ! PtfmCOByt allocated yes/no + IF ( ALLOCATED(InData%PtfmCOByt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PtfmCOByt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PtfmCOByt) ! PtfmCOByt + END IF Int_BufSz = Int_BufSz + 1 ! RdtnMod Int_BufSz = Int_BufSz + 1 ! ExctnMod Db_BufSz = Db_BufSz + 1 ! RdtnTMax @@ -402,16 +541,123 @@ SUBROUTINE WAMIT_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Db_Xferred = 1 Int_Xferred = 1 - ReKiBuf(Re_Xferred) = InData%PtfmVol0 + IntKiBuf(Int_Xferred) = InData%NBody + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NBodyMod + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Gravity + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%WtrDpth Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%PtfmVol0) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmVol0,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmVol0,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmVol0,1), UBOUND(InData%PtfmVol0,1) + ReKiBuf(Re_Xferred) = InData%PtfmVol0(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF IntKiBuf(Int_Xferred) = TRANSFER(InData%HasWAMIT, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 ReKiBuf(Re_Xferred) = InData%WAMITULEN Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%PtfmCOBxt - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%PtfmCOByt - Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%PtfmRefxt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmRefxt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmRefxt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmRefxt,1), UBOUND(InData%PtfmRefxt,1) + ReKiBuf(Re_Xferred) = InData%PtfmRefxt(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PtfmRefyt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmRefyt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmRefyt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmRefyt,1), UBOUND(InData%PtfmRefyt,1) + ReKiBuf(Re_Xferred) = InData%PtfmRefyt(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PtfmRefzt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmRefzt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmRefzt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmRefzt,1), UBOUND(InData%PtfmRefzt,1) + ReKiBuf(Re_Xferred) = InData%PtfmRefzt(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PtfmRefztRot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmRefztRot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmRefztRot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmRefztRot,1), UBOUND(InData%PtfmRefztRot,1) + DbKiBuf(Db_Xferred) = InData%PtfmRefztRot(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PtfmCOBxt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmCOBxt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmCOBxt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmCOBxt,1), UBOUND(InData%PtfmCOBxt,1) + ReKiBuf(Re_Xferred) = InData%PtfmCOBxt(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PtfmCOByt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmCOByt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmCOByt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PtfmCOByt,1), UBOUND(InData%PtfmCOByt,1) + ReKiBuf(Re_Xferred) = InData%PtfmCOByt(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF IntKiBuf(Int_Xferred) = InData%RdtnMod Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%ExctnMod @@ -573,16 +819,144 @@ SUBROUTINE WAMIT_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%PtfmVol0 = ReKiBuf(Re_Xferred) + OutData%NBody = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NBodyMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%Gravity = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%WtrDpth = REAL(ReKiBuf(Re_Xferred), SiKi) Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmVol0 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmVol0)) DEALLOCATE(OutData%PtfmVol0) + ALLOCATE(OutData%PtfmVol0(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmVol0.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmVol0,1), UBOUND(OutData%PtfmVol0,1) + OutData%PtfmVol0(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF OutData%HasWAMIT = TRANSFER(IntKiBuf(Int_Xferred), OutData%HasWAMIT) Int_Xferred = Int_Xferred + 1 OutData%WAMITULEN = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%PtfmCOBxt = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%PtfmCOByt = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmRefxt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmRefxt)) DEALLOCATE(OutData%PtfmRefxt) + ALLOCATE(OutData%PtfmRefxt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmRefxt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmRefxt,1), UBOUND(OutData%PtfmRefxt,1) + OutData%PtfmRefxt(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmRefyt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmRefyt)) DEALLOCATE(OutData%PtfmRefyt) + ALLOCATE(OutData%PtfmRefyt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmRefyt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmRefyt,1), UBOUND(OutData%PtfmRefyt,1) + OutData%PtfmRefyt(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmRefzt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmRefzt)) DEALLOCATE(OutData%PtfmRefzt) + ALLOCATE(OutData%PtfmRefzt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmRefzt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmRefzt,1), UBOUND(OutData%PtfmRefzt,1) + OutData%PtfmRefzt(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmRefztRot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmRefztRot)) DEALLOCATE(OutData%PtfmRefztRot) + ALLOCATE(OutData%PtfmRefztRot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmRefztRot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmRefztRot,1), UBOUND(OutData%PtfmRefztRot,1) + OutData%PtfmRefztRot(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmCOBxt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmCOBxt)) DEALLOCATE(OutData%PtfmCOBxt) + ALLOCATE(OutData%PtfmCOBxt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmCOBxt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmCOBxt,1), UBOUND(OutData%PtfmCOBxt,1) + OutData%PtfmCOBxt(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmCOByt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PtfmCOByt)) DEALLOCATE(OutData%PtfmCOByt) + ALLOCATE(OutData%PtfmCOByt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmCOByt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PtfmCOByt,1), UBOUND(OutData%PtfmCOByt,1) + OutData%PtfmCOByt(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF OutData%RdtnMod = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%ExctnMod = IntKiBuf(Int_Xferred) @@ -750,37 +1124,13 @@ SUBROUTINE WAMIT_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_CopyInitOutput' ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(SrcInitOutputData%WriteOutputHdr)) THEN - i1_l = LBOUND(SrcInitOutputData%WriteOutputHdr,1) - i1_u = UBOUND(SrcInitOutputData%WriteOutputHdr,1) - IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputHdr)) THEN - ALLOCATE(DstInitOutputData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInitOutputData%WriteOutputHdr = SrcInitOutputData%WriteOutputHdr -ENDIF -IF (ALLOCATED(SrcInitOutputData%WriteOutputUnt)) THEN - i1_l = LBOUND(SrcInitOutputData%WriteOutputUnt,1) - i1_u = UBOUND(SrcInitOutputData%WriteOutputUnt,1) - IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputUnt)) THEN - ALLOCATE(DstInitOutputData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInitOutputData%WriteOutputUnt = SrcInitOutputData%WriteOutputUnt -ENDIF + DstInitOutputData%NULLVAL = SrcInitOutputData%NULLVAL END SUBROUTINE WAMIT_CopyInitOutput SUBROUTINE WAMIT_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) @@ -792,12 +1142,6 @@ SUBROUTINE WAMIT_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN - DEALLOCATE(InitOutputData%WriteOutputHdr) -ENDIF -IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN - DEALLOCATE(InitOutputData%WriteOutputUnt) -ENDIF END SUBROUTINE WAMIT_DestroyInitOutput SUBROUTINE WAMIT_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -835,16 +1179,7 @@ SUBROUTINE WAMIT_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! WriteOutputHdr allocated yes/no - IF ( ALLOCATED(InData%WriteOutputHdr) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! WriteOutputHdr upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputHdr)*LEN(InData%WriteOutputHdr) ! WriteOutputHdr - END IF - Int_BufSz = Int_BufSz + 1 ! WriteOutputUnt allocated yes/no - IF ( ALLOCATED(InData%WriteOutputUnt) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! WriteOutputUnt upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputUnt)*LEN(InData%WriteOutputUnt) ! WriteOutputUnt - END IF + Re_BufSz = Re_BufSz + 1 ! NULLVAL IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -872,40 +1207,8 @@ SUBROUTINE WAMIT_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Db_Xferred = 1 Int_Xferred = 1 - IF ( .NOT. ALLOCATED(InData%WriteOutputHdr) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutputHdr,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputHdr,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%WriteOutputHdr,1), UBOUND(InData%WriteOutputHdr,1) - DO I = 1, LEN(InData%WriteOutputHdr) - IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputHdr(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - END IF - IF ( .NOT. ALLOCATED(InData%WriteOutputUnt) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutputUnt,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputUnt,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%WriteOutputUnt,1), UBOUND(InData%WriteOutputUnt,1) - DO I = 1, LEN(InData%WriteOutputUnt) - IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputUnt(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - END IF + ReKiBuf(Re_Xferred) = InData%NULLVAL + Re_Xferred = Re_Xferred + 1 END SUBROUTINE WAMIT_PackInitOutput SUBROUTINE WAMIT_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -921,7 +1224,6 @@ SUBROUTINE WAMIT_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, INTEGER(IntKi) :: Db_Xferred INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_UnPackInitOutput' @@ -935,46 +1237,8 @@ SUBROUTINE WAMIT_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputHdr not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%WriteOutputHdr)) DEALLOCATE(OutData%WriteOutputHdr) - ALLOCATE(OutData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%WriteOutputHdr,1), UBOUND(OutData%WriteOutputHdr,1) - DO I = 1, LEN(OutData%WriteOutputHdr) - OutData%WriteOutputHdr(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputUnt not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%WriteOutputUnt)) DEALLOCATE(OutData%WriteOutputUnt) - ALLOCATE(OutData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%WriteOutputUnt,1), UBOUND(OutData%WriteOutputUnt,1) - DO I = 1, LEN(OutData%WriteOutputUnt) - OutData%WriteOutputUnt(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - END IF + OutData%NULLVAL = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE WAMIT_UnPackInitOutput SUBROUTINE WAMIT_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg ) @@ -2541,11 +2805,54 @@ SUBROUTINE WAMIT_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) ErrStat = ErrID_None ErrMsg = "" DstMiscData%LastIndWave = SrcMiscData%LastIndWave +IF (ALLOCATED(SrcMiscData%F_HS)) THEN + i1_l = LBOUND(SrcMiscData%F_HS,1) + i1_u = UBOUND(SrcMiscData%F_HS,1) + IF (.NOT. ALLOCATED(DstMiscData%F_HS)) THEN + ALLOCATE(DstMiscData%F_HS(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%F_HS.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstMiscData%F_HS = SrcMiscData%F_HS +ENDIF +IF (ALLOCATED(SrcMiscData%F_Waves1)) THEN + i1_l = LBOUND(SrcMiscData%F_Waves1,1) + i1_u = UBOUND(SrcMiscData%F_Waves1,1) + IF (.NOT. ALLOCATED(DstMiscData%F_Waves1)) THEN + ALLOCATE(DstMiscData%F_Waves1(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%F_Waves1.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstMiscData%F_Waves1 = SrcMiscData%F_Waves1 +ENDIF +IF (ALLOCATED(SrcMiscData%F_Rdtn)) THEN + i1_l = LBOUND(SrcMiscData%F_Rdtn,1) + i1_u = UBOUND(SrcMiscData%F_Rdtn,1) + IF (.NOT. ALLOCATED(DstMiscData%F_Rdtn)) THEN + ALLOCATE(DstMiscData%F_Rdtn(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%F_Rdtn.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstMiscData%F_Rdtn = SrcMiscData%F_Rdtn - DstMiscData%F_PtfmAdd = SrcMiscData%F_PtfmAdd +ENDIF +IF (ALLOCATED(SrcMiscData%F_PtfmAM)) THEN + i1_l = LBOUND(SrcMiscData%F_PtfmAM,1) + i1_u = UBOUND(SrcMiscData%F_PtfmAM,1) + IF (.NOT. ALLOCATED(DstMiscData%F_PtfmAM)) THEN + ALLOCATE(DstMiscData%F_PtfmAM(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%F_PtfmAM.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstMiscData%F_PtfmAM = SrcMiscData%F_PtfmAM +ENDIF CALL SS_Rad_CopyMisc( SrcMiscData%SS_Rdtn, DstMiscData%SS_Rdtn, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -2584,6 +2891,18 @@ SUBROUTINE WAMIT_DestroyMisc( MiscData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(MiscData%F_HS)) THEN + DEALLOCATE(MiscData%F_HS) +ENDIF +IF (ALLOCATED(MiscData%F_Waves1)) THEN + DEALLOCATE(MiscData%F_Waves1) +ENDIF +IF (ALLOCATED(MiscData%F_Rdtn)) THEN + DEALLOCATE(MiscData%F_Rdtn) +ENDIF +IF (ALLOCATED(MiscData%F_PtfmAM)) THEN + DEALLOCATE(MiscData%F_PtfmAM) +ENDIF CALL SS_Rad_DestroyMisc( MiscData%SS_Rdtn, ErrStat, ErrMsg ) CALL SS_Rad_DestroyInput( MiscData%SS_Rdtn_u, ErrStat, ErrMsg ) CALL SS_Rad_DestroyOutput( MiscData%SS_Rdtn_y, ErrStat, ErrMsg ) @@ -2631,11 +2950,26 @@ SUBROUTINE WAMIT_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Db_BufSz = 0 Int_BufSz = 0 Int_BufSz = Int_BufSz + 1 ! LastIndWave + Int_BufSz = Int_BufSz + 1 ! F_HS allocated yes/no + IF ( ALLOCATED(InData%F_HS) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! F_HS upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%F_HS) ! F_HS + END IF + Int_BufSz = Int_BufSz + 1 ! F_Waves1 allocated yes/no + IF ( ALLOCATED(InData%F_Waves1) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! F_Waves1 upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%F_Waves1) ! F_Waves1 + END IF + Int_BufSz = Int_BufSz + 1 ! F_Rdtn allocated yes/no + IF ( ALLOCATED(InData%F_Rdtn) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! F_Rdtn upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%F_Rdtn) ! F_Rdtn - Re_BufSz = Re_BufSz + SIZE(InData%F_PtfmAdd) ! F_PtfmAdd + END IF + Int_BufSz = Int_BufSz + 1 ! F_PtfmAM allocated yes/no + IF ( ALLOCATED(InData%F_PtfmAM) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! F_PtfmAM upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%F_PtfmAM) ! F_PtfmAM + END IF ! Allocate buffers for subtypes, if any (we'll get sizes from these) Int_BufSz = Int_BufSz + 3 ! SS_Rdtn: size of buffers for each call to pack subtype CALL SS_Rad_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%SS_Rdtn, ErrStat2, ErrMsg2, .TRUE. ) ! SS_Rdtn @@ -2819,26 +3153,66 @@ SUBROUTINE WAMIT_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, IntKiBuf(Int_Xferred) = InData%LastIndWave Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%F_HS,1), UBOUND(InData%F_HS,1) - ReKiBuf(Re_Xferred) = InData%F_HS(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%F_Waves1,1), UBOUND(InData%F_Waves1,1) - ReKiBuf(Re_Xferred) = InData%F_Waves1(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%F_Rdtn,1), UBOUND(InData%F_Rdtn,1) - ReKiBuf(Re_Xferred) = InData%F_Rdtn(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%F_PtfmAdd,1), UBOUND(InData%F_PtfmAdd,1) - ReKiBuf(Re_Xferred) = InData%F_PtfmAdd(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%F_PtfmAM,1), UBOUND(InData%F_PtfmAM,1) - ReKiBuf(Re_Xferred) = InData%F_PtfmAM(i1) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( .NOT. ALLOCATED(InData%F_HS) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_HS,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_HS,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%F_HS,1), UBOUND(InData%F_HS,1) + ReKiBuf(Re_Xferred) = InData%F_HS(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%F_Waves1) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_Waves1,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_Waves1,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%F_Waves1,1), UBOUND(InData%F_Waves1,1) + ReKiBuf(Re_Xferred) = InData%F_Waves1(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%F_Rdtn) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_Rdtn,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_Rdtn,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%F_Rdtn,1), UBOUND(InData%F_Rdtn,1) + ReKiBuf(Re_Xferred) = InData%F_Rdtn(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%F_PtfmAM) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_PtfmAM,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_PtfmAM,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%F_PtfmAM,1), UBOUND(InData%F_PtfmAM,1) + ReKiBuf(Re_Xferred) = InData%F_PtfmAM(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF CALL SS_Rad_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%SS_Rdtn, ErrStat2, ErrMsg2, OnlySize ) ! SS_Rdtn CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3122,36 +3496,78 @@ SUBROUTINE WAMIT_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs Int_Xferred = 1 OutData%LastIndWave = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%F_HS,1) - i1_u = UBOUND(OutData%F_HS,1) - DO i1 = LBOUND(OutData%F_HS,1), UBOUND(OutData%F_HS,1) - OutData%F_HS(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%F_Waves1,1) - i1_u = UBOUND(OutData%F_Waves1,1) - DO i1 = LBOUND(OutData%F_Waves1,1), UBOUND(OutData%F_Waves1,1) - OutData%F_Waves1(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%F_Rdtn,1) - i1_u = UBOUND(OutData%F_Rdtn,1) - DO i1 = LBOUND(OutData%F_Rdtn,1), UBOUND(OutData%F_Rdtn,1) - OutData%F_Rdtn(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%F_PtfmAdd,1) - i1_u = UBOUND(OutData%F_PtfmAdd,1) - DO i1 = LBOUND(OutData%F_PtfmAdd,1), UBOUND(OutData%F_PtfmAdd,1) - OutData%F_PtfmAdd(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%F_PtfmAM,1) - i1_u = UBOUND(OutData%F_PtfmAM,1) - DO i1 = LBOUND(OutData%F_PtfmAM,1), UBOUND(OutData%F_PtfmAM,1) - OutData%F_PtfmAM(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_HS not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_HS)) DEALLOCATE(OutData%F_HS) + ALLOCATE(OutData%F_HS(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_HS.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%F_HS,1), UBOUND(OutData%F_HS,1) + OutData%F_HS(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_Waves1 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_Waves1)) DEALLOCATE(OutData%F_Waves1) + ALLOCATE(OutData%F_Waves1(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_Waves1.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%F_Waves1,1), UBOUND(OutData%F_Waves1,1) + OutData%F_Waves1(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_Rdtn not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_Rdtn)) DEALLOCATE(OutData%F_Rdtn) + ALLOCATE(OutData%F_Rdtn(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_Rdtn.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%F_Rdtn,1), UBOUND(OutData%F_Rdtn,1) + OutData%F_Rdtn(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_PtfmAM not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_PtfmAM)) DEALLOCATE(OutData%F_PtfmAM) + ALLOCATE(OutData%F_PtfmAM(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_PtfmAM.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%F_PtfmAM,1), UBOUND(OutData%F_PtfmAM,1) + OutData%F_PtfmAM(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -3530,11 +3946,50 @@ SUBROUTINE WAMIT_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMs ! ErrStat = ErrID_None ErrMsg = "" + DstParamData%NBody = SrcParamData%NBody + DstParamData%NBodyMod = SrcParamData%NBodyMod +IF (ALLOCATED(SrcParamData%F_HS_Moment_Offset)) THEN + i1_l = LBOUND(SrcParamData%F_HS_Moment_Offset,1) + i1_u = UBOUND(SrcParamData%F_HS_Moment_Offset,1) + i2_l = LBOUND(SrcParamData%F_HS_Moment_Offset,2) + i2_u = UBOUND(SrcParamData%F_HS_Moment_Offset,2) + IF (.NOT. ALLOCATED(DstParamData%F_HS_Moment_Offset)) THEN + ALLOCATE(DstParamData%F_HS_Moment_Offset(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%F_HS_Moment_Offset.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%F_HS_Moment_Offset = SrcParamData%F_HS_Moment_Offset +ENDIF +IF (ALLOCATED(SrcParamData%HdroAdMsI)) THEN + i1_l = LBOUND(SrcParamData%HdroAdMsI,1) + i1_u = UBOUND(SrcParamData%HdroAdMsI,1) + i2_l = LBOUND(SrcParamData%HdroAdMsI,2) + i2_u = UBOUND(SrcParamData%HdroAdMsI,2) + IF (.NOT. ALLOCATED(DstParamData%HdroAdMsI)) THEN + ALLOCATE(DstParamData%HdroAdMsI(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%HdroAdMsI.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstParamData%HdroAdMsI = SrcParamData%HdroAdMsI +ENDIF +IF (ALLOCATED(SrcParamData%HdroSttc)) THEN + i1_l = LBOUND(SrcParamData%HdroSttc,1) + i1_u = UBOUND(SrcParamData%HdroSttc,1) + i2_l = LBOUND(SrcParamData%HdroSttc,2) + i2_u = UBOUND(SrcParamData%HdroSttc,2) + IF (.NOT. ALLOCATED(DstParamData%HdroSttc)) THEN + ALLOCATE(DstParamData%HdroSttc(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%HdroSttc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstParamData%HdroSttc = SrcParamData%HdroSttc - DstParamData%PtfmVol0 = SrcParamData%PtfmVol0 - DstParamData%PtfmCOBxt = SrcParamData%PtfmCOBxt - DstParamData%PtfmCOByt = SrcParamData%PtfmCOByt +ENDIF DstParamData%RdtnMod = SrcParamData%RdtnMod DstParamData%ExctnMod = SrcParamData%ExctnMod IF (ALLOCATED(SrcParamData%WaveExctn)) THEN @@ -3550,19 +4005,6 @@ SUBROUTINE WAMIT_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMs END IF END IF DstParamData%WaveExctn = SrcParamData%WaveExctn -ENDIF - DstParamData%RhoXg = SrcParamData%RhoXg -IF (ALLOCATED(SrcParamData%WaveTime)) THEN - i1_l = LBOUND(SrcParamData%WaveTime,1) - i1_u = UBOUND(SrcParamData%WaveTime,1) - IF (.NOT. ALLOCATED(DstParamData%WaveTime)) THEN - ALLOCATE(DstParamData%WaveTime(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%WaveTime.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%WaveTime = SrcParamData%WaveTime ENDIF DstParamData%NStepWave = SrcParamData%NStepWave CALL Conv_Rdtn_CopyParam( SrcParamData%Conv_Rdtn, DstParamData%Conv_Rdtn, CtrlCode, ErrStat2, ErrMsg2 ) @@ -3575,12 +4017,6 @@ SUBROUTINE WAMIT_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMs CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN DstParamData%DT = SrcParamData%DT - DstParamData%PtfmSgF = SrcParamData%PtfmSgF - DstParamData%PtfmSwF = SrcParamData%PtfmSwF - DstParamData%PtfmHvF = SrcParamData%PtfmHvF - DstParamData%PtfmRF = SrcParamData%PtfmRF - DstParamData%PtfmPF = SrcParamData%PtfmPF - DstParamData%PtfmYF = SrcParamData%PtfmYF IF (ALLOCATED(SrcParamData%OutParam)) THEN i1_l = LBOUND(SrcParamData%OutParam,1) i1_u = UBOUND(SrcParamData%OutParam,1) @@ -3614,11 +4050,17 @@ SUBROUTINE WAMIT_DestroyParam( ParamData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" +IF (ALLOCATED(ParamData%F_HS_Moment_Offset)) THEN + DEALLOCATE(ParamData%F_HS_Moment_Offset) +ENDIF +IF (ALLOCATED(ParamData%HdroAdMsI)) THEN + DEALLOCATE(ParamData%HdroAdMsI) +ENDIF +IF (ALLOCATED(ParamData%HdroSttc)) THEN + DEALLOCATE(ParamData%HdroSttc) +ENDIF IF (ALLOCATED(ParamData%WaveExctn)) THEN DEALLOCATE(ParamData%WaveExctn) -ENDIF -IF (ALLOCATED(ParamData%WaveTime)) THEN - DEALLOCATE(ParamData%WaveTime) ENDIF CALL Conv_Rdtn_DestroyParam( ParamData%Conv_Rdtn, ErrStat, ErrMsg ) CALL SS_Rad_DestroyParam( ParamData%SS_Rdtn, ErrStat, ErrMsg ) @@ -3666,23 +4108,29 @@ SUBROUTINE WAMIT_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! NBody + Int_BufSz = Int_BufSz + 1 ! NBodyMod + Int_BufSz = Int_BufSz + 1 ! F_HS_Moment_Offset allocated yes/no + IF ( ALLOCATED(InData%F_HS_Moment_Offset) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! F_HS_Moment_Offset upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_HS_Moment_Offset) ! F_HS_Moment_Offset + END IF + Int_BufSz = Int_BufSz + 1 ! HdroAdMsI allocated yes/no + IF ( ALLOCATED(InData%HdroAdMsI) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! HdroAdMsI upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%HdroAdMsI) ! HdroAdMsI + END IF + Int_BufSz = Int_BufSz + 1 ! HdroSttc allocated yes/no + IF ( ALLOCATED(InData%HdroSttc) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! HdroSttc upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%HdroSttc) ! HdroSttc - Re_BufSz = Re_BufSz + 1 ! PtfmVol0 - Re_BufSz = Re_BufSz + 1 ! PtfmCOBxt - Re_BufSz = Re_BufSz + 1 ! PtfmCOByt + END IF Int_BufSz = Int_BufSz + 1 ! RdtnMod Int_BufSz = Int_BufSz + 1 ! ExctnMod Int_BufSz = Int_BufSz + 1 ! WaveExctn allocated yes/no IF ( ALLOCATED(InData%WaveExctn) ) THEN Int_BufSz = Int_BufSz + 2*2 ! WaveExctn upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WaveExctn) ! WaveExctn - END IF - Re_BufSz = Re_BufSz + 1 ! RhoXg - Int_BufSz = Int_BufSz + 1 ! WaveTime allocated yes/no - IF ( ALLOCATED(InData%WaveTime) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! WaveTime upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%WaveTime) ! WaveTime END IF Int_BufSz = Int_BufSz + 1 ! NStepWave ! Allocate buffers for subtypes, if any (we'll get sizes from these) @@ -3738,12 +4186,6 @@ SUBROUTINE WAMIT_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, DEALLOCATE(Int_Buf) END IF Db_BufSz = Db_BufSz + 1 ! DT - Int_BufSz = Int_BufSz + 1 ! PtfmSgF - Int_BufSz = Int_BufSz + 1 ! PtfmSwF - Int_BufSz = Int_BufSz + 1 ! PtfmHvF - Int_BufSz = Int_BufSz + 1 ! PtfmRF - Int_BufSz = Int_BufSz + 1 ! PtfmPF - Int_BufSz = Int_BufSz + 1 ! PtfmYF Int_BufSz = Int_BufSz + 1 ! OutParam allocated yes/no IF ( ALLOCATED(InData%OutParam) ) THEN Int_BufSz = Int_BufSz + 2*1 ! OutParam upper/lower bounds for each dimension @@ -3800,24 +4242,70 @@ SUBROUTINE WAMIT_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Db_Xferred = 1 Int_Xferred = 1 - DO i2 = LBOUND(InData%HdroAdMsI,2), UBOUND(InData%HdroAdMsI,2) - DO i1 = LBOUND(InData%HdroAdMsI,1), UBOUND(InData%HdroAdMsI,1) - ReKiBuf(Re_Xferred) = InData%HdroAdMsI(i1,i2) - Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NBody + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NBodyMod + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%F_HS_Moment_Offset) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_HS_Moment_Offset,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_HS_Moment_Offset,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_HS_Moment_Offset,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_HS_Moment_Offset,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%F_HS_Moment_Offset,2), UBOUND(InData%F_HS_Moment_Offset,2) + DO i1 = LBOUND(InData%F_HS_Moment_Offset,1), UBOUND(InData%F_HS_Moment_Offset,1) + ReKiBuf(Re_Xferred) = InData%F_HS_Moment_Offset(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO END DO - END DO - DO i2 = LBOUND(InData%HdroSttc,2), UBOUND(InData%HdroSttc,2) - DO i1 = LBOUND(InData%HdroSttc,1), UBOUND(InData%HdroSttc,1) - ReKiBuf(Re_Xferred) = InData%HdroSttc(i1,i2) - Re_Xferred = Re_Xferred + 1 + END IF + IF ( .NOT. ALLOCATED(InData%HdroAdMsI) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%HdroAdMsI,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%HdroAdMsI,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%HdroAdMsI,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%HdroAdMsI,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%HdroAdMsI,2), UBOUND(InData%HdroAdMsI,2) + DO i1 = LBOUND(InData%HdroAdMsI,1), UBOUND(InData%HdroAdMsI,1) + ReKiBuf(Re_Xferred) = InData%HdroAdMsI(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO END DO - END DO - ReKiBuf(Re_Xferred) = InData%PtfmVol0 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%PtfmCOBxt - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%PtfmCOByt - Re_Xferred = Re_Xferred + 1 + END IF + IF ( .NOT. ALLOCATED(InData%HdroSttc) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%HdroSttc,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%HdroSttc,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%HdroSttc,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%HdroSttc,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%HdroSttc,2), UBOUND(InData%HdroSttc,2) + DO i1 = LBOUND(InData%HdroSttc,1), UBOUND(InData%HdroSttc,1) + ReKiBuf(Re_Xferred) = InData%HdroSttc(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF IntKiBuf(Int_Xferred) = InData%RdtnMod Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%ExctnMod @@ -3841,23 +4329,6 @@ SUBROUTINE WAMIT_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Re_Xferred = Re_Xferred + 1 END DO END DO - END IF - ReKiBuf(Re_Xferred) = InData%RhoXg - Re_Xferred = Re_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%WaveTime) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveTime,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveTime,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%WaveTime,1), UBOUND(InData%WaveTime,1) - ReKiBuf(Re_Xferred) = InData%WaveTime(i1) - Re_Xferred = Re_Xferred + 1 - END DO END IF IntKiBuf(Int_Xferred) = InData%NStepWave Int_Xferred = Int_Xferred + 1 @@ -3947,18 +4418,6 @@ SUBROUTINE WAMIT_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, ENDIF DbKiBuf(Db_Xferred) = InData%DT Db_Xferred = Db_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmSgF, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmSwF, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmHvF, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmRF, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmPF, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%PtfmYF, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%OutParam) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -4048,37 +4507,57 @@ SUBROUTINE WAMIT_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - i1_l = LBOUND(OutData%HdroAdMsI,1) - i1_u = UBOUND(OutData%HdroAdMsI,1) - i2_l = LBOUND(OutData%HdroAdMsI,2) - i2_u = UBOUND(OutData%HdroAdMsI,2) - DO i2 = LBOUND(OutData%HdroAdMsI,2), UBOUND(OutData%HdroAdMsI,2) - DO i1 = LBOUND(OutData%HdroAdMsI,1), UBOUND(OutData%HdroAdMsI,1) - OutData%HdroAdMsI(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - i1_l = LBOUND(OutData%HdroSttc,1) - i1_u = UBOUND(OutData%HdroSttc,1) - i2_l = LBOUND(OutData%HdroSttc,2) - i2_u = UBOUND(OutData%HdroSttc,2) - DO i2 = LBOUND(OutData%HdroSttc,2), UBOUND(OutData%HdroSttc,2) - DO i1 = LBOUND(OutData%HdroSttc,1), UBOUND(OutData%HdroSttc,1) - OutData%HdroSttc(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%NBody = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NBodyMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_HS_Moment_Offset not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%F_HS_Moment_Offset)) DEALLOCATE(OutData%F_HS_Moment_Offset) + ALLOCATE(OutData%F_HS_Moment_Offset(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_HS_Moment_Offset.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%F_HS_Moment_Offset,2), UBOUND(OutData%F_HS_Moment_Offset,2) + DO i1 = LBOUND(OutData%F_HS_Moment_Offset,1), UBOUND(OutData%F_HS_Moment_Offset,1) + OutData%F_HS_Moment_Offset(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO - END DO - OutData%PtfmVol0 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%PtfmCOBxt = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%PtfmCOByt = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RdtnMod = IntKiBuf(Int_Xferred) + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! HdroAdMsI not allocated Int_Xferred = Int_Xferred + 1 - OutData%ExctnMod = IntKiBuf(Int_Xferred) + ELSE Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveExctn not allocated + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%HdroAdMsI)) DEALLOCATE(OutData%HdroAdMsI) + ALLOCATE(OutData%HdroAdMsI(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%HdroAdMsI.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%HdroAdMsI,2), UBOUND(OutData%HdroAdMsI,2) + DO i1 = LBOUND(OutData%HdroAdMsI,1), UBOUND(OutData%HdroAdMsI,1) + OutData%HdroAdMsI(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! HdroSttc not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -4088,37 +4567,44 @@ SUBROUTINE WAMIT_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%WaveExctn)) DEALLOCATE(OutData%WaveExctn) - ALLOCATE(OutData%WaveExctn(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%HdroSttc)) DEALLOCATE(OutData%HdroSttc) + ALLOCATE(OutData%HdroSttc(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveExctn.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%HdroSttc.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%WaveExctn,2), UBOUND(OutData%WaveExctn,2) - DO i1 = LBOUND(OutData%WaveExctn,1), UBOUND(OutData%WaveExctn,1) - OutData%WaveExctn(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) + DO i2 = LBOUND(OutData%HdroSttc,2), UBOUND(OutData%HdroSttc,2) + DO i1 = LBOUND(OutData%HdroSttc,1), UBOUND(OutData%HdroSttc,1) + OutData%HdroSttc(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - OutData%RhoXg = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveTime not allocated + OutData%RdtnMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%ExctnMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveExctn not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%WaveTime)) DEALLOCATE(OutData%WaveTime) - ALLOCATE(OutData%WaveTime(i1_l:i1_u),STAT=ErrStat2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WaveExctn)) DEALLOCATE(OutData%WaveExctn) + ALLOCATE(OutData%WaveExctn(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveTime.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveExctn.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%WaveTime,1), UBOUND(OutData%WaveTime,1) - OutData%WaveTime(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(OutData%WaveExctn,2), UBOUND(OutData%WaveExctn,2) + DO i1 = LBOUND(OutData%WaveExctn,1), UBOUND(OutData%WaveExctn,1) + OutData%WaveExctn(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO END DO END IF OutData%NStepWave = IntKiBuf(Int_Xferred) @@ -4245,18 +4731,6 @@ SUBROUTINE WAMIT_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) OutData%DT = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 - OutData%PtfmSgF = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmSgF) - Int_Xferred = Int_Xferred + 1 - OutData%PtfmSwF = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmSwF) - Int_Xferred = Int_Xferred + 1 - OutData%PtfmHvF = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmHvF) - Int_Xferred = Int_Xferred + 1 - OutData%PtfmRF = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmRF) - Int_Xferred = Int_Xferred + 1 - OutData%PtfmPF = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmPF) - Int_Xferred = Int_Xferred + 1 - OutData%PtfmYF = TRANSFER(IntKiBuf(Int_Xferred), OutData%PtfmYF) - Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OutParam not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -4550,7 +5024,6 @@ SUBROUTINE WAMIT_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Er CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_CopyOutput' @@ -4560,18 +5033,6 @@ SUBROUTINE WAMIT_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Er CALL MeshCopy( SrcOutputData%Mesh, DstOutputData%Mesh, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN -IF (ALLOCATED(SrcOutputData%WriteOutput)) THEN - i1_l = LBOUND(SrcOutputData%WriteOutput,1) - i1_u = UBOUND(SrcOutputData%WriteOutput,1) - IF (.NOT. ALLOCATED(DstOutputData%WriteOutput)) THEN - ALLOCATE(DstOutputData%WriteOutput(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%WriteOutput.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstOutputData%WriteOutput = SrcOutputData%WriteOutput -ENDIF END SUBROUTINE WAMIT_CopyOutput SUBROUTINE WAMIT_DestroyOutput( OutputData, ErrStat, ErrMsg ) @@ -4584,9 +5045,6 @@ SUBROUTINE WAMIT_DestroyOutput( OutputData, ErrStat, ErrMsg ) ErrStat = ErrID_None ErrMsg = "" CALL MeshDestroy( OutputData%Mesh, ErrStat, ErrMsg ) -IF (ALLOCATED(OutputData%WriteOutput)) THEN - DEALLOCATE(OutputData%WriteOutput) -ENDIF END SUBROUTINE WAMIT_DestroyOutput SUBROUTINE WAMIT_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -4642,11 +5100,6 @@ SUBROUTINE WAMIT_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 1 ! WriteOutput allocated yes/no - IF ( ALLOCATED(InData%WriteOutput) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! WriteOutput upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%WriteOutput) ! WriteOutput - END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -4702,21 +5155,6 @@ SUBROUTINE WAMIT_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - IF ( .NOT. ALLOCATED(InData%WriteOutput) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutput,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutput,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%WriteOutput,1), UBOUND(InData%WriteOutput,1) - ReKiBuf(Re_Xferred) = InData%WriteOutput(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF END SUBROUTINE WAMIT_PackOutput SUBROUTINE WAMIT_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -4732,7 +5170,6 @@ SUBROUTINE WAMIT_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err INTEGER(IntKi) :: Db_Xferred INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_UnPackOutput' @@ -4786,24 +5223,6 @@ SUBROUTINE WAMIT_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutput not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%WriteOutput)) DEALLOCATE(OutData%WriteOutput) - ALLOCATE(OutData%WriteOutput(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutput.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%WriteOutput,1), UBOUND(OutData%WriteOutput,1) - OutData%WriteOutput(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF END SUBROUTINE WAMIT_UnPackOutput @@ -5039,8 +5458,6 @@ SUBROUTINE WAMIT_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, ErrM REAL(DbKi) :: ScaleFactor ! temporary for extrapolation/interpolation INTEGER(IntKi) :: ErrStat2 ! local errors CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors - INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts - INTEGER :: i1 ! dim1 counter variable for arrays ! Initialize ErrStat ErrStat = ErrID_None ErrMsg = "" @@ -5057,12 +5474,6 @@ SUBROUTINE WAMIT_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, ErrM ScaleFactor = t_out / t(2) CALL MeshExtrapInterp1(y1%Mesh, y2%Mesh, tin, y_out%Mesh, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) -IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN - DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) - b = -(y1%WriteOutput(i1) - y2%WriteOutput(i1)) - y_out%WriteOutput(i1) = y1%WriteOutput(i1) + b * ScaleFactor - END DO -END IF ! check if allocated END SUBROUTINE WAMIT_Output_ExtrapInterp1 @@ -5098,8 +5509,6 @@ SUBROUTINE WAMIT_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, INTEGER(IntKi) :: ErrStat2 ! local errors CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_Output_ExtrapInterp2' - INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts - INTEGER :: i1 ! dim1 counter variable for arrays ! Initialize ErrStat ErrStat = ErrID_None ErrMsg = "" @@ -5122,13 +5531,6 @@ SUBROUTINE WAMIT_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) CALL MeshExtrapInterp2(y1%Mesh, y2%Mesh, y3%Mesh, tin, y_out%Mesh, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) -IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN - DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) - b = (t(3)**2*(y1%WriteOutput(i1) - y2%WriteOutput(i1)) + t(2)**2*(-y1%WriteOutput(i1) + y3%WriteOutput(i1)))* scaleFactor - c = ( (t(2)-t(3))*y1%WriteOutput(i1) + t(3)*y2%WriteOutput(i1) - t(2)*y3%WriteOutput(i1) ) * scaleFactor - y_out%WriteOutput(i1) = y1%WriteOutput(i1) + b + c * t_out - END DO -END IF ! check if allocated END SUBROUTINE WAMIT_Output_ExtrapInterp2 END MODULE WAMIT_Types diff --git a/modules/hydrodyn/src/Waves.f90 b/modules/hydrodyn/src/Waves.f90 index f8ccc2dad9..5358c49a49 100644 --- a/modules/hydrodyn/src/Waves.f90 +++ b/modules/hydrodyn/src/Waves.f90 @@ -139,7 +139,7 @@ FUNCTION BoxMuller ( RNGType, NDAmp, Phase ) ! Compute intermediate variables: IF ( NDAmp ) THEN ! Normally-distributed amplitudes - C1 = SQRT( -2.0*LOG(U1(1)) ) + C1 = SQRT( -2.0*LOG(U1(1)) ) ELSE ! Constant amplitudes (ignore U1); therefore, C1 = SQRT( 2.0 ) = MEAN( SQRT( -2.0*LOG(U1) ) for a uniform distribution of U1 between 0 and 1 C1 = SQRT( 2.0 ) END IF @@ -328,7 +328,7 @@ FUNCTION WaveNumber ( Omega, g, h ) ELSE ! Omega > 0.0; solve for the wavenumber as usual. - C = Omega*Omega*h/g + C = Omega*Omega*h/REAL(g,SiKi) CC = C*C diff --git a/modules/hydrodyn/src/Waves2.f90 b/modules/hydrodyn/src/Waves2.f90 index 97ea03a202..743e87708f 100644 --- a/modules/hydrodyn/src/Waves2.f90 +++ b/modules/hydrodyn/src/Waves2.f90 @@ -343,7 +343,7 @@ SUBROUTINE Waves2_Init( InitInp, u, p, x, xd, z, OtherState, y, misc, Interval, IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,'Cannot allocate array WaveElevC0Norm.',ErrStat,ErrMsg,'Waves2_Init') DO I=0,InitInp%NStepWave2 - WaveElevC0Norm(I) = CMPLX( InitInp%WaveElevC0(1,I), InitInp%WaveElevC0(2,I) ) / REAL(InitInp%NStepWave2) + WaveElevC0Norm(I) = CMPLX( InitInp%WaveElevC0(1,I), InitInp%WaveElevC0(2,I), SiKi ) / REAL(InitInp%NStepWave2,SiKi) ENDDO !-------------------------------------------------------------------------------- @@ -642,13 +642,13 @@ SUBROUTINE Waves2_Init( InitInp, u, p, x, xd, z, OtherState, y, misc, Interval, ! Reset the \f$ H_{\mu^-} \f$ terms to zero before calculating. - WaveVel2xCDiff = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveVel2yCDiff = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveVel2zCDiff = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveAcc2xCDiff = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveAcc2yCDiff = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveAcc2zCDiff = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveDynP2CDiff = CMPLX(0.0_SiKi, 0.0_SiKi) + WaveVel2xCDiff = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveVel2yCDiff = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveVel2zCDiff = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveAcc2xCDiff = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveAcc2yCDiff = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveAcc2zCDiff = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveDynP2CDiff = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) ! \f$ \mu^- \f$ loop. This loop is used to construct the full set of \f$ H_{\mu^-} \f$ terms used in the IFFT to find the timeseries. @@ -683,8 +683,8 @@ SUBROUTINE Waves2_Init( InitInp, u, p, x, xd, z, OtherState, y, misc, Interval, !! + \left( |\vec{k_n}| \sin \theta_n - |\vec{k_m}| sin \theta_m \right) ~ y \right] \right) \f$ WaveElevxyPrime0 = exp( - ImagNmbr & - * ( ( k_n * COS( D2R*InitInp%WaveDirArr(n) ) - k_m * COS( D2R*InitInp%WaveDirArr(m) ) ) * InitInp%WaveKinxi(WaveKinPrimeMap(I)) & - + ( k_n * SIN( D2R*InitInp%WaveDirArr(n) ) - k_m * SIN( D2R*InitInp%WaveDirArr(m) ) ) * InitInp%WaveKinyi(WaveKinPrimeMap(I)) )) + * ( ( k_n * COS( D2R_S*InitInp%WaveDirArr(n) ) - k_m * COS( D2R_S*InitInp%WaveDirArr(m) ) ) * InitInp%WaveKinxi(WaveKinPrimeMap(I)) & + + ( k_n * SIN( D2R_S*InitInp%WaveDirArr(n) ) - k_m * SIN( D2R_S*InitInp%WaveDirArr(m) ) ) * InitInp%WaveKinyi(WaveKinPrimeMap(I)) )) ! Get value for \f$ B^- \f$ for the n,m index pair @@ -694,10 +694,10 @@ SUBROUTINE Waves2_Init( InitInp, u, p, x, xd, z, OtherState, y, misc, Interval, !> Calculate \f$ U^- \f$ terms for the velocity calculations (\f$B^-\f$ provided by waves2::transfuncb_minus) ! NOTE: InitInp%WtrDpth + WaveKinzi0Prime(I) is the height above the ocean floor !> * \f$ _x{U}_{nm}^- = B_{nm}^- \left(k_n \cos \theta_n - k_m \cos \theta_m \right) \f$ - Ux_nm_minus = B_minus * ( k_n * COS( D2R*InitInp%WaveDirArr(n) ) - k_m * COS( D2R*InitInp%WaveDirArr(m) ) ) + Ux_nm_minus = B_minus * ( k_n * COS( D2R_S*InitInp%WaveDirArr(n) ) - k_m * COS( D2R_S*InitInp%WaveDirArr(m) ) ) !> * \f$ _y{U}_{nm}^- = B_{nm}^- \left(k_n \sin \theta_n - k_m \sin \theta_m \right) \f$ - Uy_nm_minus = B_minus * ( k_n * SIN( D2R*InitInp%WaveDirArr(n) ) - k_m * SIN( D2R*InitInp%WaveDirArr(m) ) ) + Uy_nm_minus = B_minus * ( k_n * SIN( D2R_S*InitInp%WaveDirArr(n) ) - k_m * SIN( D2R_S*InitInp%WaveDirArr(m) ) ) !> * \f$ _z{U}_{nm}^- = \imath B_{nm}^- k_{nm} \tanh \left( k_{nm} ( h + z ) \right) \f$ Uz_nm_minus = ImagNmbr * B_minus * k_nm * tanh( k_nm * ( InitInp%WtrDpth + WaveKinzi0Prime(I) ) ) @@ -711,7 +711,7 @@ SUBROUTINE Waves2_Init( InitInp, u, p, x, xd, z, OtherState, y, misc, Interval, !> Dynamic pressure !> * \f$ P_{nm}^- = \rho_\mathrm{w} B_{nm}^- \omega_{\mu^-} \f$ - DynP_nm_minus = InitInp%WtrDens * B_minus * Omega_minus + DynP_nm_minus = REAL(InitInp%WtrDens,SiKi) * B_minus * Omega_minus @@ -1013,21 +1013,21 @@ SUBROUTINE Waves2_Init( InitInp, u, p, x, xd, z, OtherState, y, misc, Interval, ! Reset the \f$ H_{\mu^+} \f$ terms to zero before calculating. - WaveVel2xCSumT1 = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveVel2yCSumT1 = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveVel2zCSumT1 = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveAcc2xCSumT1 = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveAcc2yCSumT1 = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveAcc2zCSumT1 = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveDynP2CSumT1 = CMPLX(0.0_SiKi, 0.0_SiKi) - - WaveVel2xCSumT2 = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveVel2yCSumT2 = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveVel2zCSumT2 = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveAcc2xCSumT2 = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveAcc2yCSumT2 = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveAcc2zCSumT2 = CMPLX(0.0_SiKi, 0.0_SiKi) - WaveDynP2CSumT2 = CMPLX(0.0_SiKi, 0.0_SiKi) + WaveVel2xCSumT1 = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveVel2yCSumT1 = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveVel2zCSumT1 = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveAcc2xCSumT1 = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveAcc2yCSumT1 = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveAcc2zCSumT1 = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveDynP2CSumT1 = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + + WaveVel2xCSumT2 = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveVel2yCSumT2 = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveVel2zCSumT2 = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveAcc2xCSumT2 = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveAcc2yCSumT2 = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveAcc2zCSumT2 = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) + WaveDynP2CSumT2 = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) !--------------- @@ -1069,8 +1069,8 @@ SUBROUTINE Waves2_Init( InitInp, u, p, x, xd, z, OtherState, y, misc, Interval, !! + |\vec{k_n}| \sin \theta_n ~ y \right] \right) \f$ WaveElevxyPrime0 = exp( - ImagNmbr & - * ( 2.0_SiKi * k_n * COS( D2R*InitInp%WaveDirArr(n) ) * InitInp%WaveKinxi(WaveKinPrimeMap(I)) & - + 2.0_SiKi * k_n * SIN( D2R*InitInp%WaveDirArr(n) ) * InitInp%WaveKinyi(WaveKinPrimeMap(I)) )) + * ( 2.0_SiKi * k_n * COS( D2R_S*InitInp%WaveDirArr(n) ) * InitInp%WaveKinxi(WaveKinPrimeMap(I)) & + + 2.0_SiKi * k_n * SIN( D2R_S*InitInp%WaveDirArr(n) ) * InitInp%WaveKinyi(WaveKinPrimeMap(I)) )) ! Get value for \f$ B+ \f$ for the n,m index pair @@ -1080,10 +1080,10 @@ SUBROUTINE Waves2_Init( InitInp, u, p, x, xd, z, OtherState, y, misc, Interval, !> Calculate \f$ U^+ \f$ terms for the velocity calculations (\f$B^+\f$ provided by waves2::transfuncb_plus) ! NOTE: InitInp%WtrDpth + WaveKinzi0Prime(I) is the height above the ocean floor !> * \f$ _x{U}_{nn}^+ = B_{nn}^+ 2 k_n \cos \theta_n \f$ - Ux_nm_plus = B_plus * 2.0_SiKi * k_n * COS( D2R*InitInp%WaveDirArr(n) ) + Ux_nm_plus = B_plus * 2.0_SiKi * k_n * COS( D2R_S*InitInp%WaveDirArr(n) ) !> * \f$ _y{U}_{nn}^+ = B_{nn}^+ 2 k_n \sin \theta_n \f$ - Uy_nm_plus = B_plus * 2.0_SiKi * k_n * SIN( D2R*InitInp%WaveDirArr(n) ) + Uy_nm_plus = B_plus * 2.0_SiKi * k_n * SIN( D2R_S*InitInp%WaveDirArr(n) ) !> * \f$ _z{U}_{nn}^+ = \imath B_{nn}^+ k_{nn} \tanh \left( k_{nn} ( h + z ) \right) \f$ Uz_nm_plus = ImagNmbr * B_plus * k_nm * tanh( k_nm * ( InitInp%WtrDpth + WaveKinzi0Prime(I) ) ) @@ -1097,7 +1097,7 @@ SUBROUTINE Waves2_Init( InitInp, u, p, x, xd, z, OtherState, y, misc, Interval, !> Dynamic pressure !> * \f$ P_{nn}^+ = \rho_\mathrm{w} B_{nn}^+ \omega_{\mu^+} \f$ - DynP_nm_plus = InitInp%WtrDens * B_plus * Omega_plus + DynP_nm_plus = REAL(InitInp%WtrDens, SiKi) * B_plus * Omega_plus @@ -1171,8 +1171,8 @@ SUBROUTINE Waves2_Init( InitInp, u, p, x, xd, z, OtherState, y, misc, Interval, !! + \left( |\vec{k_n}| \sin \theta_n + |\vec{k_m}| sin \theta_m \right) ~ y \right] \right) \f$ WaveElevxyPrime0 = exp( - ImagNmbr & - * ( ( k_n * COS( D2R*InitInp%WaveDirArr(n) ) + k_m * COS( D2R*InitInp%WaveDirArr(m) ) ) * InitInp%WaveKinxi(WaveKinPrimeMap(I)) & - + ( k_n * SIN( D2R*InitInp%WaveDirArr(n) ) + k_m * SIN( D2R*InitInp%WaveDirArr(m) ) ) * InitInp%WaveKinyi(WaveKinPrimeMap(I)) )) + * ( ( k_n * COS( D2R_S*InitInp%WaveDirArr(n) ) + k_m * COS( D2R_S*InitInp%WaveDirArr(m) ) ) * InitInp%WaveKinxi(WaveKinPrimeMap(I)) & + + ( k_n * SIN( D2R_S*InitInp%WaveDirArr(n) ) + k_m * SIN( D2R_S*InitInp%WaveDirArr(m) ) ) * InitInp%WaveKinyi(WaveKinPrimeMap(I)) )) ! Get value for \f$ B+ \f$ for the n,m index pair @@ -1182,10 +1182,10 @@ SUBROUTINE Waves2_Init( InitInp, u, p, x, xd, z, OtherState, y, misc, Interval, !> Calculate \f$ U^+ \f$ terms for the velocity calculations (\f$B^+\f$ provided by waves2::transfuncb_plus) ! NOTE: InitInp%WtrDpth + WaveKinzi0Prime(I) is the height above the ocean floor !> * \f$ _x{U}_{nm}^+ = B_{nm}^+ \left(k_n \cos \theta_n + k_m \cos \theta_m \right) \f$ - Ux_nm_plus = B_plus * ( k_n * COS( D2R*InitInp%WaveDirArr(n) ) + k_m * COS( D2R*InitInp%WaveDirArr(m) ) ) + Ux_nm_plus = B_plus * ( k_n * COS( D2R_S*InitInp%WaveDirArr(n) ) + k_m * COS( D2R_S*InitInp%WaveDirArr(m) ) ) !> * \f$ _y{U}_{nm}^+ = B_{nm}^+ \left(k_n \sin \theta_n + k_m \sin \theta_m \right) \f$ - Uy_nm_plus = B_plus * ( k_n * SIN( D2R*InitInp%WaveDirArr(n) ) + k_m * SIN( D2R*InitInp%WaveDirArr(m) ) ) + Uy_nm_plus = B_plus * ( k_n * SIN( D2R_S*InitInp%WaveDirArr(n) ) + k_m * SIN( D2R_S*InitInp%WaveDirArr(m) ) ) !> * \f$ _z{U}_{nm}^+ = \imath B_{nm}^+ k_{nm} \tanh \left( k_{nm} ( h + z ) \right) \f$ Uz_nm_plus = ImagNmbr * B_plus * k_nm * tanh( k_nm * ( InitInp%WtrDpth + WaveKinzi0Prime(I) ) ) @@ -1199,7 +1199,7 @@ SUBROUTINE Waves2_Init( InitInp, u, p, x, xd, z, OtherState, y, misc, Interval, !> Dynamic pressure !> * \f$ P_{nm}^+ = \rho_\mathrm{w} B_{nm}^+ \omega_{\mu^+} \f$ - DynP_nm_plus = InitInp%WtrDens * B_plus * Omega_plus + DynP_nm_plus = REAL(InitInp%WtrDens,SiKi) * B_plus * Omega_plus @@ -1439,7 +1439,7 @@ SUBROUTINE WaveElevTimeSeriesAtXY_Diff(Xcoord,Ycoord, WaveElevSeriesAtXY, ErrSta ! Note that TmpFreqSeries was allocated in the calling routine. Probably bad programming ! practice, but I didn't want to have to allocate it at each point. - TmpFreqSeries = CMPLX(0.0_SiKi, 0.0_SiKi) + TmpFreqSeries = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) WaveElevSeriesAtXY = 0.0_SiKi ! \f$ \mu^- \f$ loop. This loop is used to construct the full set of \f$ H_{\mu^-} \f$ terms used in the IFFT to find the timeseries. @@ -1471,7 +1471,7 @@ SUBROUTINE WaveElevTimeSeriesAtXY_Diff(Xcoord,Ycoord, WaveElevSeriesAtXY, ErrSta !! !! The value of \f$ D^-_{nm} \f$ is found from by the ::TransFuncD_minus routine. - L_minus = (( D_minus - k_n * k_m * COS(D2R*InitInp%WaveDirArr(n) - D2R*InitInp%WaveDirArr(m)) - R_n * R_m )/SQRT( R_n * R_m ) + R_n + R_m) / 4.0_SiKi !4.0_SiKi + L_minus = (( D_minus - k_n * k_m * COS(D2R_S*InitInp%WaveDirArr(n) - D2R_S*InitInp%WaveDirArr(m)) - R_n * R_m )/SQRT( R_n * R_m ) + R_n + R_m) / 4.0_SiKi !4.0_SiKi ! Calculate the terms \f$ n,m \f$ necessary for calculations @@ -1485,8 +1485,8 @@ SUBROUTINE WaveElevTimeSeriesAtXY_Diff(Xcoord,Ycoord, WaveElevSeriesAtXY, ErrSta !! + \left( |\vec{k_n}| \sin \theta_n - |\vec{k_m}| sin \theta_m \right) ~ y \right] \right) \f$ WaveElevxyPrime0 = exp( - ImagNmbr & - * ( ( k_n * COS( D2R*InitInp%WaveDirArr(n) ) - k_m * COS( D2R*InitInp%WaveDirArr(m) ) ) * XCoord & - + ( k_n * SIN( D2R*InitInp%WaveDirArr(n) ) - k_m * SIN( D2R*InitInp%WaveDirArr(m) ) ) * YCoord )) + * ( ( k_n * COS( D2R_S*InitInp%WaveDirArr(n) ) - k_m * COS( D2R_S*InitInp%WaveDirArr(m) ) ) * XCoord & + + ( k_n * SIN( D2R_S*InitInp%WaveDirArr(n) ) - k_m * SIN( D2R_S*InitInp%WaveDirArr(m) ) ) * YCoord )) !> ### Calculate the inner summation \f$ H^-(\omega_{\mu^-}) \f$ terms for the velocity, acceleration, and pressure. ### @@ -1567,8 +1567,8 @@ SUBROUTINE WaveElevTimeSeriesAtXY_Sum(Xcoord,Ycoord, WaveElevSeriesAtXY, ErrStat ! Note that TmpFreqSeries was allocated in the calling routine. Probably bad programming ! practice, but I didn't want to have to allocate it at each point. - TmpFreqSeries = CMPLX(0.0_SiKi, 0.0_SiKi) ! used for first term - TmpFreqSeries2 = CMPLX(0.0_SiKi, 0.0_SiKi) ! used for second term + TmpFreqSeries = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) ! used for first term + TmpFreqSeries2 = CMPLX(0.0_SiKi, 0.0_SiKi, SiKi) ! used for second term WaveElevSeriesAtXY = 0.0_SiKi @@ -1607,8 +1607,8 @@ SUBROUTINE WaveElevTimeSeriesAtXY_Sum(Xcoord,Ycoord, WaveElevSeriesAtXY, ErrStat !! + |\vec{k_n}| \sin \theta_n ~ y \right] \right) \f$ WaveElevxyPrime0 = exp( - ImagNmbr & - * ( 2.0_SiKi * k_n * COS( D2R*InitInp%WaveDirArr(n) ) * XCoord & - + 2.0_SiKi * k_n * SIN( D2R*InitInp%WaveDirArr(n) ) * YCoord )) + * ( 2.0_SiKi * k_n * COS( D2R_S*InitInp%WaveDirArr(n) ) * XCoord & + + 2.0_SiKi * k_n * SIN( D2R_S*InitInp%WaveDirArr(n) ) * YCoord )) ! First get the wave amplitude -- must be reconstructed from the WaveElevC0 array. First index is the real (1) or ! imaginary (2) part. Divide by NStepWave2 to remove the built in normalization in WaveElevC0. Note that the phase @@ -1663,7 +1663,7 @@ SUBROUTINE WaveElevTimeSeriesAtXY_Sum(Xcoord,Ycoord, WaveElevSeriesAtXY, ErrStat !! + (R_n+R_m) \right] \f$ !! !! The value of \f$ D^-_{nm} \f$ is found from by the ::TransFuncD_plus routine. - L_plus = (( D_plus - k_n * k_m * COS(D2R*InitInp%WaveDirArr(n) - D2R*InitInp%WaveDirArr(m)) + R_n * R_m )/SQRT( R_n * R_m ) + R_n + R_m) / 4.0_SiKi + L_plus = (( D_plus - k_n * k_m * COS(D2R_S*InitInp%WaveDirArr(n) - D2R_S*InitInp%WaveDirArr(m)) + R_n * R_m )/SQRT( R_n * R_m ) + R_n + R_m) / 4.0_SiKi !> Calculate the dot product of the wavenumbers with the (x,y) location !! This is given by: @@ -1674,8 +1674,8 @@ SUBROUTINE WaveElevTimeSeriesAtXY_Sum(Xcoord,Ycoord, WaveElevSeriesAtXY, ErrStat !! + \left( |\vec{k_n}| \sin \theta_n + |\vec{k_m}| sin \theta_m \right) ~ y \right] \right) \f$ WaveElevxyPrime0 = exp( - ImagNmbr & - * ( ( k_n * COS( D2R*InitInp%WaveDirArr(n) ) + k_m * COS( D2R*InitInp%WaveDirArr(m) ) ) * XCoord & - + ( k_n * SIN( D2R*InitInp%WaveDirArr(n) ) + k_m * SIN( D2R*InitInp%WaveDirArr(m) ) ) * YCoord )) + * ( ( k_n * COS( D2R_S*InitInp%WaveDirArr(n) ) + k_m * COS( D2R_S*InitInp%WaveDirArr(m) ) ) * XCoord & + + ( k_n * SIN( D2R_S*InitInp%WaveDirArr(n) ) + k_m * SIN( D2R_S*InitInp%WaveDirArr(m) ) ) * YCoord )) @@ -1778,7 +1778,7 @@ FUNCTION TransFuncB_minus(n,m,k_n,k_m,z) ! Calculation of B_minus - TransFuncB_minus = InitInp%Gravity*InitInp%Gravity / ( 4.0_SiKi * Omega_n * Omega_m ) & + TransFuncB_minus = REAL(InitInp%Gravity*InitInp%Gravity,SiKi) / ( 4.0_SiKi * Omega_n * Omega_m ) & * COSHNumOvrCOSHDen(k_nm, REAL(InitInp%WtrDpth,SiKi), z) * D_minus / ( Omega_n - Omega_m ) @@ -1839,7 +1839,7 @@ FUNCTION TransFuncB_plus(n,m,k_n,k_m,z) D_plus = TransFuncD_plus(n,m,k_n,k_m,R_n,R_m) ! Calculation of B_plus - TransFuncB_plus = InitInp%Gravity*InitInp%Gravity / ( 4.0_SiKi * Omega_n * Omega_m ) & + TransFuncB_plus = REAL(InitInp%Gravity*InitInp%Gravity,SiKi) / ( 4.0_SiKi * Omega_n * Omega_m ) & * COSHNumOvrCOSHDen(k_nm, REAL(InitInp%WtrDpth,SiKi), z) * D_plus / ( Omega_n + Omega_m ) @@ -1955,7 +1955,7 @@ FUNCTION TransFuncD_minus(n,m,k_n,k_m,R_n,R_m) ! Calculate the two pieces of the numerator Num1 = SqrtRnMinusRm * ( SQRT(R_m) * ( k_n*k_n - R_n*R_n ) - SQRT(R_n) * ( k_m*k_m - R_m*R_m ) ) - Num2 = 2*SqrtRnMinusRm*SqrtRnMinusRm*( k_n * k_m * COS( D2R*InitInp%WaveDirArr(n) - D2R*InitInp%WaveDirArr(m) ) + R_n*R_m ) + Num2 = 2*SqrtRnMinusRm*SqrtRnMinusRm*( k_n * k_m * COS( D2R_S*InitInp%WaveDirArr(n) - D2R_S*InitInp%WaveDirArr(m) ) + R_n*R_m ) ! Calculate the denominator Den = SqrtRnMinusRm*SqrtRnMinusRm - k_nm * tanh( k_nm * InitInp%WtrDpth ) @@ -2019,7 +2019,7 @@ FUNCTION TransFuncD_plus(n,m,k_n,k_m,R_n,R_m) ! Calculate the two pieces of the numerator Num1 = SqrtRnPlusRm * ( SQRT(R_m) * ( k_n*k_n - R_n*R_n ) + SQRT(R_n) * ( k_m*k_m - R_m*R_m ) ) - Num2 = 2*SqrtRnPlusRm*SqrtRnPlusRm*( k_n * k_m * COS( D2R*InitInp%WaveDirArr(n) - D2R*InitInp%WaveDirArr(m) ) - R_n*R_m ) + Num2 = 2*SqrtRnPlusRm*SqrtRnPlusRm*( k_n * k_m * COS( D2R_S*InitInp%WaveDirArr(n) - D2R_S*InitInp%WaveDirArr(m) ) - R_n*R_m ) ! Calculate the denominator Den = SqrtRnPlusRm*SqrtRnPlusRm - k_nm * tanh( k_nm * InitInp%WtrDpth ) @@ -2053,7 +2053,7 @@ FUNCTION k_nm_minus(n,m,k_n,k_m) k_nm_minus = 0.0_SiKi ! This is just to eliminate any numerical error ELSE !bjj: added abs() because we were getting very small negative numbers here (which should be 0). - k_nm_minus = sqrt( abs( k_n * k_n + k_m * k_m - 2 * k_n * k_m * cos( D2R*InitInp%WaveDirArr(n) - D2R*InitINp%WaveDirArr(m) ) ) ) + k_nm_minus = sqrt( abs( k_n * k_n + k_m * k_m - 2 * k_n * k_m * cos( D2R_S*InitInp%WaveDirArr(n) - D2R_S*InitINp%WaveDirArr(m) ) ) ) ENDIF END FUNCTION k_nm_minus @@ -2078,7 +2078,7 @@ FUNCTION k_nm_plus(n,m,k_n,k_m) IF (n == m ) THEN k_nm_plus = 2.0_SiKi * k_n ! This is just to eliminate any numerical error. ELSE - k_nm_plus = sqrt( k_n * k_n + k_m * k_m + 2 * k_n * k_m * cos( D2R*InitInp%WaveDirArr(n) - D2R*InitINp%WaveDirArr(m) ) ) + k_nm_plus = sqrt( k_n * k_n + k_m * k_m + 2_SiKi * k_n * k_m * cos( D2R_S*InitInp%WaveDirArr(n) - D2R_S*InitINp%WaveDirArr(m) ) ) ENDIF END FUNCTION k_nm_plus diff --git a/modules/inflowwind/src/InflowWind.f90 b/modules/inflowwind/src/InflowWind.f90 index ee9701f585..555afde4a2 100644 --- a/modules/inflowwind/src/InflowWind.f90 +++ b/modules/inflowwind/src/InflowWind.f90 @@ -221,7 +221,7 @@ SUBROUTINE InflowWind_Init( InitInp, InputGuess, p, ContStates, DiscStates, ENDIF - CALL InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, TmpErrStat, TmpErrMsg ) + CALL InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, InitInp%InputFileName, EchoFileName, TmpErrStat, TmpErrMsg ) CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() diff --git a/modules/inflowwind/src/InflowWind_Subs.f90 b/modules/inflowwind/src/InflowWind_Subs.f90 index b9251606f7..0cdb22e911 100644 --- a/modules/inflowwind/src/InflowWind_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Subs.f90 @@ -156,7 +156,7 @@ MODULE InflowWind_Subs !==================================================================================================== !> This public subroutine parses the array of strings in InputFileData for the input parameters. -SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, ErrStat, ErrMsg ) +SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, InputFileName, EchoFileName, ErrStat, ErrMsg ) !---------------------------------------------------------------------------------------------------- IMPLICIT NONE @@ -166,55 +166,74 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, Er TYPE(InflowWind_InputFile), INTENT(INOUT) :: InputFileData !< Data of the InflowWind Input File TYPE(FileInfoType), INTENT(IN ) :: InFileInfo !< The derived type for holding the file information CHARACTER(*), INTENT(IN ) :: PriPath !< Path to InflowWind input files + CHARACTER(*), intent(in ) :: InputFileName !< The name of the input file + CHARACTER(*), intent(in ) :: EchoFileName !< The name of the echo file, possibly opened in this routine INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Returned error status from this subroutine CHARACTER(*), INTENT( OUT) :: ErrMsg !< Returned error message from this subroutine ! Local variables INTEGER(IntKi) :: CurLine !< Current entry in InFileInfo%Lines array + INTEGER(IntKi) :: UnEc !< local echo unit ! Temoporary messages INTEGER(IntKi) :: TmpErrStat CHARACTER(ErrMsgLen) :: TmpErrMsg - ! Initializatio + ! Initialization ErrStat = ErrID_None ErrMsg = "" InputFileData%EchoFlag = .FALSE. ! initialize for error handling (cleanup() routine) + UnEc = -1 ! Allocate the array for the OutList CALL AllocAry( InputFileData%OutList, MaxOutPts, "InflowWind Input File's OutList", TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return !--------------------------------------------------------------------------------------------- ! General settings with wind type, direction and output point list (applies to all wind types) !--------------------------------------------------------------------------------------------- CurLine = 4 - CALL ParseVar( InFileInfo, CurLine, "Echo", InputFileData%EchoFlag, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "Echo", InputFileData%EchoFlag, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return + + if ( InputFileData%EchoFlag ) then + CALL OpenEcho ( UnEc, TRIM(EchoFileName), TmpErrStat, TmpErrMsg ) + if (Failed()) return; + WRITE(UnEc, '(A)') 'Echo file for InflowWind input file: '//trim(InputFileName) + ! Write the first three lines into the echo file + WRITE(UnEc, '(A)') InFileInfo%Lines(1) + WRITE(UnEc, '(A)') InFileInfo%Lines(2) + WRITE(UnEc, '(A)') InFileInfo%Lines(3) + + CurLine = 4 + CALL ParseVar( InFileInfo, CurLine, "Echo", InputFileData%EchoFlag, TmpErrStat, TmpErrMsg, UnEc ) + if (Failed()) return + endif + ! switch for wind file type (1=steady; 2=uniform; 3=binary TurbSim FF; 4=binary Bladed-style FF; 5=HAWC format; 6=User defined; 7=native Bladed FF) - CALL ParseVar( InFileInfo, CurLine, "WindType", InputFileData%WindType, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "WindType", InputFileData%WindType, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return ! Direction of wind propagation (meteorological direction) (deg) - CALL ParseVar( InFileInfo, CurLine, "PropagationDir", InputFileData%PropagationDir, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "PropagationDir", InputFileData%PropagationDir, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return ! VFlowAngle: Upflow angle (deg) - CALL ParseVarWDefault( InFileInfo, CurLine, "VFlowAng", InputFileData%VFlowAngle, 0.0_ReKi, TmpErrStat, TmpErrMsg ) + CALL ParseVarWDefault( InFileInfo, CurLine, "VFlowAng", InputFileData%VFlowAngle, 0.0_ReKi, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return ! NWindVel: Number of points to output the wind velocity (0 to 9) - CALL ParseVar( InFileInfo, CurLine, "NWindVel", InputFileData%NWindVel, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "NWindVel", InputFileData%NWindVel, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return ! Before proceeding, make sure that NWindVel makes sense IF ( InputFileData%NWindVel < 0 .OR. InputFileData%NwindVel > 9 ) THEN @@ -230,64 +249,64 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, Er CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) CALL AllocAry( InputFileData%WindVziList, InputFileData%NWindVel, 'WindVziList', TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return ENDIF - CALL ParseAry( InFileInfo, CurLine, 'WindVxiList', InputFileData%WindVxiList, InputFileData%NWindVel, TmpErrStat, TmpErrMsg ) + CALL ParseAry( InFileInfo, CurLine, 'WindVxiList', InputFileData%WindVxiList, InputFileData%NWindVel, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseAry( InFileInfo, CurLine, 'WindVyiList', InputFileData%WindVyiList, InputFileData%NWindVel, TmpErrStat, TmpErrMsg ) + CALL ParseAry( InFileInfo, CurLine, 'WindVyiList', InputFileData%WindVyiList, InputFileData%NWindVel, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseAry( InFileInfo, CurLine, 'WindVziList', InputFileData%WindVziList, InputFileData%NWindVel, TmpErrStat, TmpErrMsg ) + CALL ParseAry( InFileInfo, CurLine, 'WindVziList', InputFileData%WindVziList, InputFileData%NWindVel, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return !------------------------------------------------------------------------------------------------- !> Read the _Parameters for Steady Wind Conditions [used only for WindType = 1]_ section !------------------------------------------------------------------------------------------------- CurLine = CurLine + 1 ! Skip section break - CALL ParseVar( InFileInfo, CurLine, "HWindSpeed", InputFileData%Steady_HWindSpeed, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "HWindSpeed", InputFileData%Steady_HWindSpeed, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "RefHt", InputFileData%Steady_RefHt, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "RefHt", InputFileData%Steady_RefHt, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "PLexp", InputFileData%Steady_PLexp, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "PLexp", InputFileData%Steady_PLexp, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return !------------------------------------------------------------------------------------------------- !> Read the _Parameters for Uniform wind file [used only for WindType = 2]_ section !------------------------------------------------------------------------------------------------- CurLine = CurLine + 1 ! Skip section break - CALL ParseVar( InFileInfo, CurLine, "FileName_Uni", InputFileData%Uniform_FileName, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "FileName_Uni", InputFileData%Uniform_FileName, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return IF ( PathIsRelative( InputFileData%Uniform_FileName ) ) InputFileData%Uniform_FileName = TRIM(PriPath)//TRIM(InputFileData%Uniform_FileName) - CALL ParseVar( InFileInfo, CurLine, "RefHt_Uni", InputFileData%Uniform_RefHt, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "RefHt_Uni", InputFileData%Uniform_RefHt, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "RefLength", InputFileData%Uniform_RefLength, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "RefLength", InputFileData%Uniform_RefLength, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return !------------------------------------------------------------------------------------------------- !> Read the _Parameters for Binary TurbSim Full-Field files [used only for WindType = 3]_ section !------------------------------------------------------------------------------------------------- CurLine = CurLine + 1 ! Skip section break - CALL ParseVar( InFileInfo, CurLine, "FileName_BTS", InputFileData%TSFF_FileName, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "FileName_BTS", InputFileData%TSFF_FileName, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return IF ( PathIsRelative( InputFileData%TSFF_FileName ) ) InputFileData%TSFF_FileName = TRIM(PriPath)//TRIM(InputFileData%TSFF_FileName) !------------------------------------------------------------------------------------------------- @@ -295,32 +314,32 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, Er !------------------------------------------------------------------------------------------------- CurLine = CurLine + 1 ! Skip section break - CALL ParseVar( InFileInfo, CurLine, "FilenameRoot", InputFileData%BladedFF_FileName, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "FilenameRoot", InputFileData%BladedFF_FileName, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return IF ( PathIsRelative( InputFileData%BladedFF_FileName ) ) InputFileData%BladedFF_FileName = TRIM(PriPath)//TRIM(InputFileData%BladedFF_FileName) - CALL ParseVar( InFileInfo, CurLine, "TowerFile", InputFileData%BladedFF_TowerFile, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "TowerFile", InputFileData%BladedFF_TowerFile, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return !------------------------------------------------------------------------------------------------- !> Read the _Parameters for coherent turbulence [used only for WindType = 3 or 4]_ section !------------------------------------------------------------------------------------------------- ! CurLine = CurLine + 1 ! Skip section break - ! CALL ParseVar( InFileInfo, CurLine, "CTTS_CoherentTurbFlag", InputFileData%CTTS_CoherentTurb, TmpErrStat, TmpErrMsg ) + ! CALL ParseVar( InFileInfo, CurLine, "CTTS_CoherentTurbFlag", InputFileData%CTTS_CoherentTurb, TmpErrStat, TmpErrMsg, UnEc ) ! CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - ! IF (ErrStat >= AbortErrLev) RETURN + ! if (Failed()) return - ! CALL ParseVar( InFileInfo, CurLine, "CTTS_FileName", InputFileData%CTTS_FileName, TmpErrStat, TmpErrMsg ) + ! CALL ParseVar( InFileInfo, CurLine, "CTTS_FileName", InputFileData%CTTS_FileName, TmpErrStat, TmpErrMsg, UnEc ) ! CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - ! IF (ErrStat >= AbortErrLev) RETURN + ! if (Failed()) return ! IF ( PathIsRelative( InputFileData%CTTS_FileName ) ) InputFileData%CTTS_FileName = TRIM(PriPath)//TRIM(InputFileData%CTTS_FileName) - ! CALL ParseVar( InFileInfo, CurLine, "CTTS_Path", InputFileData%CTTS_Path, TmpErrStat, TmpErrMsg ) + ! CALL ParseVar( InFileInfo, CurLine, "CTTS_Path", InputFileData%CTTS_Path, TmpErrStat, TmpErrMsg, UnEc ) ! CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - ! IF (ErrStat >= AbortErrLev) RETURN + ! if (Failed()) return ! IF ( PathIsRelative( InputFileData%CTTS_Path ) ) InputFileData%CTTS_Path = TRIM(PriPath)//TRIM(InputFileData%CTTS_Path) !------------------------------------------------------------------------------------------------- @@ -328,48 +347,48 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, Er !------------------------------------------------------------------------------------------------- CurLine = CurLine + 1 ! Skip section break - CALL ParseVar( InFileInfo, CurLine, "FileName_u", InputFileData%HAWC_FileName_u, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "FileName_u", InputFileData%HAWC_FileName_u, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return IF ( PathIsRelative( InputFileData%HAWC_FileName_u ) ) InputFileData%HAWC_FileName_u = TRIM(PriPath)//TRIM(InputFileData%HAWC_FileName_u) - CALL ParseVar( InFileInfo, CurLine, "FileName_v", InputFileData%HAWC_FileName_v, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "FileName_v", InputFileData%HAWC_FileName_v, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return IF ( PathIsRelative( InputFileData%HAWC_FileName_v ) ) InputFileData%HAWC_FileName_v = TRIM(PriPath)//TRIM(InputFileData%HAWC_FileName_v) - CALL ParseVar( InFileInfo, CurLine, "FileName_w", InputFileData%HAWC_FileName_w, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "FileName_w", InputFileData%HAWC_FileName_w, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return IF ( PathIsRelative( InputFileData%HAWC_FileName_w ) ) InputFileData%HAWC_FileName_w = TRIM(PriPath)//TRIM(InputFileData%HAWC_FileName_w) - CALL ParseVar( InFileInfo, CurLine, "nx", InputFileData%HAWC_nx, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "nx", InputFileData%HAWC_nx, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "ny", InputFileData%HAWC_ny, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "ny", InputFileData%HAWC_ny, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "nz", InputFileData%HAWC_nz, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "nz", InputFileData%HAWC_nz, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "dx", InputFileData%HAWC_dx, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "dx", InputFileData%HAWC_dx, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "dy", InputFileData%HAWC_dy, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "dy", InputFileData%HAWC_dy, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "dz", InputFileData%HAWC_dz, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "dz", InputFileData%HAWC_dz, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "RefHt_HAWC", InputFileData%FF%RefHt, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "RefHt_HAWC", InputFileData%FF%RefHt, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return !---------------------------------------------------------------------------------------------- !> Read the _Scaling parameters for turbulence (HAWC-format files) [used only for WindType = 5]_ subsection @@ -377,41 +396,41 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, Er CurLine = CurLine + 1 ! Skip section break ! ScaleMethod: Turbulence scaling method [0=none, 1=direct scaling, 2= calculate scaling factor based on a desired standard deviation] - CALL ParseVar( InFileInfo, CurLine, "ScaleMethod", InputFileData%FF%ScaleMethod, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "ScaleMethod", InputFileData%FF%ScaleMethod, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "SFx", InputFileData%FF%SF(1), TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "SFx", InputFileData%FF%SF(1), TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "SFy", InputFileData%FF%SF(2), TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "SFy", InputFileData%FF%SF(2), TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "SFz", InputFileData%FF%SF(3), TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "SFz", InputFileData%FF%SF(3), TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "SigmaFx", InputFileData%FF%SigmaF(1), TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "SigmaFx", InputFileData%FF%SigmaF(1), TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "SigmaFy", InputFileData%FF%SigmaF(2), TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "SigmaFy", InputFileData%FF%SigmaF(2), TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "SigmaFz", InputFileData%FF%SigmaF(3), TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "SigmaFz", InputFileData%FF%SigmaF(3), TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - ! CALL ParseVar( InFileInfo, CurLine, "HAWC_TStart", InputFileData%FF%TStart, TmpErrStat, TmpErrMsg ) + ! CALL ParseVar( InFileInfo, CurLine, "HAWC_TStart", InputFileData%FF%TStart, TmpErrStat, TmpErrMsg, UnEc ) ! CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) ! IF (ErrStat >= AbortErrLev) THEN ! RETURN ! ENDIF - ! CALL ParseVar( InFileInfo, CurLine, "HAWC_TEnd", InputFileData%FF%TEnd, TmpErrStat, TmpErrMsg ) + ! CALL ParseVar( InFileInfo, CurLine, "HAWC_TEnd", InputFileData%FF%TEnd, TmpErrStat, TmpErrMsg, UnEc ) ! CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) ! IF (ErrStat >= AbortErrLev) THEN ! RETURN @@ -422,48 +441,56 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, Er !---------------------------------------------------------------------------------------------- CurLine = CurLine + 1 ! Skip section break - CALL ParseVar( InFileInfo, CurLine, "URef", InputFileData%FF%URef, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "URef", InputFileData%FF%URef, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return ! WindProfileType: Wind profile type (0=constant;1=logarithmic;2=power law) - CALL ParseVar( InFileInfo, CurLine, "WindProfile", InputFileData%FF%WindProfileType, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "WindProfile", InputFileData%FF%WindProfileType, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "PLExp_HAWC", InputFileData%FF%PLExp, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "PLExp_HAWC", InputFileData%FF%PLExp, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVar( InFileInfo, CurLine, "Z0", InputFileData%FF%Z0, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "Z0", InputFileData%FF%Z0, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return - CALL ParseVarWDefault( InFileInfo, CurLine, "XOffset", InputFileData%FF%XOffset, 0.0_ReKi, TmpErrStat, TmpErrMsg ) + CALL ParseVarWDefault( InFileInfo, CurLine, "XOffset", InputFileData%FF%XOffset, 0.0_ReKi, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return !---------------------------------------------------------------------------------------------- !> Read the _OUTPUT_ subsection !---------------------------------------------------------------------------------------------- CurLine = CurLine + 1 ! Skip section break - CALL ParseVar( InFileInfo, CurLine, "SumPrint", InputFileData%SumPrint, TmpErrStat, TmpErrMsg ) + CALL ParseVar( InFileInfo, CurLine, "SumPrint", InputFileData%SumPrint, TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return !---------------------- OUTLIST -------------------------------------------- CurLine = CurLine + 1 ! Skip comment line CALL ReadOutputListFromFileInfo( InFileInfo, CurLine, InputFileData%OutList, & - InputFileData%NumOuts, "OutList", "List of user-requested output channels", TmpErrStat, TmpErrMsg ) + InputFileData%NumOuts, "OutList", "List of user-requested output channels", TmpErrStat, TmpErrMsg, UnEc ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (Failed()) return !------------------------------------------------------------------------------------------------- ! This is the end of the input file !------------------------------------------------------------------------------------------------- RETURN - + CONTAINS + !------------------------------------------------------------------------------------------------- + logical function Failed() + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + if (Failed) then + if (UnEc > -1_IntKi) CLOSE( UnEc ) + endif + end function Failed END SUBROUTINE InflowWind_ParseInputFileInfo !==================================================================================================== diff --git a/modules/inflowwind/tests/ifw_test_tools.F90 b/modules/inflowwind/tests/ifw_test_tools.F90 index 0adeb610d1..bbbabbbdfc 100644 --- a/modules/inflowwind/tests/ifw_test_tools.F90 +++ b/modules/inflowwind/tests/ifw_test_tools.F90 @@ -17,7 +17,7 @@ function getInputFileData() '------- InflowWind v3.01.* INPUT FILE ------------------------------------------------------------------------- ', & 'Steady 8 m/s winds with no shear for FAST CertTests #20 and #25 ', & '--------------------------------------------------------------------------------------------------------------- ', & - ' true Echo - Echo input data to .ech (flag) ', & + ' false Echo - Echo input data to .ech (flag) ', & ' 1 WindType - switch for wind file type (1=steady; 2=uniform; 3=binary TurbSim FF; 4=binary Bladed-style FF; 5=HAWC format; 6=User defined; 7=native Bladed FF) ', & ' 0 PropagationDir - Direction of wind propagation (meteoroligical rotation from aligned with X (positive rotates towards -Y) -- degrees) ', & ' 0 VFlowAng - Upflow angle (degrees) (not used for native Bladed format WindType=7) ', & @@ -84,7 +84,7 @@ function getInputFileDataWindType2() '------- InflowWind v3.01.* INPUT FILE ------------------------------------------------------------------------- ', & 'Steady 8 m/s winds with no shear for FAST CertTests #20 and #25 ', & '--------------------------------------------------------------------------------------------------------------- ', & - ' true Echo - Echo input data to .ech (flag) ', & + ' true Echo - Echo input data to .ech (flag) ', & ' 2 WindType - switch for wind file type (1=steady; 2=uniform; 3=binary TurbSim FF; 4=binary Bladed-style FF; 5=HAWC format; 6=User defined; 7=native Bladed FF) ', & ' 0 PropagationDir - Direction of wind propagation (meteoroligical rotation from aligned with X (positive rotates towards -Y) -- degrees) ', & ' 0 VFlowAng - Upflow angle (degrees) (not used for native Bladed format WindType=7) ', & diff --git a/modules/inflowwind/tests/test_bladed_wind.F90 b/modules/inflowwind/tests/test_bladed_wind.F90 index 72bbd35f00..fe9755d8aa 100644 --- a/modules/inflowwind/tests/test_bladed_wind.F90 +++ b/modules/inflowwind/tests/test_bladed_wind.F90 @@ -24,7 +24,7 @@ subroutine test_bladed_wind_input() PriPath = "" InFileInfo = getInputFileData() - CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, "inputFile.inp", "test.ech", TmpErrStat, TmpErrMsg) @assertEqual(0, TmpErrStat, message='Error message: '//trim(TmpErrMsg)//NewLine//'ErrStat: ') @assertEqual(trim(expected), InputFileData%BladedFF_FileName) diff --git a/modules/inflowwind/tests/test_hawc_wind.F90 b/modules/inflowwind/tests/test_hawc_wind.F90 index 4de432a9af..158cda1d00 100644 --- a/modules/inflowwind/tests/test_hawc_wind.F90 +++ b/modules/inflowwind/tests/test_hawc_wind.F90 @@ -28,7 +28,7 @@ subroutine test_hawc_wind_input() expected_fnw = "wasp\Output\basic_5w.bin" InFileInfo = getInputFileData() - CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, "inputFile.inp", "test.ech", TmpErrStat, TmpErrMsg) @assertEqual(0, TmpErrStat, message='Error message: '//trim(TmpErrMsg)//NewLine//'ErrStat: ') diff --git a/modules/inflowwind/tests/test_outputs.F90 b/modules/inflowwind/tests/test_outputs.F90 index b6af55a79c..d2e403dd4d 100644 --- a/modules/inflowwind/tests/test_outputs.F90 +++ b/modules/inflowwind/tests/test_outputs.F90 @@ -21,7 +21,7 @@ subroutine test_outputs_parsing() PriPath = "" InFileInfo = getInputFileData() - CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, "inputFile.inp", "test.ech", TmpErrStat, TmpErrMsg) @assertEqual(0, TmpErrStat, message='Error message: '//trim(TmpErrMsg)//NewLine//'ErrStat: ') @assertEqual(.FALSE., InputFileData%SumPrint) @@ -50,7 +50,7 @@ subroutine test_outputs_parsing_alternate() '"Wind1VelX,Wind1VelY" - Wind velocity at point WindVxiList(1),WindVyiList(1),WindVziList(1). X, Y, and Z direction components. ' & /) - CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, "inputFile.inp", "test.ech", TmpErrStat, TmpErrMsg) @assertEqual(0, TmpErrStat, message='Error message: '//trim(TmpErrMsg)//NewLine//'ErrStat: ') @assertEqual(.TRUE., InputFileData%SumPrint) diff --git a/modules/inflowwind/tests/test_steady_wind.F90 b/modules/inflowwind/tests/test_steady_wind.F90 index 1e6f86c794..1917ae94fd 100644 --- a/modules/inflowwind/tests/test_steady_wind.F90 +++ b/modules/inflowwind/tests/test_steady_wind.F90 @@ -21,7 +21,7 @@ subroutine test_steady_wind_input_single_height() PriPath = "" InFileInfo = getInputFileData() - CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, "inputFile.inp", "test.ech", TmpErrStat, TmpErrMsg) @assertEqual(0, TmpErrStat, message='Error message: '//trim(TmpErrMsg)//NewLine//'ErrStat: ') @assertEqual(1, InputFileData%WindType) @@ -50,7 +50,7 @@ subroutine test_steady_wind_input_mult_heights() ' 80,100 WindVziList - List of coordinates in the inertial Z direction (m) ' & /) - CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, "inputFile.inp", "test.ech", TmpErrStat, TmpErrMsg) @assertEqual(0, TmpErrStat, message='Error message: '//trim(TmpErrMsg)//NewLine//'ErrStat: ') @assertEqual(1, InputFileData%WindType) diff --git a/modules/inflowwind/tests/test_turbsim_wind.F90 b/modules/inflowwind/tests/test_turbsim_wind.F90 index 975e34cf39..e56df74c74 100644 --- a/modules/inflowwind/tests/test_turbsim_wind.F90 +++ b/modules/inflowwind/tests/test_turbsim_wind.F90 @@ -24,7 +24,7 @@ subroutine test_steady_wind_input_single_height() PriPath = "" InFileInfo = getInputFileData() - CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, "inputFile.inp", "test.ech", TmpErrStat, TmpErrMsg) @assertEqual(0, TmpErrStat, message='Error message: '//trim(TmpErrMsg)//NewLine//'ErrStat: ') @assertEqual(trim(expected), InputFileData%TSFF_FileName) diff --git a/modules/inflowwind/tests/test_uniform_wind.F90 b/modules/inflowwind/tests/test_uniform_wind.F90 index 2d636c0f24..ced5f198c8 100644 --- a/modules/inflowwind/tests/test_uniform_wind.F90 +++ b/modules/inflowwind/tests/test_uniform_wind.F90 @@ -25,7 +25,7 @@ subroutine test_uniform_wind_input() PriPath = "" InFileInfo = getInputFileData() - CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, TmpErrStat, TmpErrMsg) + CALL InflowWind_ParseInputFileInfo(InputFileData , InFileInfo, PriPath, "inputFile.inp", "test.ech", TmpErrStat, TmpErrMsg) @assertEqual(0, TmpErrStat, message='Error message: '//trim(TmpErrMsg)//NewLine//'ErrStat: ') @assertEqual(trim(expected), InputFileData%Uniform_FileName) diff --git a/modules/map/CMakeLists.txt b/modules/map/CMakeLists.txt index d1d73bfc1c..2bf1de3f4c 100644 --- a/modules/map/CMakeLists.txt +++ b/modules/map/CMakeLists.txt @@ -20,6 +20,7 @@ if(WIN32 OR CYGWIN OR MINGW) endif() if (GENERATE_TYPES) + generate_f90_types(src/MAP_Fortran_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/MAP_Fortran_Types.f90 -noextrap) generate_f90_types(src/MAP_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/MAP_Types.f90 -ccode) generate_f90_types(src/MAP_Fortran_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/MAP_Fortran_Types.f90 -noextrap) endif() diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index 7c012801c6..4d1accbd50 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -65,8 +65,8 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er INTEGER(IntKi) :: Converged ! flag indicating whether the dynamic relaxation has converged INTEGER(IntKi) :: N ! convenience integer for readability: number of segments in the line REAL(ReKi) :: Pos(3) ! array for setting absolute fairlead positions in mesh - REAL(ReKi) :: TransMat(3,3) ! rotation matrix for setting fairlead positions correctly if there is initial platform rotation - REAL(ReKi), ALLOCATABLE :: FairTensIC(:,:)! array of size Nfairs, 3 to store three latest fairlead tensions of each line + REAL(DbKi) :: TransMat(3,3) ! rotation matrix for setting fairlead positions correctly if there is initial platform rotation + REAL(DbKi), ALLOCATABLE :: FairTensIC(:,:)! array of size Nfairs, 3 to store three latest fairlead tensions of each line CHARACTER(20) :: TempString ! temporary string for incidental use INTEGER(IntKi) :: ErrStat2 ! Error status of the operation CHARACTER(ErrMsgLen) :: ErrMsg2 ! Error message if ErrStat2 /= ErrID_None @@ -259,9 +259,9 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er u%PtFairleadDisplacement%TranslationDisp(3,i) = InitInp%PtfmInit(3) + Transmat(1,3)*Pos(1) + Transmat(2,3)*Pos(2) + TransMat(3,3)*Pos(3) - Pos(3) ! set velocity of each node to zero - u%PtFairleadDisplacement%TranslationVel(1,i) = 0.0_ReKi - u%PtFairleadDisplacement%TranslationVel(2,i) = 0.0_ReKi - u%PtFairleadDisplacement%TranslationVel(3,i) = 0.0_ReKi + u%PtFairleadDisplacement%TranslationVel(1,i) = 0.0_DbKi + u%PtFairleadDisplacement%TranslationVel(2,i) = 0.0_DbKi + u%PtFairleadDisplacement%TranslationVel(3,i) = 0.0_DbKi !print *, 'Fairlead ', i, ' z TranslationDisp at start is ', u%PtFairleadDisplacement%TranslationDisp(3,i) !print *, 'Fairlead ', i, ' z Position at start is ', u%PtFairleadDisplacement%Position(3,i) @@ -300,16 +300,16 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er m%ConnectList(I)%r(1) = m%ConnectList(I)%conX m%ConnectList(I)%r(2) = m%ConnectList(I)%conY m%ConnectList(I)%r(3) = m%ConnectList(I)%conZ - m%ConnectList(I)%rd(1) = 0.0_ReKi - m%ConnectList(I)%rd(2) = 0.0_ReKi - m%ConnectList(I)%rd(3) = 0.0_ReKi + m%ConnectList(I)%rd(1) = 0.0_DbKi + m%ConnectList(I)%rd(2) = 0.0_DbKi + m%ConnectList(I)%rd(3) = 0.0_DbKi END DO ! then do it for fairlead types DO I = 1,p%NFairs DO J = 1, 3 m%ConnectList(m%FairIdList(I))%r(J) = u%PtFairleadDisplacement%Position(J,I) + u%PtFairleadDisplacement%TranslationDisp(J,I) - m%ConnectList(m%FairIdList(I))%rd(J) = 0.0_ReKi + m%ConnectList(m%FairIdList(I))%rd(J) = 0.0_DbKi END DO END DO @@ -370,7 +370,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er DO J = 1, N-1 DO K = 1, 3 x%states(m%LineStateIndList(I) + 3*N-3 + 3*J-3 + K-1 ) = m%LineList(I)%r(K,J) ! assign position - x%states(m%LineStateIndList(I) + 3*J-3 + K-1 ) = 0.0_ReKi ! assign velocities (of zero) + x%states(m%LineStateIndList(I) + 3*J-3 + K-1 ) = 0.0_DbKi ! assign velocities (of zero) END DO END DO @@ -407,7 +407,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er ! initialize fairlead tension memory at zero DO J = 1,p%NFairs DO I = 1, 3 - FairTensIC(J,I) = 0.0_ReKi + FairTensIC(J,I) = 0.0_DbKi END DO END DO @@ -732,11 +732,11 @@ SUBROUTINE MD_CalcContStateDeriv( t, u, p, x, xd, z, other, m, dxdt, ErrStat, Er ! clear connection force and mass values DO L = 1, p%NConnects DO J = 1,3 - m%ConnectList(L)%Ftot(J) = 0.0_ReKi - m%ConnectList(L)%Ftot(J) = 0.0_ReKi + m%ConnectList(L)%Ftot(J) = 0.0_DbKi + m%ConnectList(L)%Ftot(J) = 0.0_DbKi DO K = 1,3 - m%ConnectList(L)%Mtot(K,J) = 0.0_ReKi - m%ConnectList(L)%Mtot(K,J) = 0.0_ReKi + m%ConnectList(L)%Mtot(K,J) = 0.0_DbKi + m%ConnectList(L)%Mtot(K,J) = 0.0_DbKi END DO END DO END DO @@ -816,33 +816,33 @@ SUBROUTINE MD_CalcContStateDeriv( t, u, p, x, xd, z, other, m, dxdt, ErrStat, Er !====================================================================== SUBROUTINE DoLineRHS (X, Xd, t, Line, LineProp, FairFtot, FairMtot, AnchFtot, AnchMtot) - Real(ReKi), INTENT( IN ) :: X(:) ! state vector, provided - Real(ReKi), INTENT( INOUT ) :: Xd(:) ! derivative of state vector, returned ! cahnged to INOUT + Real(DbKi), INTENT( IN ) :: X(:) ! state vector, provided + Real(DbKi), INTENT( INOUT ) :: Xd(:) ! derivative of state vector, returned ! cahnged to INOUT Real(DbKi), INTENT (IN) :: t ! instantaneous time TYPE(MD_Line), INTENT (INOUT) :: Line ! label for the current line, for convenience TYPE(MD_LineProp), INTENT(IN) :: LineProp ! the single line property set for the line of interest - Real(ReKi), INTENT(INOUT) :: FairFtot(:) ! total force on Connect top of line is attached to - Real(ReKi), INTENT(INOUT) :: FairMtot(:,:) ! total mass of Connect top of line is attached to - Real(ReKi), INTENT(INOUT) :: AnchFtot(:) ! total force on Connect bottom of line is attached to - Real(ReKi), INTENT(INOUT) :: AnchMtot(:,:) ! total mass of Connect bottom of line is attached to + Real(DbKi), INTENT(INOUT) :: FairFtot(:) ! total force on Connect top of line is attached to + Real(DbKi), INTENT(INOUT) :: FairMtot(:,:) ! total mass of Connect top of line is attached to + Real(DbKi), INTENT(INOUT) :: AnchFtot(:) ! total force on Connect bottom of line is attached to + Real(DbKi), INTENT(INOUT) :: AnchMtot(:,:) ! total mass of Connect bottom of line is attached to INTEGER(IntKi) :: I ! index of segments or nodes along line INTEGER(IntKi) :: J ! index INTEGER(IntKi) :: K ! index INTEGER(IntKi) :: N ! number of segments in line - Real(ReKi) :: d ! line diameter - Real(ReKi) :: rho ! line material density [kg/m^3] - Real(ReKi) :: Sum1 ! for summing squares - Real(ReKi) :: m_i ! node mass - Real(ReKi) :: v_i ! node submerged volume - Real(ReKi) :: Vi(3) ! relative water velocity at a given node - Real(ReKi) :: Vp(3) ! transverse relative water velocity component at a given node - Real(ReKi) :: Vq(3) ! tangential relative water velocity component at a given node - Real(ReKi) :: SumSqVp ! - Real(ReKi) :: SumSqVq ! - Real(ReKi) :: MagVp ! - Real(ReKi) :: MagVq ! + Real(DbKi) :: d ! line diameter + Real(DbKi) :: rho ! line material density [kg/m^3] + Real(DbKi) :: Sum1 ! for summing squares + Real(DbKi) :: m_i ! node mass + Real(DbKi) :: v_i ! node submerged volume + Real(DbKi) :: Vi(3) ! relative water velocity at a given node + Real(DbKi) :: Vp(3) ! transverse relative water velocity component at a given node + Real(DbKi) :: Vq(3) ! tangential relative water velocity component at a given node + Real(DbKi) :: SumSqVp ! + Real(DbKi) :: SumSqVq ! + Real(DbKi) :: MagVp ! + Real(DbKi) :: MagVq ! N = Line%N ! for convenience @@ -869,13 +869,13 @@ SUBROUTINE DoLineRHS (X, Xd, t, Line, LineProp, FairFtot, FairMtot, AnchFtot, An ! calculate instantaneous (stretched) segment lengths and rates << should add catch here for if lstr is ever zero DO I = 1, N - Sum1 = 0.0_ReKi + Sum1 = 0.0_DbKi DO J = 1, 3 Sum1 = Sum1 + (Line%r(J,I) - Line%r(J,I-1)) * (Line%r(J,I) - Line%r(J,I-1)) END DO Line%lstr(I) = sqrt(Sum1) ! stretched segment length - Sum1 = 0.0_ReKi + Sum1 = 0.0_DbKi DO J = 1, 3 Sum1 = Sum1 + (Line%r(J,I) - Line%r(J,I-1))*(Line%rd(J,I) - Line%rd(J,I-1)) END DO @@ -934,7 +934,7 @@ SUBROUTINE DoLineRHS (X, Xd, t, Line, LineProp, FairFtot, FairMtot, AnchFtot, An END DO ELSE DO J = 1, 3 - Line%T(J,I) = 0.0_ReKi ! cable can't "push" + Line%T(J,I) = 0.0_DbKi ! cable can't "push" END DO END if @@ -964,8 +964,8 @@ SUBROUTINE DoLineRHS (X, Xd, t, Line, LineProp, FairFtot, FairMtot, AnchFtot, An END DO ! decomponse relative flow into components - SumSqVp = 0.0_ReKi ! start sums of squares at zero - SumSqVq = 0.0_ReKi + SumSqVp = 0.0_DbKi ! start sums of squares at zero + SumSqVq = 0.0_DbKi DO J = 1, 3 Vq(J) = DOT_PRODUCT( Vi , Line%q(:,I) ) * Line%q(J,I); ! tangential relative flow component Vp(J) = Vi(J) - Vq(J) ! transverse relative flow component @@ -1009,7 +1009,7 @@ SUBROUTINE DoLineRHS (X, Xd, t, Line, LineProp, FairFtot, FairMtot, AnchFtot, An END IF ELSE - Line%B(3,I) = 0.0_ReKi + Line%B(3,I) = 0.0_DbKi END IF ! total forces @@ -1035,7 +1035,7 @@ SUBROUTINE DoLineRHS (X, Xd, t, Line, LineProp, FairFtot, FairMtot, AnchFtot, An DO J=1,3 ! calculate RHS constant (premultiplying force vector by inverse of mass matrix ... i.e. rhs = S*Forces) - Sum1 = 0.0_ReKi ! reset temporary accumulator + Sum1 = 0.0_DbKi ! reset temporary accumulator DO K = 1, 3 Sum1 = Sum1 + Line%S(K,J,I) * Line%F(K,I) ! matrix-vector multiplication [S i]{Forces i} << double check indices END DO ! K @@ -1067,8 +1067,8 @@ SUBROUTINE DoConnectRHS (X, Xd, t, Connect) ! This subroutine is for the "Connect" type of Connections only. Other types don't have their own state variables. - Real(ReKi), INTENT( IN ) :: X(:) ! state vector for this connect, provided - Real(ReKi), INTENT( OUT ) :: Xd(:) ! derivative of state vector for this connect, returned + Real(DbKi), INTENT( IN ) :: X(:) ! state vector for this connect, provided + Real(DbKi), INTENT( OUT ) :: Xd(:) ! derivative of state vector for this connect, returned Real(DbKi), INTENT (IN) :: t ! instantaneous time Type(MD_Connect), INTENT (INOUT) :: Connect ! Connect number @@ -1076,7 +1076,7 @@ SUBROUTINE DoConnectRHS (X, Xd, t, Connect) !INTEGER(IntKi) :: I ! index of segments or nodes along line INTEGER(IntKi) :: J ! index INTEGER(IntKi) :: K ! index - Real(ReKi) :: Sum1 ! for adding things + Real(DbKi) :: Sum1 ! for adding things ! When this sub is called, the force and mass contributions from the attached Lines should already have been added to ! Fto and Mtot by the Line RHS function. Also, any self weight, buoyancy, or external forcing should have already been @@ -1088,7 +1088,7 @@ SUBROUTINE DoConnectRHS (X, Xd, t, Connect) DO J = 1,3 Xd(3+J) = X(J) ! velocities - these are unused in integration - Xd(J) = 0.0_ReKi ! accelerations - these are unused in integration + Xd(J) = 0.0_DbKi ! accelerations - these are unused in integration END DO ELSE ! from state values, get r and rdot values @@ -1110,7 +1110,7 @@ SUBROUTINE DoConnectRHS (X, Xd, t, Connect) DO J = 1,3 ! RHS constant - (premultiplying force vector by inverse of mass matrix ... i.e. rhs = S*Forces - Sum1 = 0.0_ReKi ! reset accumulator + Sum1 = 0.0_DbKi ! reset accumulator DO K = 1, 3 Sum1 = Sum1 + Connect%S(K,J) * Connect%Ftot(K) ! matrix multiplication [S i]{Forces i} END DO @@ -1288,7 +1288,7 @@ SUBROUTINE TimeStep ( t, dtStep, u, utimes, p, x, xd, z, other, m, ErrStat, ErrM CALL MD_Input_ExtrapInterp(u, utimes, u_interp, t + 0.5_DbKi*dtM, ErrStat, ErrMsg) ! interpolate input mesh to correct time (t+0.5*dtM) - CALL MD_CalcContStateDeriv( (t + 0.5_ReKi*dtM), u_interp, p, x2, xd, z, other, m, dxdt, ErrStat, ErrMsg ) !called with updated states x2 and time = t + dt/2.0 + CALL MD_CalcContStateDeriv( (t + 0.5_DbKi*dtM), u_interp, p, x2, xd, z, other, m, dxdt, ErrStat, ErrMsg ) !called with updated states x2 and time = t + dt/2.0 DO J = 1, Nx x%states(J) = x%states(J) + dtM*dxdt%states(J) END DO @@ -1402,8 +1402,8 @@ SUBROUTINE SetupLine (Line, LineProp, rhoW, ErrStat, ErrMsg) ! set gravity and bottom contact forces to zero initially (because the horizontal components should remain at zero) DO J = 0,N DO K = 1,3 - Line%W(K,J) = 0.0_ReKi - Line%B(K,J) = 0.0_ReKi + Line%W(K,J) = 0.0_DbKi + Line%B(K,J) = 0.0_DbKi END DO END DO @@ -1456,22 +1456,22 @@ SUBROUTINE InitializeLine (Line, LineProp, rhoW, ErrStat, ErrMsg) INTEGER, INTENT( INOUT ) :: ErrStat ! returns a non-zero value when an error occurs CHARACTER(*), INTENT( INOUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - REAL(ReKi) :: COSPhi ! Cosine of the angle between the xi-axis of the inertia frame and the X-axis of the local coordinate system of the current mooring line (-) - REAL(ReKi) :: SINPhi ! Sine of the angle between the xi-axis of the inertia frame and the X-axis of the local coordinate system of the current mooring line (-) - REAL(ReKi) :: XF ! Horizontal distance between anchor and fairlead of the current mooring line (meters) - REAL(ReKi) :: ZF ! Vertical distance between anchor and fairlead of the current mooring line (meters) + REAL(DbKi) :: COSPhi ! Cosine of the angle between the xi-axis of the inertia frame and the X-axis of the local coordinate system of the current mooring line (-) + REAL(DbKi) :: SINPhi ! Sine of the angle between the xi-axis of the inertia frame and the X-axis of the local coordinate system of the current mooring line (-) + REAL(DbKi) :: XF ! Horizontal distance between anchor and fairlead of the current mooring line (meters) + REAL(DbKi) :: ZF ! Vertical distance between anchor and fairlead of the current mooring line (meters) INTEGER(4) :: I ! Generic index INTEGER(4) :: J ! Generic index INTEGER(IntKi) :: ErrStat2 ! Error status of the operation CHARACTER(ErrMsgLen) :: ErrMsg2 ! Error message if ErrStat2 /= ErrID_None - REAL(ReKi) :: WetWeight - REAL(ReKi) :: SeabedCD = 0.0_ReKi - REAL(ReKi) :: TenTol = 0.0001_ReKi - REAL(ReKi), ALLOCATABLE :: LSNodes(:) - REAL(ReKi), ALLOCATABLE :: LNodesX(:) - REAL(ReKi), ALLOCATABLE :: LNodesZ(:) + REAL(DbKi) :: WetWeight + REAL(DbKi) :: SeabedCD = 0.0_DbKi + REAL(DbKi) :: TenTol = 0.0001_DbKi + REAL(DbKi), ALLOCATABLE :: LSNodes(:) + REAL(DbKi), ALLOCATABLE :: LNodesX(:) + REAL(DbKi), ALLOCATABLE :: LNodesZ(:) INTEGER(IntKi) :: N @@ -1490,8 +1490,8 @@ SUBROUTINE InitializeLine (Line, LineProp, rhoW, ErrStat, ErrMsg) ZF = Line%r(3,N) - Line%r(3,0) IF ( XF == 0.0 ) THEN ! .TRUE. if the current mooring line is exactly vertical; thus, the solution below is ill-conditioned because the orientation is undefined; so set it such that the tensions and nodal positions are only vertical - COSPhi = 0.0_ReKi - SINPhi = 0.0_ReKi + COSPhi = 0.0_DbKi + SINPhi = 0.0_DbKi ELSE ! The current mooring line must not be vertical; use simple trigonometry COSPhi = ( Line%r(1,N) - Line%r(1,0) )/XF SINPhi = ( Line%r(2,N) - Line%r(2,0) )/XF @@ -1524,7 +1524,7 @@ SUBROUTINE InitializeLine (Line, LineProp, rhoW, ErrStat, ErrMsg) END IF ! Assign node arc length locations - LSNodes(1) = 0.0_ReKi + LSNodes(1) = 0.0_DbKi DO I=2,N LSNodes(I) = LSNodes(I-1) + Line%l(I-1) ! note: l index is because line segment indices start at 1 END DO @@ -1562,9 +1562,9 @@ SUBROUTINE InitializeLine (Line, LineProp, rhoW, ErrStat, ErrMsg) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'InitializeLine') DO J = 0,Line%N ! Loop through all nodes per line where the line position and tension can be output - Line%r(1,J) = Line%r(1,0) + (Line%r(1,N) - Line%r(1,0))*REAL(J, ReKi)/REAL(N, ReKi) - Line%r(2,J) = Line%r(2,0) + (Line%r(2,N) - Line%r(2,0))*REAL(J, ReKi)/REAL(N, ReKi) - Line%r(3,J) = Line%r(3,0) + (Line%r(3,N) - Line%r(3,0))*REAL(J, ReKi)/REAL(N, ReKi) + Line%r(1,J) = Line%r(1,0) + (Line%r(1,N) - Line%r(1,0))*REAL(J, DbKi)/REAL(N, DbKi) + Line%r(2,J) = Line%r(2,0) + (Line%r(2,N) - Line%r(2,0))*REAL(J, DbKi)/REAL(N, DbKi) + Line%r(3,J) = Line%r(3,0) + (Line%r(3,N) - Line%r(3,0))*REAL(J, DbKi)/REAL(N, DbKi) ENDDO ENDIF @@ -1621,21 +1621,21 @@ SUBROUTINE Catenary ( XF_In, ZF_In, L_In , EA_In, & INTEGER(4), INTENT(IN ) :: N ! Number of nodes where the line position and tension can be output (-) - REAL(ReKi), INTENT(IN ) :: CB_In ! Coefficient of seabed static friction drag (a negative value indicates no seabed) (-) - REAL(ReKi), INTENT(IN ) :: EA_In ! Extensional stiffness of line (N) - ! REAL(ReKi), INTENT( OUT) :: HA_In ! Effective horizontal tension in line at the anchor (N) - ! REAL(ReKi), INTENT(INOUT) :: HF_In ! Effective horizontal tension in line at the fairlead (N) - REAL(ReKi), INTENT(IN ) :: L_In ! Unstretched length of line (meters) - REAL(ReKi), INTENT(IN ) :: s_In (N) ! Unstretched arc distance along line from anchor to each node where the line position and tension can be output (meters) - ! REAL(ReKi), INTENT( OUT) :: Te_In (N) ! Effective line tensions at each node (N) - REAL(ReKi), INTENT(IN ) :: Tol_In ! Convergence tolerance within Newton-Raphson iteration specified as a fraction of tension (-) - ! REAL(ReKi), INTENT( OUT) :: VA_In ! Effective vertical tension in line at the anchor (N) - ! REAL(ReKi), INTENT(INOUT) :: VF_In ! Effective vertical tension in line at the fairlead (N) - REAL(ReKi), INTENT(IN ) :: W_In ! Weight of line in fluid per unit length (N/m) - REAL(ReKi), INTENT( OUT) :: X_In (N) ! Horizontal locations of each line node relative to the anchor (meters) - REAL(ReKi), INTENT(IN ) :: XF_In ! Horizontal distance between anchor and fairlead (meters) - REAL(ReKi), INTENT( OUT) :: Z_In (N) ! Vertical locations of each line node relative to the anchor (meters) - REAL(ReKi), INTENT(IN ) :: ZF_In ! Vertical distance between anchor and fairlead (meters) + REAL(DbKi), INTENT(IN ) :: CB_In ! Coefficient of seabed static friction drag (a negative value indicates no seabed) (-) + REAL(DbKi), INTENT(IN ) :: EA_In ! Extensional stiffness of line (N) + ! REAL(DbKi), INTENT( OUT) :: HA_In ! Effective horizontal tension in line at the anchor (N) + ! REAL(DbKi), INTENT(INOUT) :: HF_In ! Effective horizontal tension in line at the fairlead (N) + REAL(DbKi), INTENT(IN ) :: L_In ! Unstretched length of line (meters) + REAL(DbKi), INTENT(IN ) :: s_In (N) ! Unstretched arc distance along line from anchor to each node where the line position and tension can be output (meters) + ! REAL(DbKi), INTENT( OUT) :: Te_In (N) ! Effective line tensions at each node (N) + REAL(DbKi), INTENT(IN ) :: Tol_In ! Convergence tolerance within Newton-Raphson iteration specified as a fraction of tension (-) + ! REAL(DbKi), INTENT( OUT) :: VA_In ! Effective vertical tension in line at the anchor (N) + ! REAL(DbKi), INTENT(INOUT) :: VF_In ! Effective vertical tension in line at the fairlead (N) + REAL(DbKi), INTENT(IN ) :: W_In ! Weight of line in fluid per unit length (N/m) + REAL(DbKi), INTENT( OUT) :: X_In (N) ! Horizontal locations of each line node relative to the anchor (meters) + REAL(DbKi), INTENT(IN ) :: XF_In ! Horizontal distance between anchor and fairlead (meters) + REAL(DbKi), INTENT( OUT) :: Z_In (N) ! Vertical locations of each line node relative to the anchor (meters) + REAL(DbKi), INTENT(IN ) :: ZF_In ! Vertical distance between anchor and fairlead (meters) INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None @@ -2137,13 +2137,13 @@ SUBROUTINE Catenary ( XF_In, ZF_In, L_In , EA_In, & ! convert the output arguments back into the default precision for real ! numbers: - !HA_In = REAL( HA , ReKi ) !mth: for this I only care about returning node positions - !HF_In = REAL( HF , ReKi ) - !Te_In(:) = REAL( Te(:), ReKi ) - !VA_In = REAL( VA , ReKi ) - !VF_In = REAL( VF , ReKi ) - X_In (:) = REAL( X (:), ReKi ) - Z_In (:) = REAL( Z (:), ReKi ) + !HA_In = REAL( HA , DbKi ) !mth: for this I only care about returning node positions + !HF_In = REAL( HF , DbKi ) + !Te_In(:) = REAL( Te(:), DbKi ) + !VA_In = REAL( VA , DbKi ) + !VF_In = REAL( VF , DbKi ) + X_In (:) = REAL( X (:), DbKi ) + Z_In (:) = REAL( Z (:), DbKi ) END SUBROUTINE Catenary !======================================================================= @@ -2161,16 +2161,16 @@ END SUBROUTINE InitializeLine ! return unit vector (u) in direction from r1 to r2 !======================================================================= SUBROUTINE UnitVector( u, r1, r2 ) - REAL(ReKi), INTENT(OUT) :: u(:) - REAL(ReKi), INTENT(IN) :: r1(:) - REAL(ReKi), INTENT(IN) :: r2(:) + REAL(DbKi), INTENT(OUT) :: u(:) + REAL(DbKi), INTENT(IN) :: r1(:) + REAL(DbKi), INTENT(IN) :: r2(:) - REAL(ReKi) :: Length + REAL(DbKi) :: Length u = r2 - r1 Length = TwoNorm(u) - if ( .NOT. EqualRealNos(length, 0.0_ReKi ) ) THEN + if ( .NOT. EqualRealNos(length, 0.0_DbKi ) ) THEN u = u / Length END IF @@ -2181,11 +2181,11 @@ END SUBROUTINE UnitVector !compute the inverse of a 3-by-3 matrix m !======================================================================= SUBROUTINE Inverse3by3( Minv, M ) - Real(ReKi), INTENT(OUT) :: Minv(:,:) ! returned inverse matrix - Real(ReKi), INTENT(IN) :: M(:,:) ! inputted matrix + Real(DbKi), INTENT(OUT) :: Minv(:,:) ! returned inverse matrix + Real(DbKi), INTENT(IN) :: M(:,:) ! inputted matrix - Real(ReKi) :: det ! the determinant - Real(ReKi) :: invdet ! inverse of the determinant + Real(DbKi) :: det ! the determinant + Real(DbKi) :: invdet ! inverse of the determinant det = M(1, 1) * (M(2, 2) * M(3, 3) - M(3, 2) * M(2, 3)) - & M(1, 2) * (M(2, 1) * M(3, 3) - M(2, 3) * M(3, 1)) + & diff --git a/modules/moordyn/src/MoorDyn_IO.f90 b/modules/moordyn/src/MoorDyn_IO.f90 index e18d4b0ed2..f4dfba6420 100644 --- a/modules/moordyn/src/MoorDyn_IO.f90 +++ b/modules/moordyn/src/MoorDyn_IO.f90 @@ -1180,7 +1180,7 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) CASE (FZ) y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%Ftot(3) ! total force in z CASE DEFAULT - y%WriteOutput(I) = 0.0_ReKi + y%WriteOutput(I) = 0.0_DbKi ErrStat = ErrID_Warn ErrMsg = ' Unsupported output quantity '//TRIM(Num2Lstr(p%OutParam(I)%QType))//' requested from Connection '//TRIM(Num2Lstr(p%OutParam(I)%ObjID))//'.' END SELECT @@ -1203,13 +1203,13 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) CASE (Ten) y%WriteOutput(I) = TwoNorm(m%LineList(p%OutParam(I)%ObjID)%T(:,p%OutParam(I)%NodeID)) ! this is actually the segment tension ( 1 < NodeID < N ) Should deal with properly! CASE DEFAULT - y%WriteOutput(I) = 0.0_ReKi + y%WriteOutput(I) = 0.0_DbKi ErrStat = ErrID_Warn ErrMsg = ' Unsupported output quantity '//TRIM(Num2Lstr(p%OutParam(I)%QType))//' requested from Line '//TRIM(Num2Lstr(p%OutParam(I)%ObjID))//'.' END SELECT ELSE ! it must be an invalid output, so write zero - y%WriteOutput(I) = 0.0_ReKi + y%WriteOutput(I) = 0.0_DbKi END IF @@ -1218,7 +1218,7 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) ! Write the output parameters to the file - Frmt = '(F10.4,'//TRIM(Int2LStr(p%NumOuts))//'(A1,e10.4))' ! should evenutally use user specified format? + Frmt = '(F10.4,'//TRIM(Int2LStr(p%NumOuts))//'(A1,e12.6))' ! should evenutally use user specified format? WRITE(p%MDUnOut,Frmt) Time, ( p%Delim, y%WriteOutput(I), I=1,p%NumOuts ) @@ -1237,7 +1237,7 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) LineNumOuts = 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:5)) + m%LineList(I)%N*SUM(m%LineList(I)%OutFlagList(6:10)) - Frmt = '(F10.4,'//TRIM(Int2LStr(LineNumOuts))//'(A1,e10.4))' ! should evenutally use user specified format? + Frmt = '(F10.4,'//TRIM(Int2LStr(LineNumOuts))//'(A1,e12.6))' ! should evenutally use user specified format? L = 1 ! start of index of line output file at first entry diff --git a/modules/moordyn/src/MoorDyn_Registry.txt b/modules/moordyn/src/MoorDyn_Registry.txt index 8868e2621c..6fb1e729db 100644 --- a/modules/moordyn/src/MoorDyn_Registry.txt +++ b/modules/moordyn/src/MoorDyn_Registry.txt @@ -33,14 +33,14 @@ typedef ^ ^ CHARACTER(ChanLen) OutList {: # line properties from line dictionary input typedef ^ MD_LineProp IntKi IdNum - - - "integer identifier of this set of line properties" typedef ^ ^ CHARACTER(10) name - - - "name/identifier of this set of line properties" -typedef ^ ^ ReKi d - - - "volume-equivalent diameter" "[m]" -typedef ^ ^ ReKi w - - - "per-length weight in air" "[kg/m]" -typedef ^ ^ ReKi EA - - - "stiffness" "[N]" -typedef ^ ^ ReKi BA - - - "internal damping coefficient times area" "[N-s]" -typedef ^ ^ ReKi Can - - - "transverse added mass coefficient" -typedef ^ ^ ReKi Cat - - - "tangential added mass coefficient" -typedef ^ ^ ReKi Cdn - - - "transverse drag coefficient" -typedef ^ ^ ReKi Cdt - - - "tangential drag coefficient" +typedef ^ ^ DbKi d - - - "volume-equivalent diameter" "[m]" +typedef ^ ^ DbKi w - - - "per-length weight in air" "[kg/m]" +typedef ^ ^ DbKi EA - - - "stiffness" "[N]" +typedef ^ ^ DbKi BA - - - "internal damping coefficient times area" "[N-s]" +typedef ^ ^ DbKi Can - - - "transverse added mass coefficient" +typedef ^ ^ DbKi Cat - - - "tangential added mass coefficient" +typedef ^ ^ DbKi Cdn - - - "transverse drag coefficient" +typedef ^ ^ DbKi Cdt - - - "tangential drag coefficient" # this is the Connection type, which holds data for each connection object typedef ^ MD_Connect IntKi IdNum - - - "integer identifier of this Connection" @@ -48,21 +48,21 @@ typedef ^ ^ CHARACTER(10) type - typedef ^ ^ IntKi TypeNum - - - "integer identifying the type. 0=fixed, 1=vessel, 2=connect" typedef ^ ^ IntKi AttachedFairs {:} - - "list of IdNums of connected Line tops" typedef ^ ^ IntKi AttachedAnchs {:} - - "list of IdNums of connected Line bottoms" -typedef ^ ^ ReKi conX - - - "" -typedef ^ ^ ReKi conY - - - "" -typedef ^ ^ ReKi conZ - - - "" -typedef ^ ^ ReKi conM - - - "" -typedef ^ ^ ReKi conV - - - "" -typedef ^ ^ ReKi conFX - - - "" -typedef ^ ^ ReKi conFY - - - "" -typedef ^ ^ ReKi conFZ - - - "" -typedef ^ ^ ReKi conCa - - - "added mass coefficient of connection point" "-" -typedef ^ ^ ReKi conCdA - - - "product of drag force and frontal area of connection point" "[m^2]" -typedef ^ ^ ReKi Ftot {3} - - "total force on node" -typedef ^ ^ ReKi Mtot {3}{3} - - "node mass matrix, from attached lines" -typedef ^ ^ ReKi S {3}{3} - - "inverse mass matrix" "[kg]" -typedef ^ ^ ReKi r {3} - - "position" -typedef ^ ^ ReKi rd {3} - - "velocity" +typedef ^ ^ DbKi conX - - - "" +typedef ^ ^ DbKi conY - - - "" +typedef ^ ^ DbKi conZ - - - "" +typedef ^ ^ DbKi conM - - - "" +typedef ^ ^ DbKi conV - - - "" +typedef ^ ^ DbKi conFX - - - "" +typedef ^ ^ DbKi conFY - - - "" +typedef ^ ^ DbKi conFZ - - - "" +typedef ^ ^ DbKi conCa - - - "added mass coefficient of connection point" "-" +typedef ^ ^ DbKi conCdA - - - "product of drag force and frontal area of connection point" "[m^2]" +typedef ^ ^ DbKi Ftot {3} - - "total force on node" +typedef ^ ^ DbKi Mtot {3}{3} - - "node mass matrix, from attached lines" +typedef ^ ^ DbKi S {3}{3} - - "inverse mass matrix" "[kg]" +typedef ^ ^ DbKi r {3} - - "position" +typedef ^ ^ DbKi rd {3} - - "velocity" # this is the Line type, which holds data for each line object typedef ^ MD_Line IntKi IdNum - - - "integer identifier of this Line" @@ -73,27 +73,27 @@ typedef ^ ^ IntKi FairConnect - typedef ^ ^ IntKi AnchConnect - - - "IdNum of Connection at anchor" typedef ^ ^ IntKi PropsIdNum - - - "the IdNum of the associated line properties" - typedef ^ ^ IntKi N - - - "The number of elements in the line" - -typedef ^ ^ ReKi UnstrLen - - - "unstretched length of the line" - -typedef ^ ^ ReKi BA - - - "internal damping coefficient times area for this line only" "[N-s]" -typedef ^ ^ ReKi r {:}{:} - - "node positions" - -typedef ^ ^ ReKi rd {:}{:} - - "node velocities" - -typedef ^ ^ ReKi q {:}{:} - - "node tangent vectors" - -typedef ^ ^ ReKi l {:} - - "segment unstretched length" "[m]" -typedef ^ ^ ReKi ld {:} - - "segment unstretched length rate of change (used in active tensioning)" "[m]" -typedef ^ ^ ReKi lstr {:} - - "segment stretched length" "[m]" -typedef ^ ^ ReKi lstrd {:} - - "segment change in stretched length" "[m/s]" -typedef ^ ^ ReKi V {:} - - "segment volume" "[m^3]" -typedef ^ ^ ReKi T {:}{:} - - "segment tension vectors" "[N]" -typedef ^ ^ ReKi Td {:}{:} - - "segment internal damping force vectors" "[N]" -typedef ^ ^ ReKi W {:}{:} - - "weight/buoyancy vectors" "[N]" -typedef ^ ^ ReKi Dp {:}{:} - - "node drag (transverse)" "[N]" -typedef ^ ^ ReKi Dq {:}{:} - - "node drag (axial)" "[N]" -typedef ^ ^ ReKi Ap {:}{:} - - "node added mass forcing (transverse)" "[N]" -typedef ^ ^ ReKi Aq {:}{:} - - "node added mass forcing (axial)" "[N]" -typedef ^ ^ ReKi B {:}{:} - - "node bottom contact force" "[N]" -typedef ^ ^ ReKi F {:}{:} - - "total force on node" "[N]" -typedef ^ ^ ReKi S {:}{:}{:} - - "node inverse mass matrix" "[kg]" -typedef ^ ^ ReKi M {:}{:}{:} - - "node mass matrix" "[kg]" +typedef ^ ^ DbKi UnstrLen - - - "unstretched length of the line" - +typedef ^ ^ DbKi BA - - - "internal damping coefficient times area for this line only" "[N-s]" +typedef ^ ^ DbKi r {:}{:} - - "node positions" - +typedef ^ ^ DbKi rd {:}{:} - - "node velocities" - +typedef ^ ^ DbKi q {:}{:} - - "node tangent vectors" - +typedef ^ ^ DbKi l {:} - - "segment unstretched length" "[m]" +typedef ^ ^ DbKi ld {:} - - "segment unstretched length rate of change (used in active tensioning)" "[m]" +typedef ^ ^ DbKi lstr {:} - - "segment stretched length" "[m]" +typedef ^ ^ DbKi lstrd {:} - - "segment change in stretched length" "[m/s]" +typedef ^ ^ DbKi V {:} - - "segment volume" "[m^3]" +typedef ^ ^ DbKi T {:}{:} - - "segment tension vectors" "[N]" +typedef ^ ^ DbKi Td {:}{:} - - "segment internal damping force vectors" "[N]" +typedef ^ ^ DbKi W {:}{:} - - "weight/buoyancy vectors" "[N]" +typedef ^ ^ DbKi Dp {:}{:} - - "node drag (transverse)" "[N]" +typedef ^ ^ DbKi Dq {:}{:} - - "node drag (axial)" "[N]" +typedef ^ ^ DbKi Ap {:}{:} - - "node added mass forcing (transverse)" "[N]" +typedef ^ ^ DbKi Aq {:}{:} - - "node added mass forcing (axial)" "[N]" +typedef ^ ^ DbKi B {:}{:} - - "node bottom contact force" "[N]" +typedef ^ ^ DbKi F {:}{:} - - "total force on node" "[N]" +typedef ^ ^ DbKi S {:}{:}{:} - - "node inverse mass matrix" "[kg]" +typedef ^ ^ DbKi M {:}{:}{:} - - "node mass matrix" "[kg]" typedef ^ ^ IntKi LineUnOut - - - "unit number of line output file" typedef ^ ^ ReKi LineWrOutput {:} - - "one row of output data for this line" @@ -115,7 +115,7 @@ typedef ^ ^ ProgDesc Ver - " ## ============================== Define Continuous states here: ===================================================================================================================================== -typedef ^ ContinuousStateType ReKi states {:} "" - "full list of node coordinates and velocities" "[m] or [m/s]" +typedef ^ ContinuousStateType DbKi states {:} "" - "full list of node coordinates and velocities" "[m] or [m/s]" ## ============================== Define Discrete states here: ===================================================================================================================================== diff --git a/modules/moordyn/src/MoorDyn_Types.f90 b/modules/moordyn/src/MoorDyn_Types.f90 index e7fb3a826a..dc9c2bff15 100644 --- a/modules/moordyn/src/MoorDyn_Types.f90 +++ b/modules/moordyn/src/MoorDyn_Types.f90 @@ -53,14 +53,14 @@ MODULE MoorDyn_Types TYPE, PUBLIC :: MD_LineProp INTEGER(IntKi) :: IdNum !< integer identifier of this set of line properties [-] CHARACTER(10) :: name !< name/identifier of this set of line properties [-] - REAL(ReKi) :: d !< volume-equivalent diameter [[m]] - REAL(ReKi) :: w !< per-length weight in air [[kg/m]] - REAL(ReKi) :: EA !< stiffness [[N]] - REAL(ReKi) :: BA !< internal damping coefficient times area [[N-s]] - REAL(ReKi) :: Can !< transverse added mass coefficient [-] - REAL(ReKi) :: Cat !< tangential added mass coefficient [-] - REAL(ReKi) :: Cdn !< transverse drag coefficient [-] - REAL(ReKi) :: Cdt !< tangential drag coefficient [-] + REAL(DbKi) :: d !< volume-equivalent diameter [[m]] + REAL(DbKi) :: w !< per-length weight in air [[kg/m]] + REAL(DbKi) :: EA !< stiffness [[N]] + REAL(DbKi) :: BA !< internal damping coefficient times area [[N-s]] + REAL(DbKi) :: Can !< transverse added mass coefficient [-] + REAL(DbKi) :: Cat !< tangential added mass coefficient [-] + REAL(DbKi) :: Cdn !< transverse drag coefficient [-] + REAL(DbKi) :: Cdt !< tangential drag coefficient [-] END TYPE MD_LineProp ! ======================= ! ========= MD_Connect ======= @@ -70,21 +70,21 @@ MODULE MoorDyn_Types INTEGER(IntKi) :: TypeNum !< integer identifying the type. 0=fixed, 1=vessel, 2=connect [-] INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: AttachedFairs !< list of IdNums of connected Line tops [-] INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: AttachedAnchs !< list of IdNums of connected Line bottoms [-] - REAL(ReKi) :: conX !< [-] - REAL(ReKi) :: conY !< [-] - REAL(ReKi) :: conZ !< [-] - REAL(ReKi) :: conM !< [-] - REAL(ReKi) :: conV !< [-] - REAL(ReKi) :: conFX !< [-] - REAL(ReKi) :: conFY !< [-] - REAL(ReKi) :: conFZ !< [-] - REAL(ReKi) :: conCa !< added mass coefficient of connection point [-] - REAL(ReKi) :: conCdA !< product of drag force and frontal area of connection point [[m^2]] - REAL(ReKi) , DIMENSION(1:3) :: Ftot !< total force on node [-] - REAL(ReKi) , DIMENSION(1:3,1:3) :: Mtot !< node mass matrix, from attached lines [-] - REAL(ReKi) , DIMENSION(1:3,1:3) :: S !< inverse mass matrix [[kg]] - REAL(ReKi) , DIMENSION(1:3) :: r !< position [-] - REAL(ReKi) , DIMENSION(1:3) :: rd !< velocity [-] + REAL(DbKi) :: conX !< [-] + REAL(DbKi) :: conY !< [-] + REAL(DbKi) :: conZ !< [-] + REAL(DbKi) :: conM !< [-] + REAL(DbKi) :: conV !< [-] + REAL(DbKi) :: conFX !< [-] + REAL(DbKi) :: conFY !< [-] + REAL(DbKi) :: conFZ !< [-] + REAL(DbKi) :: conCa !< added mass coefficient of connection point [-] + REAL(DbKi) :: conCdA !< product of drag force and frontal area of connection point [[m^2]] + REAL(DbKi) , DIMENSION(1:3) :: Ftot !< total force on node [-] + REAL(DbKi) , DIMENSION(1:3,1:3) :: Mtot !< node mass matrix, from attached lines [-] + REAL(DbKi) , DIMENSION(1:3,1:3) :: S !< inverse mass matrix [[kg]] + REAL(DbKi) , DIMENSION(1:3) :: r !< position [-] + REAL(DbKi) , DIMENSION(1:3) :: rd !< velocity [-] END TYPE MD_Connect ! ======================= ! ========= MD_Line ======= @@ -97,27 +97,27 @@ MODULE MoorDyn_Types INTEGER(IntKi) :: AnchConnect !< IdNum of Connection at anchor [-] INTEGER(IntKi) :: PropsIdNum !< the IdNum of the associated line properties [-] INTEGER(IntKi) :: N !< The number of elements in the line [-] - REAL(ReKi) :: UnstrLen !< unstretched length of the line [-] - REAL(ReKi) :: BA !< internal damping coefficient times area for this line only [[N-s]] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: r !< node positions [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: rd !< node velocities [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: q !< node tangent vectors [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: l !< segment unstretched length [[m]] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: ld !< segment unstretched length rate of change (used in active tensioning) [[m]] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: lstr !< segment stretched length [[m]] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: lstrd !< segment change in stretched length [[m/s]] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: V !< segment volume [[m^3]] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: T !< segment tension vectors [[N]] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Td !< segment internal damping force vectors [[N]] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: W !< weight/buoyancy vectors [[N]] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Dp !< node drag (transverse) [[N]] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Dq !< node drag (axial) [[N]] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Ap !< node added mass forcing (transverse) [[N]] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Aq !< node added mass forcing (axial) [[N]] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: B !< node bottom contact force [[N]] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: F !< total force on node [[N]] - REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: S !< node inverse mass matrix [[kg]] - REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: M !< node mass matrix [[kg]] + REAL(DbKi) :: UnstrLen !< unstretched length of the line [-] + REAL(DbKi) :: BA !< internal damping coefficient times area for this line only [[N-s]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: r !< node positions [-] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: rd !< node velocities [-] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: q !< node tangent vectors [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: l !< segment unstretched length [[m]] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: ld !< segment unstretched length rate of change (used in active tensioning) [[m]] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: lstr !< segment stretched length [[m]] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: lstrd !< segment change in stretched length [[m/s]] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: V !< segment volume [[m^3]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: T !< segment tension vectors [[N]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: Td !< segment internal damping force vectors [[N]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: W !< weight/buoyancy vectors [[N]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: Dp !< node drag (transverse) [[N]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: Dq !< node drag (axial) [[N]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: Ap !< node added mass forcing (transverse) [[N]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: Aq !< node added mass forcing (axial) [[N]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: B !< node bottom contact force [[N]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: F !< total force on node [[N]] + REAL(DbKi) , DIMENSION(:,:,:), ALLOCATABLE :: S !< node inverse mass matrix [[kg]] + REAL(DbKi) , DIMENSION(:,:,:), ALLOCATABLE :: M !< node mass matrix [[kg]] INTEGER(IntKi) :: LineUnOut !< unit number of line output file [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: LineWrOutput !< one row of output data for this line [-] END TYPE MD_Line @@ -141,7 +141,7 @@ MODULE MoorDyn_Types ! ======================= ! ========= MD_ContinuousStateType ======= TYPE, PUBLIC :: MD_ContinuousStateType - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: states !< full list of node coordinates and velocities [[m] or [m/s]] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: states !< full list of node coordinates and velocities [[m] or [m/s]] END TYPE MD_ContinuousStateType ! ======================= ! ========= MD_DiscreteStateType ======= @@ -542,14 +542,14 @@ SUBROUTINE MD_PackLineProp( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = 0 Int_BufSz = Int_BufSz + 1 ! IdNum Int_BufSz = Int_BufSz + 1*LEN(InData%name) ! name - Re_BufSz = Re_BufSz + 1 ! d - Re_BufSz = Re_BufSz + 1 ! w - Re_BufSz = Re_BufSz + 1 ! EA - Re_BufSz = Re_BufSz + 1 ! BA - Re_BufSz = Re_BufSz + 1 ! Can - Re_BufSz = Re_BufSz + 1 ! Cat - Re_BufSz = Re_BufSz + 1 ! Cdn - Re_BufSz = Re_BufSz + 1 ! Cdt + Db_BufSz = Db_BufSz + 1 ! d + Db_BufSz = Db_BufSz + 1 ! w + Db_BufSz = Db_BufSz + 1 ! EA + Db_BufSz = Db_BufSz + 1 ! BA + Db_BufSz = Db_BufSz + 1 ! Can + Db_BufSz = Db_BufSz + 1 ! Cat + Db_BufSz = Db_BufSz + 1 ! Cdn + Db_BufSz = Db_BufSz + 1 ! Cdt IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -583,22 +583,22 @@ SUBROUTINE MD_PackLineProp( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, IntKiBuf(Int_Xferred) = ICHAR(InData%name(I:I), IntKi) Int_Xferred = Int_Xferred + 1 END DO ! I - ReKiBuf(Re_Xferred) = InData%d - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%w - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%EA - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%BA - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Can - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Cat - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Cdn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Cdt - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%d + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%w + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%EA + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%BA + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%Can + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%Cat + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%Cdn + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%Cdt + Db_Xferred = Db_Xferred + 1 END SUBROUTINE MD_PackLineProp SUBROUTINE MD_UnPackLineProp( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -633,22 +633,22 @@ SUBROUTINE MD_UnPackLineProp( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM OutData%name(I:I) = CHAR(IntKiBuf(Int_Xferred)) Int_Xferred = Int_Xferred + 1 END DO ! I - OutData%d = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%w = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%EA = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%BA = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Can = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Cat = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Cdn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Cdt = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%d = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%w = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%EA = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%BA = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%Can = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%Cat = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%Cdn = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%Cdt = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END SUBROUTINE MD_UnPackLineProp SUBROUTINE MD_CopyConnect( SrcConnectData, DstConnectData, CtrlCode, ErrStat, ErrMsg ) @@ -776,21 +776,21 @@ SUBROUTINE MD_PackConnect( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + 2*1 ! AttachedAnchs upper/lower bounds for each dimension Int_BufSz = Int_BufSz + SIZE(InData%AttachedAnchs) ! AttachedAnchs END IF - Re_BufSz = Re_BufSz + 1 ! conX - Re_BufSz = Re_BufSz + 1 ! conY - Re_BufSz = Re_BufSz + 1 ! conZ - Re_BufSz = Re_BufSz + 1 ! conM - Re_BufSz = Re_BufSz + 1 ! conV - Re_BufSz = Re_BufSz + 1 ! conFX - Re_BufSz = Re_BufSz + 1 ! conFY - Re_BufSz = Re_BufSz + 1 ! conFZ - Re_BufSz = Re_BufSz + 1 ! conCa - Re_BufSz = Re_BufSz + 1 ! conCdA - Re_BufSz = Re_BufSz + SIZE(InData%Ftot) ! Ftot - Re_BufSz = Re_BufSz + SIZE(InData%Mtot) ! Mtot - Re_BufSz = Re_BufSz + SIZE(InData%S) ! S - Re_BufSz = Re_BufSz + SIZE(InData%r) ! r - Re_BufSz = Re_BufSz + SIZE(InData%rd) ! rd + Db_BufSz = Db_BufSz + 1 ! conX + Db_BufSz = Db_BufSz + 1 ! conY + Db_BufSz = Db_BufSz + 1 ! conZ + Db_BufSz = Db_BufSz + 1 ! conM + Db_BufSz = Db_BufSz + 1 ! conV + Db_BufSz = Db_BufSz + 1 ! conFX + Db_BufSz = Db_BufSz + 1 ! conFY + Db_BufSz = Db_BufSz + 1 ! conFZ + Db_BufSz = Db_BufSz + 1 ! conCa + Db_BufSz = Db_BufSz + 1 ! conCdA + Db_BufSz = Db_BufSz + SIZE(InData%Ftot) ! Ftot + Db_BufSz = Db_BufSz + SIZE(InData%Mtot) ! Mtot + Db_BufSz = Db_BufSz + SIZE(InData%S) ! S + Db_BufSz = Db_BufSz + SIZE(InData%r) ! r + Db_BufSz = Db_BufSz + SIZE(InData%rd) ! rd IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -856,49 +856,49 @@ SUBROUTINE MD_PackConnect( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_Xferred = Int_Xferred + 1 END DO END IF - ReKiBuf(Re_Xferred) = InData%conX - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%conY - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%conZ - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%conM - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%conV - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%conFX - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%conFY - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%conFZ - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%conCa - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%conCdA - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%conX + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%conY + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%conZ + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%conM + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%conV + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%conFX + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%conFY + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%conFZ + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%conCa + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%conCdA + Db_Xferred = Db_Xferred + 1 DO i1 = LBOUND(InData%Ftot,1), UBOUND(InData%Ftot,1) - ReKiBuf(Re_Xferred) = InData%Ftot(i1) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%Ftot(i1) + Db_Xferred = Db_Xferred + 1 END DO DO i2 = LBOUND(InData%Mtot,2), UBOUND(InData%Mtot,2) DO i1 = LBOUND(InData%Mtot,1), UBOUND(InData%Mtot,1) - ReKiBuf(Re_Xferred) = InData%Mtot(i1,i2) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%Mtot(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO DO i2 = LBOUND(InData%S,2), UBOUND(InData%S,2) DO i1 = LBOUND(InData%S,1), UBOUND(InData%S,1) - ReKiBuf(Re_Xferred) = InData%S(i1,i2) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%S(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO DO i1 = LBOUND(InData%r,1), UBOUND(InData%r,1) - ReKiBuf(Re_Xferred) = InData%r(i1) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%r(i1) + Db_Xferred = Db_Xferred + 1 END DO DO i1 = LBOUND(InData%rd,1), UBOUND(InData%rd,1) - ReKiBuf(Re_Xferred) = InData%rd(i1) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%rd(i1) + Db_Xferred = Db_Xferred + 1 END DO END SUBROUTINE MD_PackConnect @@ -974,31 +974,31 @@ SUBROUTINE MD_UnPackConnect( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs Int_Xferred = Int_Xferred + 1 END DO END IF - OutData%conX = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%conY = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%conZ = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%conM = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%conV = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%conFX = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%conFY = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%conFZ = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%conCa = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%conCdA = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%conX = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%conY = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%conZ = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%conM = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%conV = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%conFX = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%conFY = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%conFZ = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%conCa = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%conCdA = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 i1_l = LBOUND(OutData%Ftot,1) i1_u = UBOUND(OutData%Ftot,1) DO i1 = LBOUND(OutData%Ftot,1), UBOUND(OutData%Ftot,1) - OutData%Ftot(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%Ftot(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO i1_l = LBOUND(OutData%Mtot,1) i1_u = UBOUND(OutData%Mtot,1) @@ -1006,8 +1006,8 @@ SUBROUTINE MD_UnPackConnect( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs i2_u = UBOUND(OutData%Mtot,2) DO i2 = LBOUND(OutData%Mtot,2), UBOUND(OutData%Mtot,2) DO i1 = LBOUND(OutData%Mtot,1), UBOUND(OutData%Mtot,1) - OutData%Mtot(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%Mtot(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO i1_l = LBOUND(OutData%S,1) @@ -1016,21 +1016,21 @@ SUBROUTINE MD_UnPackConnect( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs i2_u = UBOUND(OutData%S,2) DO i2 = LBOUND(OutData%S,2), UBOUND(OutData%S,2) DO i1 = LBOUND(OutData%S,1), UBOUND(OutData%S,1) - OutData%S(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%S(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO i1_l = LBOUND(OutData%r,1) i1_u = UBOUND(OutData%r,1) DO i1 = LBOUND(OutData%r,1), UBOUND(OutData%r,1) - OutData%r(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%r(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO i1_l = LBOUND(OutData%rd,1) i1_u = UBOUND(OutData%rd,1) DO i1 = LBOUND(OutData%rd,1), UBOUND(OutData%rd,1) - OutData%rd(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%rd(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END SUBROUTINE MD_UnPackConnect @@ -1450,102 +1450,102 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Int_BufSz = Int_BufSz + 1 ! AnchConnect Int_BufSz = Int_BufSz + 1 ! PropsIdNum Int_BufSz = Int_BufSz + 1 ! N - Re_BufSz = Re_BufSz + 1 ! UnstrLen - Re_BufSz = Re_BufSz + 1 ! BA + Db_BufSz = Db_BufSz + 1 ! UnstrLen + Db_BufSz = Db_BufSz + 1 ! BA Int_BufSz = Int_BufSz + 1 ! r allocated yes/no IF ( ALLOCATED(InData%r) ) THEN Int_BufSz = Int_BufSz + 2*2 ! r upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%r) ! r + Db_BufSz = Db_BufSz + SIZE(InData%r) ! r END IF Int_BufSz = Int_BufSz + 1 ! rd allocated yes/no IF ( ALLOCATED(InData%rd) ) THEN Int_BufSz = Int_BufSz + 2*2 ! rd upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%rd) ! rd + Db_BufSz = Db_BufSz + SIZE(InData%rd) ! rd END IF Int_BufSz = Int_BufSz + 1 ! q allocated yes/no IF ( ALLOCATED(InData%q) ) THEN Int_BufSz = Int_BufSz + 2*2 ! q upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%q) ! q + Db_BufSz = Db_BufSz + SIZE(InData%q) ! q END IF Int_BufSz = Int_BufSz + 1 ! l allocated yes/no IF ( ALLOCATED(InData%l) ) THEN Int_BufSz = Int_BufSz + 2*1 ! l upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%l) ! l + Db_BufSz = Db_BufSz + SIZE(InData%l) ! l END IF Int_BufSz = Int_BufSz + 1 ! ld allocated yes/no IF ( ALLOCATED(InData%ld) ) THEN Int_BufSz = Int_BufSz + 2*1 ! ld upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%ld) ! ld + Db_BufSz = Db_BufSz + SIZE(InData%ld) ! ld END IF Int_BufSz = Int_BufSz + 1 ! lstr allocated yes/no IF ( ALLOCATED(InData%lstr) ) THEN Int_BufSz = Int_BufSz + 2*1 ! lstr upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%lstr) ! lstr + Db_BufSz = Db_BufSz + SIZE(InData%lstr) ! lstr END IF Int_BufSz = Int_BufSz + 1 ! lstrd allocated yes/no IF ( ALLOCATED(InData%lstrd) ) THEN Int_BufSz = Int_BufSz + 2*1 ! lstrd upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%lstrd) ! lstrd + Db_BufSz = Db_BufSz + SIZE(InData%lstrd) ! lstrd END IF Int_BufSz = Int_BufSz + 1 ! V allocated yes/no IF ( ALLOCATED(InData%V) ) THEN Int_BufSz = Int_BufSz + 2*1 ! V upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%V) ! V + Db_BufSz = Db_BufSz + SIZE(InData%V) ! V END IF Int_BufSz = Int_BufSz + 1 ! T allocated yes/no IF ( ALLOCATED(InData%T) ) THEN Int_BufSz = Int_BufSz + 2*2 ! T upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%T) ! T + Db_BufSz = Db_BufSz + SIZE(InData%T) ! T END IF Int_BufSz = Int_BufSz + 1 ! Td allocated yes/no IF ( ALLOCATED(InData%Td) ) THEN Int_BufSz = Int_BufSz + 2*2 ! Td upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Td) ! Td + Db_BufSz = Db_BufSz + SIZE(InData%Td) ! Td END IF Int_BufSz = Int_BufSz + 1 ! W allocated yes/no IF ( ALLOCATED(InData%W) ) THEN Int_BufSz = Int_BufSz + 2*2 ! W upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%W) ! W + Db_BufSz = Db_BufSz + SIZE(InData%W) ! W END IF Int_BufSz = Int_BufSz + 1 ! Dp allocated yes/no IF ( ALLOCATED(InData%Dp) ) THEN Int_BufSz = Int_BufSz + 2*2 ! Dp upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Dp) ! Dp + Db_BufSz = Db_BufSz + SIZE(InData%Dp) ! Dp END IF Int_BufSz = Int_BufSz + 1 ! Dq allocated yes/no IF ( ALLOCATED(InData%Dq) ) THEN Int_BufSz = Int_BufSz + 2*2 ! Dq upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Dq) ! Dq + Db_BufSz = Db_BufSz + SIZE(InData%Dq) ! Dq END IF Int_BufSz = Int_BufSz + 1 ! Ap allocated yes/no IF ( ALLOCATED(InData%Ap) ) THEN Int_BufSz = Int_BufSz + 2*2 ! Ap upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Ap) ! Ap + Db_BufSz = Db_BufSz + SIZE(InData%Ap) ! Ap END IF Int_BufSz = Int_BufSz + 1 ! Aq allocated yes/no IF ( ALLOCATED(InData%Aq) ) THEN Int_BufSz = Int_BufSz + 2*2 ! Aq upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Aq) ! Aq + Db_BufSz = Db_BufSz + SIZE(InData%Aq) ! Aq END IF Int_BufSz = Int_BufSz + 1 ! B allocated yes/no IF ( ALLOCATED(InData%B) ) THEN Int_BufSz = Int_BufSz + 2*2 ! B upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%B) ! B + Db_BufSz = Db_BufSz + SIZE(InData%B) ! B END IF Int_BufSz = Int_BufSz + 1 ! F allocated yes/no IF ( ALLOCATED(InData%F) ) THEN Int_BufSz = Int_BufSz + 2*2 ! F upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%F) ! F + Db_BufSz = Db_BufSz + SIZE(InData%F) ! F END IF Int_BufSz = Int_BufSz + 1 ! S allocated yes/no IF ( ALLOCATED(InData%S) ) THEN Int_BufSz = Int_BufSz + 2*3 ! S upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%S) ! S + Db_BufSz = Db_BufSz + SIZE(InData%S) ! S END IF Int_BufSz = Int_BufSz + 1 ! M allocated yes/no IF ( ALLOCATED(InData%M) ) THEN Int_BufSz = Int_BufSz + 2*3 ! M upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%M) ! M + Db_BufSz = Db_BufSz + SIZE(InData%M) ! M END IF Int_BufSz = Int_BufSz + 1 ! LineUnOut Int_BufSz = Int_BufSz + 1 ! LineWrOutput allocated yes/no @@ -1600,10 +1600,10 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%N Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%UnstrLen - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%BA - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%UnstrLen + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%BA + Db_Xferred = Db_Xferred + 1 IF ( .NOT. ALLOCATED(InData%r) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -1619,8 +1619,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz DO i2 = LBOUND(InData%r,2), UBOUND(InData%r,2) DO i1 = LBOUND(InData%r,1), UBOUND(InData%r,1) - ReKiBuf(Re_Xferred) = InData%r(i1,i2) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%r(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -1639,8 +1639,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz DO i2 = LBOUND(InData%rd,2), UBOUND(InData%rd,2) DO i1 = LBOUND(InData%rd,1), UBOUND(InData%rd,1) - ReKiBuf(Re_Xferred) = InData%rd(i1,i2) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%rd(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -1659,8 +1659,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz DO i2 = LBOUND(InData%q,2), UBOUND(InData%q,2) DO i1 = LBOUND(InData%q,1), UBOUND(InData%q,1) - ReKiBuf(Re_Xferred) = InData%q(i1,i2) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%q(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -1675,8 +1675,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Int_Xferred = Int_Xferred + 2 DO i1 = LBOUND(InData%l,1), UBOUND(InData%l,1) - ReKiBuf(Re_Xferred) = InData%l(i1) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%l(i1) + Db_Xferred = Db_Xferred + 1 END DO END IF IF ( .NOT. ALLOCATED(InData%ld) ) THEN @@ -1690,8 +1690,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Int_Xferred = Int_Xferred + 2 DO i1 = LBOUND(InData%ld,1), UBOUND(InData%ld,1) - ReKiBuf(Re_Xferred) = InData%ld(i1) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%ld(i1) + Db_Xferred = Db_Xferred + 1 END DO END IF IF ( .NOT. ALLOCATED(InData%lstr) ) THEN @@ -1705,8 +1705,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Int_Xferred = Int_Xferred + 2 DO i1 = LBOUND(InData%lstr,1), UBOUND(InData%lstr,1) - ReKiBuf(Re_Xferred) = InData%lstr(i1) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%lstr(i1) + Db_Xferred = Db_Xferred + 1 END DO END IF IF ( .NOT. ALLOCATED(InData%lstrd) ) THEN @@ -1720,8 +1720,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Int_Xferred = Int_Xferred + 2 DO i1 = LBOUND(InData%lstrd,1), UBOUND(InData%lstrd,1) - ReKiBuf(Re_Xferred) = InData%lstrd(i1) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%lstrd(i1) + Db_Xferred = Db_Xferred + 1 END DO END IF IF ( .NOT. ALLOCATED(InData%V) ) THEN @@ -1735,8 +1735,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Int_Xferred = Int_Xferred + 2 DO i1 = LBOUND(InData%V,1), UBOUND(InData%V,1) - ReKiBuf(Re_Xferred) = InData%V(i1) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%V(i1) + Db_Xferred = Db_Xferred + 1 END DO END IF IF ( .NOT. ALLOCATED(InData%T) ) THEN @@ -1754,8 +1754,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz DO i2 = LBOUND(InData%T,2), UBOUND(InData%T,2) DO i1 = LBOUND(InData%T,1), UBOUND(InData%T,1) - ReKiBuf(Re_Xferred) = InData%T(i1,i2) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%T(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -1774,8 +1774,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz DO i2 = LBOUND(InData%Td,2), UBOUND(InData%Td,2) DO i1 = LBOUND(InData%Td,1), UBOUND(InData%Td,1) - ReKiBuf(Re_Xferred) = InData%Td(i1,i2) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%Td(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -1794,8 +1794,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz DO i2 = LBOUND(InData%W,2), UBOUND(InData%W,2) DO i1 = LBOUND(InData%W,1), UBOUND(InData%W,1) - ReKiBuf(Re_Xferred) = InData%W(i1,i2) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%W(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -1814,8 +1814,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz DO i2 = LBOUND(InData%Dp,2), UBOUND(InData%Dp,2) DO i1 = LBOUND(InData%Dp,1), UBOUND(InData%Dp,1) - ReKiBuf(Re_Xferred) = InData%Dp(i1,i2) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%Dp(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -1834,8 +1834,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz DO i2 = LBOUND(InData%Dq,2), UBOUND(InData%Dq,2) DO i1 = LBOUND(InData%Dq,1), UBOUND(InData%Dq,1) - ReKiBuf(Re_Xferred) = InData%Dq(i1,i2) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%Dq(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -1854,8 +1854,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz DO i2 = LBOUND(InData%Ap,2), UBOUND(InData%Ap,2) DO i1 = LBOUND(InData%Ap,1), UBOUND(InData%Ap,1) - ReKiBuf(Re_Xferred) = InData%Ap(i1,i2) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%Ap(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -1874,8 +1874,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz DO i2 = LBOUND(InData%Aq,2), UBOUND(InData%Aq,2) DO i1 = LBOUND(InData%Aq,1), UBOUND(InData%Aq,1) - ReKiBuf(Re_Xferred) = InData%Aq(i1,i2) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%Aq(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -1894,8 +1894,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz DO i2 = LBOUND(InData%B,2), UBOUND(InData%B,2) DO i1 = LBOUND(InData%B,1), UBOUND(InData%B,1) - ReKiBuf(Re_Xferred) = InData%B(i1,i2) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%B(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -1914,8 +1914,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz DO i2 = LBOUND(InData%F,2), UBOUND(InData%F,2) DO i1 = LBOUND(InData%F,1), UBOUND(InData%F,1) - ReKiBuf(Re_Xferred) = InData%F(i1,i2) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%F(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -1938,8 +1938,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz DO i3 = LBOUND(InData%S,3), UBOUND(InData%S,3) DO i2 = LBOUND(InData%S,2), UBOUND(InData%S,2) DO i1 = LBOUND(InData%S,1), UBOUND(InData%S,1) - ReKiBuf(Re_Xferred) = InData%S(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%S(i1,i2,i3) + Db_Xferred = Db_Xferred + 1 END DO END DO END DO @@ -1963,8 +1963,8 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz DO i3 = LBOUND(InData%M,3), UBOUND(InData%M,3) DO i2 = LBOUND(InData%M,2), UBOUND(InData%M,2) DO i1 = LBOUND(InData%M,1), UBOUND(InData%M,1) - ReKiBuf(Re_Xferred) = InData%M(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%M(i1,i2,i3) + Db_Xferred = Db_Xferred + 1 END DO END DO END DO @@ -2039,10 +2039,10 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) Int_Xferred = Int_Xferred + 1 OutData%N = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%UnstrLen = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%BA = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%UnstrLen = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%BA = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! r not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -2061,8 +2061,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END IF DO i2 = LBOUND(OutData%r,2), UBOUND(OutData%r,2) DO i1 = LBOUND(OutData%r,1), UBOUND(OutData%r,1) - OutData%r(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%r(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -2084,8 +2084,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END IF DO i2 = LBOUND(OutData%rd,2), UBOUND(OutData%rd,2) DO i1 = LBOUND(OutData%rd,1), UBOUND(OutData%rd,1) - OutData%rd(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%rd(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -2107,8 +2107,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END IF DO i2 = LBOUND(OutData%q,2), UBOUND(OutData%q,2) DO i1 = LBOUND(OutData%q,1), UBOUND(OutData%q,1) - OutData%q(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%q(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -2126,8 +2126,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) RETURN END IF DO i1 = LBOUND(OutData%l,1), UBOUND(OutData%l,1) - OutData%l(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%l(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ld not allocated @@ -2144,8 +2144,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) RETURN END IF DO i1 = LBOUND(OutData%ld,1), UBOUND(OutData%ld,1) - OutData%ld(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%ld(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! lstr not allocated @@ -2162,8 +2162,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) RETURN END IF DO i1 = LBOUND(OutData%lstr,1), UBOUND(OutData%lstr,1) - OutData%lstr(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%lstr(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! lstrd not allocated @@ -2180,8 +2180,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) RETURN END IF DO i1 = LBOUND(OutData%lstrd,1), UBOUND(OutData%lstrd,1) - OutData%lstrd(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%lstrd(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! V not allocated @@ -2198,8 +2198,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) RETURN END IF DO i1 = LBOUND(OutData%V,1), UBOUND(OutData%V,1) - OutData%V(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%V(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! T not allocated @@ -2220,8 +2220,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END IF DO i2 = LBOUND(OutData%T,2), UBOUND(OutData%T,2) DO i1 = LBOUND(OutData%T,1), UBOUND(OutData%T,1) - OutData%T(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%T(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -2243,8 +2243,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END IF DO i2 = LBOUND(OutData%Td,2), UBOUND(OutData%Td,2) DO i1 = LBOUND(OutData%Td,1), UBOUND(OutData%Td,1) - OutData%Td(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%Td(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -2266,8 +2266,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END IF DO i2 = LBOUND(OutData%W,2), UBOUND(OutData%W,2) DO i1 = LBOUND(OutData%W,1), UBOUND(OutData%W,1) - OutData%W(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%W(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -2289,8 +2289,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END IF DO i2 = LBOUND(OutData%Dp,2), UBOUND(OutData%Dp,2) DO i1 = LBOUND(OutData%Dp,1), UBOUND(OutData%Dp,1) - OutData%Dp(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%Dp(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -2312,8 +2312,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END IF DO i2 = LBOUND(OutData%Dq,2), UBOUND(OutData%Dq,2) DO i1 = LBOUND(OutData%Dq,1), UBOUND(OutData%Dq,1) - OutData%Dq(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%Dq(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -2335,8 +2335,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END IF DO i2 = LBOUND(OutData%Ap,2), UBOUND(OutData%Ap,2) DO i1 = LBOUND(OutData%Ap,1), UBOUND(OutData%Ap,1) - OutData%Ap(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%Ap(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -2358,8 +2358,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END IF DO i2 = LBOUND(OutData%Aq,2), UBOUND(OutData%Aq,2) DO i1 = LBOUND(OutData%Aq,1), UBOUND(OutData%Aq,1) - OutData%Aq(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%Aq(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -2381,8 +2381,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END IF DO i2 = LBOUND(OutData%B,2), UBOUND(OutData%B,2) DO i1 = LBOUND(OutData%B,1), UBOUND(OutData%B,1) - OutData%B(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%B(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -2404,8 +2404,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END IF DO i2 = LBOUND(OutData%F,2), UBOUND(OutData%F,2) DO i1 = LBOUND(OutData%F,1), UBOUND(OutData%F,1) - OutData%F(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%F(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -2431,8 +2431,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) DO i3 = LBOUND(OutData%S,3), UBOUND(OutData%S,3) DO i2 = LBOUND(OutData%S,2), UBOUND(OutData%S,2) DO i1 = LBOUND(OutData%S,1), UBOUND(OutData%S,1) - OutData%S(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%S(i1,i2,i3) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO END DO @@ -2459,8 +2459,8 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) DO i3 = LBOUND(OutData%M,3), UBOUND(OutData%M,3) DO i2 = LBOUND(OutData%M,2), UBOUND(OutData%M,2) DO i1 = LBOUND(OutData%M,1), UBOUND(OutData%M,1) - OutData%M(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%M(i1,i2,i3) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END DO END DO @@ -3056,7 +3056,7 @@ SUBROUTINE MD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 1 ! states allocated yes/no IF ( ALLOCATED(InData%states) ) THEN Int_BufSz = Int_BufSz + 2*1 ! states upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%states) ! states + Db_BufSz = Db_BufSz + SIZE(InData%states) ! states END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -3096,8 +3096,8 @@ SUBROUTINE MD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_Xferred = Int_Xferred + 2 DO i1 = LBOUND(InData%states,1), UBOUND(InData%states,1) - ReKiBuf(Re_Xferred) = InData%states(i1) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%states(i1) + Db_Xferred = Db_Xferred + 1 END DO END IF END SUBROUTINE MD_PackContState @@ -3143,8 +3143,8 @@ SUBROUTINE MD_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err RETURN END IF DO i1 = LBOUND(OutData%states,1), UBOUND(OutData%states,1) - OutData%states(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%states(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END IF END SUBROUTINE MD_UnPackContState diff --git a/modules/nwtc-library/src/Generate_NWTC_Library_Types.bat b/modules/nwtc-library/src/Generate_NWTC_Library_Types.bat index 44f068c955..d6c0ef77f4 100644 --- a/modules/nwtc-library/src/Generate_NWTC_Library_Types.bat +++ b/modules/nwtc-library/src/Generate_NWTC_Library_Types.bat @@ -1,8 +1,8 @@ @ECHO OFF -SET REG_Loc=C:\Users\bjonkman\Documents\DATA\DesignCodes\miscellaneous\FAST_Registry\bin -SET Registry=%REG_Loc%\Registry_Win32.exe -:: SET Registry=%REG_Loc%\Registry.exe +SET REG_Loc=..\..\..\build\bin +::SET Registry=%REG_Loc%\Registry_Win32.exe +SET Registry=%REG_Loc%\Registry.exe SET ModuleName=%1 diff --git a/modules/nwtc-library/src/NWTC_IO.f90 b/modules/nwtc-library/src/NWTC_IO.f90 index 96cf0169fd..3440ebed04 100644 --- a/modules/nwtc-library/src/NWTC_IO.f90 +++ b/modules/nwtc-library/src/NWTC_IO.f90 @@ -63,6 +63,7 @@ MODULE NWTC_IO CHARACTER(99) :: ProgVer = ' ' !< The version (including date) of the calling program. DO NOT USE THIS IN NEW PROGRAMS CHARACTER(1), PARAMETER :: Tab = CHAR( 9 ) !< The tab character. CHARACTER(*), PARAMETER :: CommChars = '!#%' !< Comment characters that mark the end of useful input + INTEGER(IntKi), PARAMETER :: NWTC_SizeOfNumWord = 200 !< maximum length of the words containing numeric input (for ParseVar routines) ! Parameters for writing to echo files (in this module only) @@ -139,7 +140,7 @@ MODULE NWTC_IO END INTERFACE !> \copydoc nwtc_io::parsechvarwdefault - INTERFACE ParseVarWDefault ! Parses a boolean variable name and value from a string, potentially sets to a default value if "Default" is parsed. + INTERFACE ParseVarWDefault ! Parses a character variable name and value from a string, potentially sets to a default value if "Default" is parsed. MODULE PROCEDURE ParseChVarWDefault ! Parses a character string from a string, potentially sets to a default value if "Default" is parsed. MODULE PROCEDURE ParseDbVarWDefault ! Parses a double-precision REAL from a string, potentially sets to a default value if "Default" is parsed. MODULE PROCEDURE ParseInVarWDefault ! Parses an INTEGER from a string, potentially sets to a default value if "Default" is parsed. @@ -245,7 +246,6 @@ MODULE NWTC_IO MODULE PROCEDURE WrR8AryFileNR MODULE PROCEDURE WrR16AryFileNR END INTERFACE - CONTAINS @@ -1696,28 +1696,40 @@ SUBROUTINE ChkParseData ( Words, ExpVarName, FileName, FileLineNum, NameIndx, Er CALL Conv2UC ( ExpUCVarName ) - ! See which word is the variable name. Generate an error if it is neither. - ! If it is the first word, check to make sure the second word is not empty. + ! Allow for an empty variable name to be passed. This occurs when we have + ! multiple lines of items that may not have variable keys associated. In + ! this case, we will assume the first word has the value and return that. + ! Otherwise, we will check which is the variable keyname. + IF ( LEN_TRIM(ExpVarName) == 0 ) THEN + ! There isn't actually a variable name passed in, but this satisfies the + ! logic for retrieving the value in the calling routine + NameIndx = 2 - IF ( TRIM( FndUCVarName ) == TRIM( ExpUCVarName ) ) THEN - NameIndx = 1 - IF ( LEN_TRIM( Words(2) ) == 0 ) THEN - CALL ExitThisRoutine ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data from "'//TRIM( FileName ) & - //'".'//NewLine//' >> The variable "'//TRIM( Words(1) )//'" was not assigned a value on line #' & - //TRIM( Num2LStr( FileLineNum ) )//'.' ) - RETURN - ENDIF ELSE - FndUCVarName = Words(2) - CALL Conv2UC ( FndUCVarName ) + ! See which word is the variable name. Generate an error if it is neither. + ! If it is the first word, check to make sure the second word is not empty. + IF ( TRIM( FndUCVarName ) == TRIM( ExpUCVarName ) ) THEN - NameIndx = 2 + NameIndx = 1 + IF ( LEN_TRIM( Words(2) ) == 0 ) THEN + CALL ExitThisRoutine ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data from "'//TRIM( FileName ) & + //'".'//NewLine//' >> The variable "'//TRIM( Words(1) )//'" was not assigned a value on line #' & + //TRIM( Num2LStr( FileLineNum ) )//'.' ) + RETURN + ENDIF ELSE - CALL ExitThisRoutine ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data from "'//TRIM( FileName ) & - //'".'//NewLine//' >> The variable "'//TRIM( ExpVarName )//'" was not found on line #' & - //TRIM( Num2LStr( FileLineNum ) )//'.' ) - RETURN + FndUCVarName = Words(2) + CALL Conv2UC ( FndUCVarName ) + IF ( TRIM( FndUCVarName ) == TRIM( ExpUCVarName ) ) THEN + NameIndx = 2 + ELSE + CALL ExitThisRoutine ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data from "'//TRIM( FileName ) & + //'".'//NewLine//' >> The variable "'//TRIM( ExpVarName )//'" was not found on line #' & + //TRIM( Num2LStr( FileLineNum ) )//'.' ) + RETURN + ENDIF ENDIF + ENDIF @@ -2264,6 +2276,8 @@ SUBROUTINE DispCompileRuntimeInfo() compiler_version_str = compiler_version() #elif defined(__INTEL_COMPILER) compiler_version_str = 'Intel(R) Fortran Compiler '//num2lstr(__INTEL_COMPILER) +#else + compiler_version_str = OS_Desc #endif CALL WrScr(trim(name)//'-'//trim(git_commit)) @@ -3451,7 +3465,7 @@ SUBROUTINE ParseChVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE CALL GetWords ( FileInfo%Lines(LineNum), Words, 2 ) ! Read the first two words in Line. - IF ( Words(2) == '' ) THEN + IF ( Words(2) == '' .and. (LEN_TRIM(ExpVarName) > 0) ) THEN CALL SetErrStat ( ErrID_Fatal, 'A fatal error occurred when parsing data from "' & //TRIM( FileInfo%FileList(FileInfo%FileIndx(LineNum)) )//'".'//NewLine// & ' >> The variable "'//TRIM( ExpVarName )//'" was not assigned valid string value on line #' & @@ -3616,7 +3630,7 @@ SUBROUTINE ParseDbVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE INTEGER(IntKi) :: ErrStatLcl ! Error status local to this routine. INTEGER(IntKi) :: NameIndx ! The index into the Words array that points to the variable name. - CHARACTER(200) :: Words (2) ! The two "words" parsed from the line. + CHARACTER(NWTC_SizeOfNumWord) :: Words (2) ! The two "words" parsed from the line. CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'ParseDbVar' @@ -3912,7 +3926,7 @@ SUBROUTINE ParseInVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE INTEGER(IntKi) :: ErrStatLcl ! Error status local to this routine. INTEGER(IntKi) :: NameIndx ! The index into the Words array that points to the variable name. - CHARACTER(200) :: Words (2) ! The two "words" parsed from the line. + CHARACTER(NWTC_SizeOfNumWord) :: Words (2) ! The two "words" parsed from the line. CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'ParseInVar' @@ -4097,7 +4111,7 @@ SUBROUTINE ParseLoVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE INTEGER(IntKi) :: ErrStatLcl ! Error status local to this routine. INTEGER(IntKi) :: NameIndx ! The index into the Words array that points to the variable name. - CHARACTER(200) :: Words (2) ! The two "words" parsed from the line. + CHARACTER(NWTC_SizeOfNumWord) :: Words (2) ! The two "words" parsed from the line. CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'ParseLoVar' @@ -4273,7 +4287,7 @@ SUBROUTINE ParseSiVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE INTEGER(IntKi) :: ErrStatLcl ! Error status local to this routine. INTEGER(IntKi) :: NameIndx ! The index into the Words array that points to the variable name. - CHARACTER(200) :: Words (2) ! The two "words" parsed from the line. + CHARACTER(NWTC_SizeOfNumWord) :: Words (2) ! The two "words" parsed from the line. CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'ParseSiVar' @@ -4308,7 +4322,7 @@ SUBROUTINE ParseSiVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE CALL CheckRealVar( Var, ExpVarName, ErrStat, ErrMsg) IF ( PRESENT(UnEc) ) THEN - IF ( UnEc > 0 ) WRITE (UnEc,'(1X,A15," = ",A20)') Words + IF ( UnEc > 0 ) WRITE (UnEc,'(1X,A15," = ",A20)') Words !bjj: not sure this is the best way to echo the number being read (in case of truncation, etc) END IF LineNum = LineNum + 1 @@ -5606,7 +5620,7 @@ SUBROUTINE ReadFASTbin ( UnIn, Init, FASTdata, ErrStat, ErrMsg ) IF ( FileType == FileFmtID_NoCompressWithoutTime ) THEN DO IRow=1,FASTdata%NumRecs - FASTdata%Data(IRow,2:) = REAL(TmpInArray(IRow,:), ReKi) + FASTdata%Data(IRow,2:) = REAL(TmpR8InArray(IRow,:), ReKi) END DO ! IRow=1,FASTdata%NumRecs ELSE DO IRow=1,FASTdata%NumRecs @@ -6285,7 +6299,6 @@ SUBROUTINE ReadR4AryFromStr ( Str, Ary, AryLen, AryName, AryDescr, ErrStat, ErrM RETURN END SUBROUTINE ReadR4AryFromStr !======================================================================= -!======================================================================= !> \copydoc nwtc_io::readcary SUBROUTINE ReadR8Ary ( UnIn, Fil, Ary, AryLen, AryName, AryDescr, ErrStat, ErrMsg, UnEc ) @@ -8676,5 +8689,6 @@ SUBROUTINE WrVTK_SP_vectors3D( Un, dataDescr, dims, origin, gridSpacing, gridVal RETURN END SUBROUTINE WrVTK_SP_vectors3D - + + END MODULE NWTC_IO diff --git a/modules/nwtc-library/src/NWTC_Library_Types.f90 b/modules/nwtc-library/src/NWTC_Library_Types.f90 index 9967947fb1..61640b5329 100644 --- a/modules/nwtc-library/src/NWTC_Library_Types.f90 +++ b/modules/nwtc-library/src/NWTC_Library_Types.f90 @@ -32,14 +32,6 @@ MODULE NWTC_Library_Types !--------------------------------------------------------------------------------------------------------------------------------- USE SysSubs IMPLICIT NONE - - TYPE NWTC_RandomNumber_ParameterType - INTEGER(IntKi) :: pRNG - INTEGER(IntKi) :: RandSeed(3) ! The array that holds the initial random seeds for the 3 components. - INTEGER(IntKi), allocatable :: RandSeedAry(:) ! The array that holds the random seeds. - CHARACTER(6) :: RNG_type ! Type of Random Number Generator to use - END TYPE NWTC_RandomNumber_ParameterType - ! ========= ProgDesc ======= TYPE, PUBLIC :: ProgDesc CHARACTER(99) :: Name !< Name of the program or module [-] @@ -54,8 +46,8 @@ MODULE NWTC_Library_Types INTEGER(IntKi) :: NumChans !< Number of output channels in this binary file (not including the time channel) [-] INTEGER(IntKi) :: NumRecs !< Number of records (rows) of data in the file [-] REAL(DbKi) :: TimeStep !< Time step for evenly-spaced data in the output file (when NumRecs is not allo [-] - CHARACTER(20) , DIMENSION(:), ALLOCATABLE :: ChanNames !< Strings describing the names of the channels from the binary file (including the time channel) [-] - CHARACTER(20) , DIMENSION(:), ALLOCATABLE :: ChanUnits !< Strings describing the units of the channels from the binary file (including the time channel) [-] + CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: ChanNames !< Strings describing the names of the channels from the binary file (including the time channel) [-] + CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: ChanUnits !< Strings describing the units of the channels from the binary file (including the time channel) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Data !< numeric data (rows and columns) from the binary file, including the time channel [-] END TYPE FASTdataType ! ======================= @@ -70,11 +62,11 @@ MODULE NWTC_Library_Types ! ========= FileInfoType ======= TYPE, PUBLIC :: FileInfoType INTEGER(IntKi) :: NumLines - CHARACTER(1024) , DIMENSION(:), ALLOCATABLE :: Lines - INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: FileLine INTEGER(IntKi) :: NumFiles + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: FileLine INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: FileIndx CHARACTER(1024) , DIMENSION(:), ALLOCATABLE :: FileList + CHARACTER(1024) , DIMENSION(:), ALLOCATABLE :: Lines END TYPE FileInfoType ! ======================= ! ========= Quaternion ======= @@ -83,6 +75,14 @@ MODULE NWTC_Library_Types REAL(ReKi) , DIMENSION(1:3) :: v END TYPE Quaternion ! ======================= +! ========= NWTC_RandomNumber_ParameterType ======= + TYPE, PUBLIC :: NWTC_RandomNumber_ParameterType + INTEGER(IntKi) :: pRNG + INTEGER(IntKi) , DIMENSION(1:3) :: RandSeed + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: RandSeedAry + CHARACTER(6) :: RNG_type + END TYPE NWTC_RandomNumber_ParameterType +! ======================= CONTAINS !======================================================================= @@ -1253,206 +1253,206 @@ SUBROUTINE NWTC_Library_UnPackQuaternion( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, E END SUBROUTINE NWTC_Library_UnPackQuaternion SUBROUTINE NWTC_Library_CopyNWTC_RandomNumber_ParameterType( SrcNWTC_RandomNumber_ParameterTypeData, DstNWTC_RandomNumber_ParameterTypeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(NWTC_RandomNumber_ParameterType), INTENT(IN) :: SrcNWTC_RandomNumber_ParameterTypeData - TYPE(NWTC_RandomNumber_ParameterType), INTENT(INOUT) :: DstNWTC_RandomNumber_ParameterTypeData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg + TYPE(NWTC_RandomNumber_ParameterType), INTENT(IN) :: SrcNWTC_RandomNumber_ParameterTypeData + TYPE(NWTC_RandomNumber_ParameterType), INTENT(INOUT) :: DstNWTC_RandomNumber_ParameterTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_CopyNWTC_RandomNumber_ParameterType' + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_CopyNWTC_RandomNumber_ParameterType' ! - ErrStat = ErrID_None - ErrMsg = "" - DstNWTC_RandomNumber_ParameterTypeData%pRNG = SrcNWTC_RandomNumber_ParameterTypeData%pRNG - DstNWTC_RandomNumber_ParameterTypeData%RandSeed = SrcNWTC_RandomNumber_ParameterTypeData%RandSeed + ErrStat = ErrID_None + ErrMsg = "" + DstNWTC_RandomNumber_ParameterTypeData%pRNG = SrcNWTC_RandomNumber_ParameterTypeData%pRNG + DstNWTC_RandomNumber_ParameterTypeData%RandSeed = SrcNWTC_RandomNumber_ParameterTypeData%RandSeed IF (ALLOCATED(SrcNWTC_RandomNumber_ParameterTypeData%RandSeedAry)) THEN - i1_l = LBOUND(SrcNWTC_RandomNumber_ParameterTypeData%RandSeedAry,1) - i1_u = UBOUND(SrcNWTC_RandomNumber_ParameterTypeData%RandSeedAry,1) - IF (.NOT. ALLOCATED(DstNWTC_RandomNumber_ParameterTypeData%RandSeedAry)) THEN - ALLOCATE(DstNWTC_RandomNumber_ParameterTypeData%RandSeedAry(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstNWTC_RandomNumber_ParameterTypeData%RandSeedAry.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstNWTC_RandomNumber_ParameterTypeData%RandSeedAry = SrcNWTC_RandomNumber_ParameterTypeData%RandSeedAry + i1_l = LBOUND(SrcNWTC_RandomNumber_ParameterTypeData%RandSeedAry,1) + i1_u = UBOUND(SrcNWTC_RandomNumber_ParameterTypeData%RandSeedAry,1) + IF (.NOT. ALLOCATED(DstNWTC_RandomNumber_ParameterTypeData%RandSeedAry)) THEN + ALLOCATE(DstNWTC_RandomNumber_ParameterTypeData%RandSeedAry(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstNWTC_RandomNumber_ParameterTypeData%RandSeedAry.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstNWTC_RandomNumber_ParameterTypeData%RandSeedAry = SrcNWTC_RandomNumber_ParameterTypeData%RandSeedAry ENDIF - DstNWTC_RandomNumber_ParameterTypeData%RNG_type = SrcNWTC_RandomNumber_ParameterTypeData%RNG_type -END SUBROUTINE NWTC_Library_CopyNWTC_RandomNumber_ParameterType + DstNWTC_RandomNumber_ParameterTypeData%RNG_type = SrcNWTC_RandomNumber_ParameterTypeData%RNG_type + END SUBROUTINE NWTC_Library_CopyNWTC_RandomNumber_ParameterType -SUBROUTINE NWTC_Library_DestroyNWTC_RandomNumber_ParameterType( NWTC_RandomNumber_ParameterTypeData, ErrStat, ErrMsg ) - TYPE(NWTC_RandomNumber_ParameterType), INTENT(INOUT) :: NWTC_RandomNumber_ParameterTypeData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyNWTC_RandomNumber_ParameterType' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + SUBROUTINE NWTC_Library_DestroyNWTC_RandomNumber_ParameterType( NWTC_RandomNumber_ParameterTypeData, ErrStat, ErrMsg ) + TYPE(NWTC_RandomNumber_ParameterType), INTENT(INOUT) :: NWTC_RandomNumber_ParameterTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyNWTC_RandomNumber_ParameterType' + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 ! - ErrStat = ErrID_None - ErrMsg = "" + ErrStat = ErrID_None + ErrMsg = "" IF (ALLOCATED(NWTC_RandomNumber_ParameterTypeData%RandSeedAry)) THEN - DEALLOCATE(NWTC_RandomNumber_ParameterTypeData%RandSeedAry) + DEALLOCATE(NWTC_RandomNumber_ParameterTypeData%RandSeedAry) ENDIF -END SUBROUTINE NWTC_Library_DestroyNWTC_RandomNumber_ParameterType + END SUBROUTINE NWTC_Library_DestroyNWTC_RandomNumber_ParameterType -SUBROUTINE NWTC_Library_PackNWTC_RandomNumber_ParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(NWTC_RandomNumber_ParameterType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_PackNWTC_RandomNumber_ParameterType' -! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + SUBROUTINE NWTC_Library_PackNWTC_RandomNumber_ParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(NWTC_RandomNumber_ParameterType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_PackNWTC_RandomNumber_ParameterType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! pRNG - Int_BufSz = Int_BufSz + SIZE(InData%RandSeed) ! RandSeed - Int_BufSz = Int_BufSz + 1 ! RandSeedAry allocated yes/no - IF ( ALLOCATED(InData%RandSeedAry) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! RandSeedAry upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%RandSeedAry) ! RandSeedAry - END IF - Int_BufSz = Int_BufSz + 1*LEN(InData%RNG_type) ! RNG_type - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! pRNG + Int_BufSz = Int_BufSz + SIZE(InData%RandSeed) ! RandSeed + Int_BufSz = Int_BufSz + 1 ! RandSeedAry allocated yes/no + IF ( ALLOCATED(InData%RandSeedAry) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! RandSeedAry upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%RandSeedAry) ! RandSeedAry + END IF + Int_BufSz = Int_BufSz + 1*LEN(InData%RNG_type) ! RNG_type + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 - IntKiBuf(Int_Xferred) = InData%pRNG - Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%RandSeed,1), UBOUND(InData%RandSeed,1) - IntKiBuf(Int_Xferred) = InData%RandSeed(i1) - Int_Xferred = Int_Xferred + 1 - END DO - IF ( .NOT. ALLOCATED(InData%RandSeedAry) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%RandSeedAry,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RandSeedAry,1) - Int_Xferred = Int_Xferred + 2 + IntKiBuf(Int_Xferred) = InData%pRNG + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%RandSeed,1), UBOUND(InData%RandSeed,1) + IntKiBuf(Int_Xferred) = InData%RandSeed(i1) + Int_Xferred = Int_Xferred + 1 + END DO + IF ( .NOT. ALLOCATED(InData%RandSeedAry) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%RandSeedAry,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RandSeedAry,1) + Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%RandSeedAry,1), UBOUND(InData%RandSeedAry,1) - IntKiBuf(Int_Xferred) = InData%RandSeedAry(i1) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - DO I = 1, LEN(InData%RNG_type) - IntKiBuf(Int_Xferred) = ICHAR(InData%RNG_type(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I -END SUBROUTINE NWTC_Library_PackNWTC_RandomNumber_ParameterType + DO i1 = LBOUND(InData%RandSeedAry,1), UBOUND(InData%RandSeedAry,1) + IntKiBuf(Int_Xferred) = InData%RandSeedAry(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + DO I = 1, LEN(InData%RNG_type) + IntKiBuf(Int_Xferred) = ICHAR(InData%RNG_type(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END SUBROUTINE NWTC_Library_PackNWTC_RandomNumber_ParameterType -SUBROUTINE NWTC_Library_UnPackNWTC_RandomNumber_ParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(NWTC_RandomNumber_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_UnPackNWTC_RandomNumber_ParameterType' -! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%pRNG = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%RandSeed,1) - i1_u = UBOUND(OutData%RandSeed,1) - DO i1 = LBOUND(OutData%RandSeed,1), UBOUND(OutData%RandSeed,1) - OutData%RandSeed(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! RandSeedAry not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%RandSeedAry)) DEALLOCATE(OutData%RandSeedAry) - ALLOCATE(OutData%RandSeedAry(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%RandSeedAry.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%RandSeedAry,1), UBOUND(OutData%RandSeedAry,1) - OutData%RandSeedAry(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - DO I = 1, LEN(OutData%RNG_type) - OutData%RNG_type(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I -END SUBROUTINE NWTC_Library_UnPackNWTC_RandomNumber_ParameterType + SUBROUTINE NWTC_Library_UnPackNWTC_RandomNumber_ParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(NWTC_RandomNumber_ParameterType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_UnPackNWTC_RandomNumber_ParameterType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%pRNG = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%RandSeed,1) + i1_u = UBOUND(OutData%RandSeed,1) + DO i1 = LBOUND(OutData%RandSeed,1), UBOUND(OutData%RandSeed,1) + OutData%RandSeed(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! RandSeedAry not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%RandSeedAry)) DEALLOCATE(OutData%RandSeedAry) + ALLOCATE(OutData%RandSeedAry(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%RandSeedAry.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%RandSeedAry,1), UBOUND(OutData%RandSeedAry,1) + OutData%RandSeedAry(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + DO I = 1, LEN(OutData%RNG_type) + OutData%RNG_type(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END SUBROUTINE NWTC_Library_UnPackNWTC_RandomNumber_ParameterType END MODULE NWTC_Library_Types !ENDOFREGISTRYGENERATEDFILE diff --git a/modules/nwtc-library/src/NWTC_Num.f90 b/modules/nwtc-library/src/NWTC_Num.f90 index 2b0786ed44..3bbfae4a79 100644 --- a/modules/nwtc-library/src/NWTC_Num.f90 +++ b/modules/nwtc-library/src/NWTC_Num.f90 @@ -55,6 +55,18 @@ MODULE NWTC_Num REAL(ReKi) :: TwoByPi !< 2/Pi REAL(ReKi) :: TwoPi !< 2*Pi + REAL(SiKi) :: D2R_S !< Factor to convert degrees to radians in single precision + REAL(SiKi) :: Inf_S !< IEEE value for NaN (not-a-number) in single precision + REAL(SiKi) :: Inv2Pi_S !< 0.5/Pi (1/(2*Pi)) in single precision + REAL(SiKi) :: NaN_S !< IEEE value for Inf (infinity) in single precision + REAL(SiKi) :: Pi_S !< Ratio of a circle's circumference to its diameter in single precision + REAL(SiKi) :: PiBy2_S !< Pi/2 in single precision + REAL(SiKi) :: R2D_S !< Factor to convert radians to degrees in single precision + REAL(SiKi) :: RPM2RPS_S !< Factor to convert revolutions per minute to radians per second in single precision + REAL(SiKi) :: RPS2RPM_S !< Factor to convert radians per second to revolutions per minute in single precision + REAL(SiKi) :: TwoByPi_S !< 2/Pi in single precision + REAL(SiKi) :: TwoPi_S !< 2*Pi in single precision + REAL(SiKi) :: Pi_R4 !< Ratio of a circle's circumference to its diameter in 4-byte precision REAL(R8Ki) :: Pi_R8 !< Ratio of a circle's circumference to its diameter in 8-byte precision REAL(QuKi) :: Pi_R16 !< Ratio of a circle's circumference to its diameter in 16-byte precision @@ -5357,6 +5369,15 @@ SUBROUTINE SetConstants( ) TwoPi = 2.0_ReKi*Pi Inv2Pi = 0.5_ReKi/Pi ! 1.0/TwoPi + Pi_S = ACOS( -1.0_SiKi ) + D2R_S = Pi_S/180.0_SiKi + R2D_S = 180.0_SiKi/Pi_S + PiBy2_S = Pi_S/2.0_SiKi + RPM2RPS_S = Pi_S/30.0_SiKi + RPS2RPM_S = 30.0_SiKi/Pi_S + TwoByPi_S = 2.0_SiKi/Pi_S + TwoPi_S = 2.0_SiKi*Pi_S + Inv2Pi_S = 0.5_SiKi/Pi_S ! 1.0_SiKi/TwoPi_S Pi_R4 = ACOS( -1.0_SiKi ) Pi_R8 = ACOS( -1.0_R8Ki ) Pi_R16 = ACOS( -1.0_QuKi ) @@ -5366,7 +5387,7 @@ SUBROUTINE SetConstants( ) TwoPi_R16 = Pi_R16*2.0_QuKi ! IEEE constants: - CALL Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) + CALL Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf, NaN_S, Inf_S ) RETURN diff --git a/modules/nwtc-library/src/NetLib/lapack/NWTC_LAPACK.f90 b/modules/nwtc-library/src/NetLib/lapack/NWTC_LAPACK.f90 index 99cdd7a088..54a61f1bac 100644 --- a/modules/nwtc-library/src/NetLib/lapack/NWTC_LAPACK.f90 +++ b/modules/nwtc-library/src/NetLib/lapack/NWTC_LAPACK.f90 @@ -93,15 +93,19 @@ MODULE NWTC_LAPACK MODULE PROCEDURE LAPACK_spptrf END INTERFACE -!> Compute the SVD for a general matrix A = USV^T. + !> Compute the SVD for a general matrix A = USV^T. INTERFACE LAPACK_gesvd MODULE PROCEDURE LAPACK_dgesvd MODULE PROCEDURE LAPACK_sgesvd END INTERFACE + !> Unpack packed (1D) to regular matrix format (2D) + INTERFACE LAPACK_TPTTR + MODULE PROCEDURE LAPACK_STPTTR + MODULE PROCEDURE LAPACK_DTPTTR + END INTERFACE -!> straight-up lapack routines (from ExtPtfm_MCKF): - + !> straight-up lapack routines (from ExtPtfm_MCKF): INTERFACE LAPACK_COPY SUBROUTINE DCOPY(N,DX,INCX,DY,INCY) USE Precision, only: R8Ki @@ -1576,5 +1580,57 @@ SUBROUTINE LAPACK_SGESVD(JOBU, JOBVT, M, N, A, S, U, VT, WORK, LWORK, ErrStat, E RETURN END SUBROUTINE LAPACK_SGESVD -!======================================================================= + !======================================================================= + !INTERFACE LAPACK_TPTTR: + !> Unpack a by-column-packed array into a 2D matrix format + !! See documentation in DTPTTR/STPTTR source code. + SUBROUTINE LAPACK_DTPTTR( UPLO, N, AP, A, LDA, ErrStat, ErrMsg ) + CHARACTER(1), intent(in ) :: UPLO !< = 'U': A is an upper triangular matrix; 'L': A is a lower triangular matrix + INTEGER, intent(in ) :: N !< The order of matrix A and AP. + INTEGER, intent(in) :: LDA !< The leading dimension of the matrix A. LDA ? max(1,N) + INTEGER(IntKi), intent(out) :: ErrStat !< Error level + CHARACTER(*), intent(out) :: ErrMsg !< Message describing error + REAL(R8Ki), intent(in) :: AP( : ) !< Packed array + REAL(R8Ki), intent(out) :: A( :,: ) !< Unpacked array : Note AP(1)=A(1,1); AP(2)=A(1,2); AP(3)=A(2,2); AP(4)=A(1,3) etc. by column, upper triang + INTEGER :: INFO ! = 0: successful exit; < 0: if INFO = -i, the i-th argument had an illegal value + ErrStat = ErrID_None + ErrMsg = "" + CALL DTPTTR( UPLO, N, AP, A, LDA, INFO ) + IF (INFO /= 0) THEN + ErrStat = ErrID_FATAL + WRITE( ErrMsg, * ) INFO + IF (INFO < 0) THEN + ErrMsg = "LAPACK_DTPTTR: illegal value in argument "//TRIM(ErrMsg)//"." + ELSE + ErrMsg = 'LAPACK_DTPTTR: Unknown error '//TRIM(ErrMsg)//'.' + END IF + END IF + RETURN + END SUBROUTINE LAPACK_DTPTTR + !======================================================================= + !> Unpack a by-column-packed array into a 2D matrix format + SUBROUTINE LAPACK_STPTTR( UPLO, N, AP, A, LDA, ErrStat, ErrMsg ) + CHARACTER(1), intent(in ) :: UPLO !< = 'U': A is an upper triangular matrix; 'L': A is a lower triangular matrix + INTEGER, intent(in ) :: N !< The order of matrix A and AP. + INTEGER, intent(in) :: LDA !< The leading dimension of the matrix A. LDA ? max(1,N) + INTEGER(IntKi), intent(out) :: ErrStat !< Error level + CHARACTER(*), intent(out) :: ErrMsg !< Message describing error + REAL(SiKi), intent(in) :: AP( : ) !< Packed array + REAL(SiKi), intent(out) :: A( :,: ) !< Unpacked array : Note AP(1)=A(1,1); AP(2)=A(1,2); AP(3)=A(2,2); AP(4)=A(1,3) etc. by column, upper triang + INTEGER :: INFO ! = 0: successful exit; < 0: if INFO = -i, the i-th argument had an illegal value + ErrStat = ErrID_None + ErrMsg = "" + CALL STPTTR( UPLO, N, AP, A, LDA, INFO ) + IF (INFO /= 0) THEN + ErrStat = ErrID_FATAL + WRITE( ErrMsg, * ) INFO + IF (INFO < 0) THEN + ErrMsg = "LAPACK_STPTTR: illegal value in argument "//TRIM(ErrMsg)//"." + ELSE + ErrMsg = 'LAPACK_STPTTR: Unknown error '//TRIM(ErrMsg)//'.' + END IF + END IF + RETURN + END SUBROUTINE LAPACK_STPTTR + !======================================================================= END MODULE NWTC_LAPACK diff --git a/modules/nwtc-library/src/Registry_NWTC_Library.txt b/modules/nwtc-library/src/Registry_NWTC_Library.txt index eb3d0b0d0b..a237d6de6a 100644 --- a/modules/nwtc-library/src/Registry_NWTC_Library.txt +++ b/modules/nwtc-library/src/Registry_NWTC_Library.txt @@ -15,8 +15,8 @@ usefrom ^ ^ CHARACTER(1024) Descr usefrom ^ ^ IntKi NumChans usefrom ^ ^ IntKi NumRecs usefrom ^ ^ DbKi TimeStep -usefrom ^ ^ CHARACTER(20) ChanNames {:} -usefrom ^ ^ CHARACTER(20) ChanUnits {:} +usefrom ^ ^ CHARACTER(ChanLen) ChanNames {:} +usefrom ^ ^ CHARACTER(ChanLen) ChanUnits {:} usefrom ^ ^ ReKi Data {:}{:} usefrom NWTC_Library OutParmType IntKi Indx @@ -25,15 +25,20 @@ usefrom ^ ^ CHARACTER(ChanLen) Units usefrom ^ ^ IntKi SignM usefrom NWTC_Library FileInfoType IntKi NumLines -usefrom ^ ^ CHARACTER(1024) Lines {:} -usefrom ^ ^ IntKi FileLine {:} usefrom ^ ^ IntKi NumFiles +usefrom ^ ^ IntKi FileLine {:} usefrom ^ ^ IntKi FileIndx {:} usefrom ^ ^ CHARACTER(1024) FileList {:} +usefrom ^ ^ CHARACTER(1024) Lines {:} usefrom NWTC_Library Quaternion ReKi q0 usefrom ^ ^ ReKi v {3} +usefrom NWTC_Library NWTC_RandomNumber_ParameterType IntKi pRNG +usefrom ^ ^ IntKi RandSeed {3} +usefrom ^ ^ IntKi RandSeedAry {:} +usefrom ^ ^ CHARACTER(6) RNG_type + #BJJ: the following three types will actually be placed in the ModMesh_Mapping.f90 file instead of NWTC_Library_Types.f90 usefrom NWTC_Library MapType IntKi OtherMesh_Element usefrom ^ ^ R8Ki distance - @@ -64,8 +69,3 @@ usefrom ^ ^ R8Ki LoadLn2_F usefrom ^ ^ R8Ki LoadLn2_M {:}{:} usefrom ^ ^ MeshMapLinearizationType dM -usefrom NWTC_Library NWTC_RandomNumber_ParameterType IntKi pRNG -usefrom ^ ^ IntKi RandSeed {3} -usefrom ^ ^ IntKi RandSeedAry {:} -usefrom ^ ^ CHARACTER(6) RNG_type - diff --git a/modules/nwtc-library/src/Registry_NWTC_Library_typedef_mesh.txt b/modules/nwtc-library/src/Registry_NWTC_Library_typedef_mesh.txt index bb2096f1fd..e1720a4772 100644 --- a/modules/nwtc-library/src/Registry_NWTC_Library_typedef_mesh.txt +++ b/modules/nwtc-library/src/Registry_NWTC_Library_typedef_mesh.txt @@ -9,9 +9,9 @@ #BJJ: the following three types will actually be placed in the ModMesh_Mapping.f90 file instead of NWTC_Library_Types.f90 typedef NWTC_Library MapType IntKi OtherMesh_Element - - - "Node (for point meshes) or Element (for line2 meshes) number on other mesh; for loads, other mesh is Dest, for motions/scalars, other mesh is Src" -typedef ^ ^ R8Ki distance - - - "Magnitude of couple_arm" -typedef ^ ^ R8Ki couple_arm {3} - - "Vector between a point and node 1 of an element (p_ODR - p_OSR)" -typedef ^ ^ R8Ki shape_fn {2} - - "shape functions: 1-D element-level location [0,1] based on closest-line projection of point" +typedef ^ ^ R8Ki distance - - - "Magnitude of couple_arm" m +typedef ^ ^ R8Ki couple_arm {3} - - "Vector between a point and node 1 of an element (p_ODR - p_OSR)" m +typedef ^ ^ R8Ki shape_fn {2} - - "shape functions: 1-D element-level location [0,1] based on closest-line projection of point" - typedef NWTC_Library MeshMapLinearizationType R8Ki mi {:}{:} - - "block matrix of motions that reflects identity (i.e., solely the mapping of one quantity to itself on another mesh)" typedef ^ ^ R8Ki fx_p {:}{:} - - "block matrix of motions that reflects skew-symmetric (cross-product) matrix" @@ -25,13 +25,13 @@ typedef ^ ^ R8Ki M_uS { typedef ^ ^ R8Ki M_uD {:}{:} - - "block matrix of moment that is multiplied by Destination u (translationDisp)" typedef ^ ^ R8Ki M_f {:}{:} - - "block matrix of moment that is multiplied by force" -typedef NWTC_Library MeshMapType MapType MapLoads {:} - - "mapping data structure for loads on the mesh" -typedef ^ ^ MapType MapMotions {:} - - "mapping data structure for motions and/or scalars on the mesh" +typedef NWTC_Library MeshMapType MapType MapLoads {:} - - "mapping data structure for load fields on the mesh" +typedef ^ ^ MapType MapMotions {:} - - "mapping data structure for motion and/or scalar fields on the mesh" typedef ^ ^ MapType MapSrcToAugmt {:} - - "for source line2 loads, we map between source and an augmented source mesh, then between augmented source and destination" typedef ^ ^ MeshType Augmented_Ln2_Src - - - "temporary mesh for storing augmented line2 source values" typedef ^ ^ MeshType Lumped_Points_Src - - - "temporary mesh for lumping lines to points, stored here for efficiency" typedef ^ ^ INTEGER LoadLn2_A_Mat_Piv {:} - - "The pivot values for the factorization of LoadLn2_A_Mat" -typedef ^ ^ R8Ki DisplacedPosition {:}{:}{:} - - "couple_arm +Scr%Disp - Dest%Disp for each mapped node (stored here for efficiency)" +typedef ^ ^ R8Ki DisplacedPosition {:}{:}{:} - - "couple_arm +Scr%Disp - Dest%Disp for each mapped node (stored here for efficiency)" m typedef ^ ^ R8Ki LoadLn2_A_Mat {:}{:} - - "The 3-components of the forces for each node of an element in the point-to-line load mapping (for each element)" typedef ^ ^ R8Ki LoadLn2_F {:}{:} - - "The 6-by-6 matrix that makes up the diagonal of the [A 0; B A] matrix in the point-to-line load mapping" typedef ^ ^ R8Ki LoadLn2_M {:}{:} - - "The 3-components of the moments for each node of an element in the point-to-line load mapping (for each element)" diff --git a/modules/nwtc-library/src/Registry_NWTC_Library_typedef_nomesh.txt b/modules/nwtc-library/src/Registry_NWTC_Library_typedef_nomesh.txt index b69bd3831b..3207dde39c 100644 --- a/modules/nwtc-library/src/Registry_NWTC_Library_typedef_nomesh.txt +++ b/modules/nwtc-library/src/Registry_NWTC_Library_typedef_nomesh.txt @@ -15,8 +15,8 @@ typedef ^ ^ CHARACTER(1024) Descr - typedef ^ ^ IntKi NumChans - - - "Number of output channels in this binary file (not including the time channel)" typedef ^ ^ IntKi NumRecs - - - "Number of records (rows) of data in the file" typedef ^ ^ DbKi TimeStep - - - "Time step for evenly-spaced data in the output file (when NumRecs is not allo" -typedef ^ ^ CHARACTER(20) ChanNames {:} - - "Strings describing the names of the channels from the binary file (including the time channel)" -typedef ^ ^ CHARACTER(20) ChanUnits {:} - - "Strings describing the units of the channels from the binary file (including the time channel)" +typedef ^ ^ CHARACTER(ChanLen) ChanNames {:} - - "Strings describing the names of the channels from the binary file (including the time channel)" +typedef ^ ^ CHARACTER(ChanLen) ChanUnits {:} - - "Strings describing the units of the channels from the binary file (including the time channel)" typedef ^ ^ ReKi Data {:}{:} - - "numeric data (rows and columns) from the binary file, including the time channel" typedef NWTC_Library OutParmType IntKi Indx - - - "An index into AllOuts array where this channel is computed/stored" @@ -24,14 +24,17 @@ typedef ^ ^ CHARACTER(ChanLen) Name - - typedef ^ ^ CHARACTER(ChanLen) Units - - - "Units this channel is specified in" typedef ^ ^ IntKi SignM - - - "Multiplier for output channel; usually -1 (minus) or 0 (invalid channel)" - typedef NWTC_Library FileInfoType IntKi NumLines typedef ^ ^ IntKi NumFiles typedef ^ ^ IntKi FileLine {:} typedef ^ ^ IntKi FileIndx {:} typedef ^ ^ CHARACTER(1024) FileList {:} -typedef ^ ^ CHARACTER(512) Lines {:} +typedef ^ ^ CHARACTER(1024) Lines {:} typedef NWTC_Library Quaternion ReKi q0 typedef ^ ^ ReKi v {3} +typedef NWTC_Library NWTC_RandomNumber_ParameterType IntKi pRNG +typedef ^ ^ IntKi RandSeed {3} +typedef ^ ^ IntKi RandSeedAry {:} +typedef ^ ^ CHARACTER(6) RNG_type diff --git a/modules/nwtc-library/src/SysGnuLinux.f90 b/modules/nwtc-library/src/SysGnuLinux.f90 index 7257e32561..8f3eeb9bc4 100644 --- a/modules/nwtc-library/src/SysGnuLinux.f90 +++ b/modules/nwtc-library/src/SysGnuLinux.f90 @@ -32,7 +32,7 @@ MODULE SysSubs ! SUBROUTINE OpenCon ! SUBROUTINE OpenUnfInpBEFile ( Un, InFile, RecLen, Error ) ! SUBROUTINE ProgExit ( StatCode ) - ! SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) + ! SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf, NaN_S, Inf_S ) ! SUBROUTINE UsrAlarm ! SUBROUTINE WrNR ( Str ) ! SUBROUTINE WrOver ( Str ) @@ -288,7 +288,7 @@ SUBROUTINE ProgExit ( StatCode ) END SUBROUTINE ProgExit ! ( StatCode ) !======================================================================= -SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) +SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf, NaN_S, Inf_S ) ! routine that sets the values of NaN_D, Inf_D, NaN, Inf (IEEE ! values for not-a-number and infinity in sindle and double @@ -301,10 +301,13 @@ SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) REAL(DbKi), INTENT(inout) :: NaN_D ! IEEE value for Inf (infinity) in double precision REAL(ReKi), INTENT(inout) :: Inf ! IEEE value for NaN (not-a-number) REAL(ReKi), INTENT(inout) :: NaN ! IEEE value for Inf (infinity) + REAL(SiKi), INTENT(inout) :: Inf_S ! IEEE value for NaN (not-a-number) in single precision + REAL(SiKi), INTENT(inout) :: NaN_S ! IEEE value for Inf (infinity) in single precision ! local variables for getting values of NaN and Inf (not necessary when using ieee_arithmetic) REAL(DbKi) :: Neg_D ! a negative real(DbKi) number REAL(ReKi) :: Neg ! a negative real(ReKi) number + REAL(SiKi) :: Neg_S ! a negative real(SiKi) number ! if compiling with floating-point-exception traps, this will not work, so we've added a compiler directive. @@ -314,16 +317,20 @@ SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) ! set variables to negative numbers to calculate NaNs (compilers may complain when taking sqrt of negative constants) Neg_D = -1.0_DbKi Neg = -1.0_ReKi + Neg_S = -1.0_SiKi NaN_D = SQRT ( Neg_D ) NaN = SQRT ( Neg ) + NaN_S = SQRT ( Neg_S ) ! set variables to zero to calculate Infs (using division by zero) Neg_D = 0.0_DbKi Neg = 0.0_ReKi + Neg_S = 0.0_SiKi Inf_D = 1.0_DbKi / Neg_D Inf = 1.0_ReKi / Neg + Inf_S = 1.0_SiKi / Neg_S #endif END SUBROUTINE Set_IEEE_Constants @@ -489,7 +496,7 @@ FUNCTION dlSym(handle,name) BIND(C,NAME="dlsym") DLL%ProcAddr(i) = dlSym( DLL%FileAddrX, TRIM(DLL%ProcName(i))//C_NULL_CHAR ) !the "C_NULL_CHAR" converts the Fortran string to a C-type string (i.e., adds //CHAR(0) to the end) IF(.NOT. C_ASSOCIATED(DLL%ProcAddr(i))) THEN - ErrStat = ErrID_Fatal + ErrStat = ErrID_Fatal + i - 1 ErrMsg = 'The procedure '//TRIM(DLL%ProcName(i))//' in file '//TRIM(DLL%FileName)//' could not be loaded.' RETURN END IF diff --git a/modules/nwtc-library/src/SysGnuWin.f90 b/modules/nwtc-library/src/SysGnuWin.f90 index a515e2e003..f761a2e723 100644 --- a/modules/nwtc-library/src/SysGnuWin.f90 +++ b/modules/nwtc-library/src/SysGnuWin.f90 @@ -32,7 +32,7 @@ MODULE SysSubs ! SUBROUTINE OpenCon ! SUBROUTINE OpenUnfInpBEFile ( Un, InFile, RecLen, Error ) ! SUBROUTINE ProgExit ( StatCode ) - ! SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) + ! SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf, NaN_S, Inf_S ) ! SUBROUTINE UsrAlarm ! SUBROUTINE WrNR ( Str ) ! SUBROUTINE WrOver ( Str ) @@ -288,7 +288,7 @@ SUBROUTINE ProgExit ( StatCode ) END SUBROUTINE ProgExit ! ( StatCode ) !======================================================================= -SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) +SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf, NaN_S, Inf_S ) ! routine that sets the values of NaN_D, Inf_D, NaN, Inf (IEEE ! values for not-a-number and infinity in sindle and double @@ -301,10 +301,13 @@ SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) REAL(DbKi), INTENT(inout) :: NaN_D ! IEEE value for Inf (infinity) in double precision REAL(ReKi), INTENT(inout) :: Inf ! IEEE value for NaN (not-a-number) REAL(ReKi), INTENT(inout) :: NaN ! IEEE value for Inf (infinity) + REAL(SiKi), INTENT(inout) :: Inf_S ! IEEE value for NaN (not-a-number) in single precision + REAL(SiKi), INTENT(inout) :: NaN_S ! IEEE value for Inf (infinity) in single precision ! local variables for getting values of NaN and Inf (not necessary when using ieee_arithmetic) REAL(DbKi) :: Neg_D ! a negative real(DbKi) number REAL(ReKi) :: Neg ! a negative real(ReKi) number + REAL(SiKi) :: Neg_S ! a negative real(SiKi) number ! if compiling with floating-point-exception traps, this will not work, so we've added a compiler directive. @@ -314,16 +317,20 @@ SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) ! set variables to negative numbers to calculate NaNs (compilers may complain when taking sqrt of negative constants) Neg_D = -1.0_DbKi Neg = -1.0_ReKi + Neg_S = -1.0_SiKi NaN_D = SQRT ( Neg_D ) NaN = SQRT ( Neg ) + NaN_S = SQRT ( Neg_S ) ! set variables to zero to calculate Infs (using division by zero) Neg_D = 0.0_DbKi Neg = 0.0_ReKi + Neg_S = 0.0_SiKi Inf_D = 1.0_DbKi / Neg_D Inf = 1.0_ReKi / Neg + Inf_S = 1.0_SiKi / Neg_S #endif END SUBROUTINE Set_IEEE_Constants @@ -476,7 +483,7 @@ END FUNCTION GetProcAddress if ( len_trim( DLL%ProcName(i) ) > 0 ) then DLL%ProcAddr(i) = GetProcAddress( DLL%FileAddr, TRIM(DLL%ProcName(i))//C_NULL_CHAR ) !the "C_NULL_CHAR" converts the Fortran string to a C-type string (i.e., adds //CHAR(0) to the end) IF(.NOT. C_ASSOCIATED(DLL%ProcAddr(i))) THEN - ErrStat = ErrID_Fatal + ErrStat = ErrID_Fatal + i - 1 ErrMsg = 'The procedure '//TRIM(DLL%ProcName(i))//' in file '//TRIM(DLL%FileName)//' could not be loaded.' RETURN END IF diff --git a/modules/nwtc-library/src/SysIFL.f90 b/modules/nwtc-library/src/SysIFL.f90 index 14fc973377..a3746afde3 100644 --- a/modules/nwtc-library/src/SysIFL.f90 +++ b/modules/nwtc-library/src/SysIFL.f90 @@ -32,7 +32,7 @@ MODULE SysSubs ! SUBROUTINE OpenCon ! SUBROUTINE OpenUnfInpBEFile ( Un, InFile, RecLen, Error ) ! SUBROUTINE ProgExit ( StatCode ) - ! SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) + ! SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf, NaN_S, Inf_S ) ! SUBROUTINE UsrAlarm ! SUBROUTINE WrNR ( Str ) ! SUBROUTINE WrOver ( Str ) @@ -294,7 +294,7 @@ SUBROUTINE ProgExit ( StatCode ) END SUBROUTINE ProgExit ! ( StatCode ) !======================================================================= -SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) +SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf, NaN_S, Inf_S ) ! routine that sets the values of NaN_D, Inf_D, NaN, Inf (IEEE ! values for not-a-number and infinity in sindle and double @@ -310,13 +310,19 @@ SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) REAL(ReKi), INTENT(inout) :: Inf ! IEEE value for NaN (not-a-number) REAL(ReKi), INTENT(inout) :: NaN ! IEEE value for Inf (infinity) + REAL(SiKi), INTENT(inout) :: Inf_S ! IEEE value for NaN (not-a-number) in single precision + REAL(SiKi), INTENT(inout) :: NaN_S ! IEEE value for Inf (infinity) in single precision + NaN_D = ieee_value(0.0_DbKi, ieee_quiet_nan) Inf_D = ieee_value(0.0_DbKi, ieee_positive_inf) NaN = ieee_value(0.0_ReKi, ieee_quiet_nan) Inf = ieee_value(0.0_ReKi, ieee_positive_inf) + NaN_S = ieee_value(0.0_SiKi, ieee_quiet_nan) + Inf_S = ieee_value(0.0_SiKi, ieee_positive_inf) + END SUBROUTINE Set_IEEE_Constants !======================================================================= SUBROUTINE UsrAlarm @@ -468,7 +474,7 @@ FUNCTION dlSym(handle,name) BIND(C,NAME="dlsym") DLL%ProcAddr(i) = dlSym( DLL%FileAddrX, TRIM(DLL%ProcName(i))//C_NULL_CHAR ) !the "C_NULL_CHAR" converts the Fortran string to a C-type string (i.e., adds //CHAR(0) to the end) IF(.NOT. C_ASSOCIATED(DLL%ProcAddr(i))) THEN - ErrStat = ErrID_Fatal + ErrStat = ErrID_Fatal + i - 1 ErrMsg = 'The procedure '//TRIM(DLL%ProcName(i))//' in file '//TRIM(DLL%FileName)//' could not be loaded.' RETURN END IF diff --git a/modules/nwtc-library/src/SysIVF.f90 b/modules/nwtc-library/src/SysIVF.f90 index 84848626c7..0e99442cdb 100644 --- a/modules/nwtc-library/src/SysIVF.f90 +++ b/modules/nwtc-library/src/SysIVF.f90 @@ -32,7 +32,7 @@ MODULE SysSubs ! SUBROUTINE OpenCon ! SUBROUTINE OpenUnfInpBEFile ( Un, InFile, RecLen, Error ) ! SUBROUTINE ProgExit ( StatCode ) - ! SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) + ! SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf, NaN_S, Inf_S ) ! SUBROUTINE UsrAlarm ! SUBROUTINE WrNR ( Str ) ! SUBROUTINE WrOver ( Str ) @@ -298,7 +298,7 @@ END SUBROUTINE ProgExit ! ( StatCode ) !! precision) This uses standard F03 intrinsic routines, !! however Gnu has not yet implemented it, so we've placed this !! routine in the system-specific code. -SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) +SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf, NaN_S, Inf_S ) USE, INTRINSIC :: ieee_arithmetic ! use this for compilers that have implemented ieee_arithmetic from F03 standard (otherwise see logic in SysGnu*.f90) @@ -308,12 +308,18 @@ SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) REAL(ReKi), INTENT(inout) :: Inf !< IEEE value for NaN (not-a-number) REAL(ReKi), INTENT(inout) :: NaN !< IEEE value for Inf (infinity) + REAL(SiKi), INTENT(inout) :: Inf_S !< IEEE value for NaN (not-a-number) in single precision + REAL(SiKi), INTENT(inout) :: NaN_S !< IEEE value for Inf (infinity) in single precision + NaN_D = ieee_value(0.0_DbKi, ieee_quiet_nan) Inf_D = ieee_value(0.0_DbKi, ieee_positive_inf) NaN = ieee_value(0.0_ReKi, ieee_quiet_nan) Inf = ieee_value(0.0_ReKi, ieee_positive_inf) + NaN_S = ieee_value(0.0_SiKi, ieee_quiet_nan) + Inf_S = ieee_value(0.0_SiKi, ieee_positive_inf) + END SUBROUTINE Set_IEEE_Constants !======================================================================= !> This routine generates an alarm to warn the user that something went wrong. @@ -424,7 +430,7 @@ SUBROUTINE LoadDynamicLibProc ( DLL, ErrStat, ErrMsg ) DLL%ProcAddr(i) = TRANSFER(ProcAddr, DLL%ProcAddr(i)) !convert INTEGER(LPVOID) to INTEGER(C_FUNPTR) [used only for compatibility with gfortran] IF(.NOT. C_ASSOCIATED(DLL%ProcAddr(i))) THEN - ErrStat = ErrID_Fatal + ErrStat = ErrID_Fatal + i - 1 ErrMsg = 'The procedure '//TRIM(DLL%ProcName(i))//' in file '//TRIM(DLL%FileName)//' could not be loaded.' RETURN END IF diff --git a/modules/nwtc-library/src/SysIVF_Labview.f90 b/modules/nwtc-library/src/SysIVF_Labview.f90 index 05dc72ae51..40b1600e9d 100644 --- a/modules/nwtc-library/src/SysIVF_Labview.f90 +++ b/modules/nwtc-library/src/SysIVF_Labview.f90 @@ -43,7 +43,7 @@ MODULE SysSubs ! SUBROUTINE OpenCon ! Actually, it can't be removed until we get Intel's FLUSH working. (mlb) ! SUBROUTINE OpenUnfInpBEFile ( Un, InFile, RecLen, Error ) ! SUBROUTINE ProgExit ( StatCode ) - ! SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) + ! SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf, NaN_S, Inf_S ) ! SUBROUTINE UsrAlarm ! SUBROUTINE WrNR ( Str ) ! SUBROUTINE WrOver ( Str ) @@ -362,7 +362,7 @@ SUBROUTINE ProgExit ( StatCode ) END SUBROUTINE ProgExit ! ( StatCode ) !======================================================================= - SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) + SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf, NaN_S, Inf_S ) ! routine that sets the values of NaN_D, Inf_D, NaN, Inf (IEEE ! values for not-a-number and infinity in sindle and double @@ -377,6 +377,9 @@ SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) REAL(ReKi), INTENT(inout) :: Inf ! IEEE value for NaN (not-a-number) REAL(ReKi), INTENT(inout) :: NaN ! IEEE value for Inf (infinity) + REAL(SiKi), INTENT(inout) :: Inf_S ! IEEE value for NaN (not-a-number) in single precision + REAL(SiKi), INTENT(inout) :: NaN_S ! IEEE value for Inf (infinity) in single precision + ! local variables for getting values of NaN and Inf (not necessary when using ieee_arithmetic) REAL(DbKi) :: Neg_D ! a negative real(DbKi) number REAL(ReKi) :: Neg ! a negative real(ReKi) number @@ -389,16 +392,20 @@ SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) ! set variables to negative numbers to calculate NaNs (compilers may complain when taking sqrt of negative constants) Neg_D = -1.0_DbKi Neg = -1.0_ReKi + Neg_S = -1.0_SiKi NaN_D = SQRT ( Neg_D ) NaN = SQRT ( Neg ) + NaN_S = SQRT ( Neg_S ) ! set variables to zero to calculate Infs (using division by zero) Neg_D = 0.0_DbKi Neg = 0.0_ReKi + Neg_S = 0.0_SiKi Inf_D = 1.0_DbKi / Neg_D Inf = 1.0_ReKi / Neg + Inf_S = 1.0_SiKi / Neg_S #endif END SUBROUTINE Set_IEEE_Constants diff --git a/modules/nwtc-library/src/SysMatlabLinuxGnu.f90 b/modules/nwtc-library/src/SysMatlabLinuxGnu.f90 index 180f48503a..7c2931c26a 100644 --- a/modules/nwtc-library/src/SysMatlabLinuxGnu.f90 +++ b/modules/nwtc-library/src/SysMatlabLinuxGnu.f90 @@ -486,7 +486,7 @@ FUNCTION dlSym(handle,name) BIND(C,NAME="dlsym") DLL%ProcAddr(i) = dlSym( DLL%FileAddrX, TRIM(DLL%ProcName(i))//C_NULL_CHAR ) !the "C_NULL_CHAR" converts the Fortran string to a C-type string (i.e., adds //CHAR(0) to the end) IF(.NOT. C_ASSOCIATED(DLL%ProcAddr(i))) THEN - ErrStat = ErrID_Fatal + ErrStat = ErrID_Fatal + i - 1 ErrMsg = 'The procedure '//TRIM(DLL%ProcName(i))//' in file '//TRIM(DLL%FileName)//' could not be loaded.' RETURN END IF diff --git a/modules/nwtc-library/src/SysMatlabLinuxIntel.f90 b/modules/nwtc-library/src/SysMatlabLinuxIntel.f90 index 2cfe4d24ca..cb66012814 100644 --- a/modules/nwtc-library/src/SysMatlabLinuxIntel.f90 +++ b/modules/nwtc-library/src/SysMatlabLinuxIntel.f90 @@ -478,7 +478,7 @@ FUNCTION dlSym(handle,name) BIND(C,NAME="dlsym") DLL%ProcAddr(i) = dlSym( DLL%FileAddrX, TRIM(DLL%ProcName(i))//C_NULL_CHAR ) !the "C_NULL_CHAR" converts the Fortran string to a C-type string (i.e., adds //CHAR(0) to the end) IF(.NOT. C_ASSOCIATED(DLL%ProcAddr(i))) THEN - ErrStat = ErrID_Fatal + ErrStat = ErrID_Fatal + i - 1 ErrMsg = 'The procedure '//TRIM(DLL%ProcName(i))//' in file '//TRIM(DLL%FileName)//' could not be loaded.' RETURN END IF diff --git a/modules/nwtc-library/src/SysMatlabWindows.f90 b/modules/nwtc-library/src/SysMatlabWindows.f90 index e864497641..8e73364b73 100644 --- a/modules/nwtc-library/src/SysMatlabWindows.f90 +++ b/modules/nwtc-library/src/SysMatlabWindows.f90 @@ -27,6 +27,30 @@ MODULE SysSubs +<<<<<<< HEAD:modules/nwtc-library/src/SysMatlab.f90 + ! It contains the following routines: + + ! FUNCTION FileSize( Unit ) ! Returns the size (in bytes) of an open file. + ! SUBROUTINE FlushOut ( Unit ) + ! FUNCTION NWTC_ERF( x ) + ! FUNCTION NWTC_gamma( x ) + ! SUBROUTINE GET_CWD( DirName, Status ) + ! FUNCTION Is_NaN( DblNum ) ! Please use IEEE_IS_NAN() instead + ! FUNCTION NWTC_Gamma( x ) ! Returns the gamma value of its argument. + ! per MLB, this can be removed, but only if CU is OUTPUT_UNIT: + ! SUBROUTINE OpenCon ! Actually, it can't be removed until we get Intel's FLUSH working. (mlb) + ! SUBROUTINE OpenUnfInpBEFile ( Un, InFile, RecLen, Error ) + ! SUBROUTINE ProgExit ( StatCode ) + ! SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf, NaN_S, Inf_S ) + ! SUBROUTINE UsrAlarm + ! SUBROUTINE WrNR ( Str ) + ! SUBROUTINE WrOver ( Str ) + ! SUBROUTINE WriteScr ( Str, Frm ) + ! SUBROUTINE LoadDynamicLib( DLL, ErrStat, ErrMsg ) + ! SUBROUTINE FreeDynamicLib( DLL, ErrStat, ErrMsg ) + +======= +>>>>>>> upstream/master:modules/nwtc-library/src/SysMatlabWindows.f90 USE NWTC_Base @@ -310,20 +334,35 @@ SUBROUTINE ProgExit ( StatCode ) END SUBROUTINE ProgExit ! ( StatCode ) !======================================================================= -!> This routine sets the values of NaN_D, Inf_D, NaN, Inf (IEEE -!! values for not-a-number and infinity in sindle and double -!! precision) This uses standard F03 intrinsic routines, -!! however Gnu has not yet implemented it, so we've placed this -!! routine in the system-specific code. -SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf ) +SUBROUTINE Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf, NaN_S, Inf_S ) + + ! routine that sets the values of NaN_D, Inf_D, NaN, Inf (IEEE + ! values for not-a-number and infinity in sindle and double + ! precision) This uses standard F03 intrinsic routines, + ! however Gnu has not yet implemented it, so we've placed this + ! routine in the system-specific code. + USE, INTRINSIC :: ieee_arithmetic ! use this for compilers that have implemented ieee_arithmetic from F03 standard (otherwise see logic in SysGnu*.f90) - REAL(DbKi), INTENT(inout) :: Inf_D !< IEEE value for NaN (not-a-number) in double precision - REAL(DbKi), INTENT(inout) :: NaN_D !< IEEE value for Inf (infinity) in double precision + REAL(DbKi), INTENT(inout) :: Inf_D ! IEEE value for NaN (not-a-number) in double precision + REAL(DbKi), INTENT(inout) :: NaN_D ! IEEE value for Inf (infinity) in double precision + + REAL(ReKi), INTENT(inout) :: Inf ! IEEE value for NaN (not-a-number) + REAL(ReKi), INTENT(inout) :: NaN ! IEEE value for Inf (infinity) + + REAL(SiKi), INTENT(inout) :: Inf_S ! IEEE value for NaN (not-a-number) in single precision + REAL(SiKi), INTENT(inout) :: NaN_S ! IEEE value for Inf (infinity) in single precision + + + NaN_D = ieee_value(0.0_DbKi, ieee_quiet_nan) + Inf_D = ieee_value(0.0_DbKi, ieee_positive_inf) + + NaN = ieee_value(0.0_ReKi, ieee_quiet_nan) + Inf = ieee_value(0.0_ReKi, ieee_positive_inf) - REAL(ReKi), INTENT(inout) :: Inf !< IEEE value for NaN (not-a-number) - REAL(ReKi), INTENT(inout) :: NaN !< IEEE value for Inf (infinity) + NaN_S = ieee_value(0.0_SiKi, ieee_quiet_nan) + Inf_S = ieee_value(0.0_SiKi, ieee_positive_inf) NaN_D = ieee_value(0.0_DbKi, ieee_quiet_nan) Inf_D = ieee_value(0.0_DbKi, ieee_positive_inf) @@ -472,7 +511,7 @@ SUBROUTINE LoadDynamicLibProc ( DLL, ErrStat, ErrMsg ) DLL%ProcAddr(i) = TRANSFER(ProcAddr, DLL%ProcAddr(i)) !convert INTEGER(LPVOID) to INTEGER(C_FUNPTR) [used only for compatibility with gfortran] IF(.NOT. C_ASSOCIATED(DLL%ProcAddr(i))) THEN - ErrStat = ErrID_Fatal + ErrStat = ErrID_Fatal + i - 1 ErrMsg = 'The procedure '//TRIM(DLL%ProcName(i))//' in file '//TRIM(DLL%FileName)//' could not be loaded.' RETURN END IF diff --git a/modules/openfast-library/CMakeLists.txt b/modules/openfast-library/CMakeLists.txt index 66f97e08ee..ed53eddd38 100644 --- a/modules/openfast-library/CMakeLists.txt +++ b/modules/openfast-library/CMakeLists.txt @@ -56,7 +56,9 @@ target_link_libraries(openfast_postlib openfast_prelib scfastlib foamfastlib ver add_library(openfastlib src/FAST_Library.f90) target_link_libraries(openfastlib openfast_postlib openfast_prelib scfastlib foamfastlib) -if (${CMAKE_Fortran_COMPILER_ID} STREQUAL "GNU" AND ${CMAKE_Fortran_COMPILER_ID} STREQUAL "RELEASE") +string(TOUPPER ${CMAKE_Fortran_COMPILER_ID} _compiler_id) +string(TOUPPER ${CMAKE_BUILD_TYPE} _build_type) +if (${_compiler_id} STREQUAL "GNU" AND ${_build_type} STREQUAL "RELEASE") # With variable tracking enabled, the compile step frequently aborts on large modules and # restarts with this option off. Disabling in Release mode avoids this problem when compiling with # full optimizations, but leaves it enabled for RelWithDebInfo which adds both -O2 and -g flags. diff --git a/modules/openfast-library/src/FAST_Lin.f90 b/modules/openfast-library/src/FAST_Lin.f90 index 8b05043ad2..30696f80fd 100644 --- a/modules/openfast-library/src/FAST_Lin.f90 +++ b/modules/openfast-library/src/FAST_Lin.f90 @@ -30,14 +30,15 @@ MODULE FAST_Linear !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ !---------------------------------------------------------------------------------------------------------------------------------- !> Routine that initializes some variables for linearization. -SUBROUTINE Init_Lin(p_FAST, y_FAST, m_FAST, AD, ED, NumBl, ErrStat, ErrMsg) +SUBROUTINE Init_Lin(p_FAST, y_FAST, m_FAST, AD, ED, NumBl, NumBlNodes, ErrStat, ErrMsg) TYPE(FAST_ParameterType), INTENT(INOUT) :: p_FAST !< Parameters for the glue code TYPE(FAST_OutputFileType),INTENT(INOUT) :: y_FAST !< Output variables for the glue code TYPE(FAST_MiscVarType), INTENT(INOUT) :: m_FAST !< Miscellaneous variables TYPE(AeroDyn_Data), INTENT(IN ) :: AD !< AeroDyn data TYPE(ElastoDyn_Data), INTENT(IN ) :: ED !< ElastoDyn data - INTEGER(IntKi), INTENT(IN ) :: NumBl !< Number of blades (for index into ED input array) + INTEGER(IntKi), INTENT(IN ) :: NumBl !< Number of blades (for index into ED,AD input array) + INTEGER(IntKi), INTENT(IN ) :: NumBlNodes !< Number of blade nodes (for index into AD input array) INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None @@ -103,17 +104,22 @@ SUBROUTINE Init_Lin(p_FAST, y_FAST, m_FAST, AD, ED, NumBl, ErrStat, ErrMsg) p_FAST%Lin_ModOrder( p_FAST%Lin_NumMods ) = Module_HD end if + + ! SD or ExtPtfm is next, if activated: + if ( p_FAST%CompSub == Module_SD ) then + p_FAST%Lin_NumMods = p_FAST%Lin_NumMods + 1 + p_FAST%Lin_ModOrder( p_FAST%Lin_NumMods ) = Module_SD + else if ( p_FAST%CompSub == Module_ExtPtfm ) then + p_FAST%Lin_NumMods = p_FAST%Lin_NumMods + 1 + p_FAST%Lin_ModOrder( p_FAST%Lin_NumMods ) = Module_ExtPtfm + end if + ! MAP is next, if activated: if ( p_FAST%CompMooring == Module_MAP ) then p_FAST%Lin_NumMods = p_FAST%Lin_NumMods + 1 p_FAST%Lin_ModOrder( p_FAST%Lin_NumMods ) = Module_MAP end if - ! ExtPtfm is next, if activated: - if ( p_FAST%CompSub == Module_ExtPtfm ) then - p_FAST%Lin_NumMods = p_FAST%Lin_NumMods + 1 - p_FAST%Lin_ModOrder( p_FAST%Lin_NumMods ) = Module_ExtPtfm - end if !..................... ! determine total number of inputs/outputs/contStates: @@ -153,7 +159,7 @@ SUBROUTINE Init_Lin(p_FAST, y_FAST, m_FAST, AD, ED, NumBl, ErrStat, ErrMsg) ! ................................... ! determine which of the module inputs/outputs are written to file ! ................................... - call Init_Lin_InputOutput(p_FAST, y_FAST, NumBl, ErrStat2, ErrMsg2) + call Init_Lin_InputOutput(p_FAST, y_FAST, NumBl, NumBlNodes, ErrStat2, ErrMsg2) call SetErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) ! ................................... @@ -419,11 +425,12 @@ SUBROUTINE Init_Lin_IfW( p_FAST, y_FAST, u_AD ) END SUBROUTINE Init_Lin_IfW !---------------------------------------------------------------------------------------------------------------------------------- !> Routine that initializes some use_u and use_y, which determine which, if any, inputs and outputs are output in the linearization file. -SUBROUTINE Init_Lin_InputOutput(p_FAST, y_FAST, NumBl, ErrStat, ErrMsg) +SUBROUTINE Init_Lin_InputOutput(p_FAST, y_FAST, NumBl, NumBlNodes, ErrStat, ErrMsg) TYPE(FAST_ParameterType), INTENT(INOUT) :: p_FAST !< Parameters for the glue code TYPE(FAST_OutputFileType),INTENT(INOUT) :: y_FAST !< Output variables for the glue code - INTEGER(IntKi), INTENT(IN ) :: NumBl !< Number of blades (for index into ED input array) + INTEGER(IntKi), INTENT(IN ) :: NumBl !< Number of blades (for index into ED,AD input array) + INTEGER(IntKi), INTENT(IN ) :: NumBlNodes !< Number of blades nodes (for index into AD input array) INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None @@ -476,6 +483,13 @@ SUBROUTINE Init_Lin_InputOutput(p_FAST, y_FAST, NumBl, ErrStat, ErrMsg) end do end do + ! AD standard inputs: UserProp(NumBlNodes,NumBl) + if (p_FAST%CompAero == MODULE_AD) then + do j=1,NumBl*NumBlNodes + y_FAST%Lin%Modules(MODULE_AD)%Instance(1)%use_u(y_FAST%Lin%Modules(MODULE_AD)%Instance(1)%SizeLin(LIN_INPUT_COL)+1-j) = .true. + end do + end if + ! ED standard inputs: BlPitchCom, YawMom, GenTrq, extended input (collective pitch) do j=1,NumBl+3 y_FAST%Lin%Modules(MODULE_ED)%Instance(1)%use_u(y_FAST%Lin%Modules(MODULE_ED)%Instance(1)%SizeLin(LIN_INPUT_COL)+1-j) = .true. @@ -493,13 +507,7 @@ SUBROUTINE Init_Lin_InputOutput(p_FAST, y_FAST, NumBl, ErrStat, ErrMsg) y_FAST%Lin%Modules(MODULE_HD)%Instance(1)%use_u(y_FAST%Lin%Modules(MODULE_HD)%Instance(1)%SizeLin(LIN_INPUT_COL)) = .true. end if - !bjj: removed because I'm not sure these should be included in the "standard" inputs - !!!! ExtPtfm standard inputs: x1, x1dot x1ddot ! TODO TODO TODO CHECK - !!!if (p_FAST%CompSub == MODULE_ExtPtfm) then - !!! do j = 1,18 - !!! y_FAST%Lin%Modules(MODULE_ExtPtfm)%Instance(1)%use_u(y_FAST%Lin%Modules(MODULE_ExtPtfm)%Instance(1)%SizeLin(LIN_INPUT_COL)+1-j) = .true. - !!! end do - !!!end if + ! SD has no standard inputs elseif(p_FAST%LinInputs == LIN_ALL) then do i = 1,p_FAST%Lin_NumMods @@ -899,6 +907,7 @@ SUBROUTINE FAST_Linearize_OP(t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, end if + !..................... ! HydroDyn !..................... @@ -921,6 +930,8 @@ SUBROUTINE FAST_Linearize_OP(t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, call cleanup() return end if + + ! write the module matrices: if (p_FAST%LinOutMod) then @@ -953,56 +964,50 @@ SUBROUTINE FAST_Linearize_OP(t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, ! finish writing the file call WrLinFile_txt_End(Un, p_FAST, y_FAST%Lin%Modules(Module_HD)%Instance(1) ) - end if ! LIN-TODO: Check if this is really where we want to terminate the if block + end if end if + !..................... - ! MAP + ! SubDyn / ExtPtfm !..................... - if ( p_FAST%CompMooring == Module_MAP ) then - ! LIN-TODO: We need this to compute the dYdu total derivative which is D for MAP, and the template uses OtherSt(STATE_CURR), but the FAST MAP DATA has OtherSt as a scalar - call MAP_JacobianPInput( t_global, MAPp%Input(1), MAPp%p, MAPp%x(STATE_CURR), MAPp%xd(STATE_CURR), MAPp%z(STATE_CURR), & - MAPp%OtherSt, MAPp%y, ErrStat2, ErrMsg2, y_FAST%Lin%Modules(Module_MAP)%Instance(1)%D ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - ! et the operating point - !LIN-TODO: template uses OtherSt(STATE_CURR), but the FAST MAP DATA has OtherSt as a scalar - call MAP_GetOP( t_global, MAPp%Input(1), MAPp%p, MAPp%x(STATE_CURR), MAPp%xd(STATE_CURR), MAPp%z(STATE_CURR), & - MAPp%OtherSt, MAPp%y, ErrStat2, ErrMsg2, & - y_FAST%Lin%Modules(Module_MAP)%Instance(1)%op_u, y_FAST%Lin%Modules(Module_MAP)%Instance(1)%op_y ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if (ErrStat >=AbortErrLev) then - call cleanup() - return - end if - + + if ( p_FAST%CompSub == Module_SD ) then + ! get the jacobians + call SD_JacobianPInput( t_global, SD%Input(1), SD%p, SD%x(STATE_CURR), SD%xd(STATE_CURR), & + SD%z(STATE_CURR), SD%OtherSt(STATE_CURR), SD%y, SD%m, ErrStat2, ErrMsg2, & + dYdu=y_FAST%Lin%Modules(Module_SD)%Instance(1)%D, dXdu=y_FAST%Lin%Modules(Module_SD)%Instance(1)%B ) + if(Failed()) return; + + call SD_JacobianPContState( t_global, SD%Input(1), SD%p, SD%x(STATE_CURR), SD%xd(STATE_CURR), & + SD%z(STATE_CURR), SD%OtherSt(STATE_CURR), SD%y, SD%m, ErrStat2, ErrMsg2,& + dYdx=y_FAST%Lin%Modules(Module_SD)%Instance(1)%C, dXdx=y_FAST%Lin%Modules(Module_SD)%Instance(1)%A ) + if(Failed()) return; + + ! get the operating point + call SD_GetOP(t_global, SD%Input(1), SD%p, SD%x(STATE_CURR), SD%xd(STATE_CURR), SD%z(STATE_CURR),& + SD%OtherSt(STATE_CURR), SD%y, SD%m, ErrStat2, ErrMsg2, u_op=y_FAST%Lin%Modules(Module_SD)%Instance(1)%op_u,& + y_op=y_FAST%Lin%Modules(Module_SD)%Instance(1)%op_y, & + x_op=y_FAST%Lin%Modules(Module_SD)%Instance(1)%op_x, dx_op=y_FAST%Lin%Modules(Module_SD)%Instance(1)%op_dx) + if(Failed()) return; + ! write the module matrices: if (p_FAST%LinOutMod) then + OutFileName = trim(LinRootName)//'.'//TRIM(y_FAST%Module_Abrev(Module_SD)) + call WrLinFile_txt_Head(t_global, p_FAST, y_FAST, y_FAST%Lin%Modules(Module_SD)%Instance(1), OutFileName, Un, ErrStat2, ErrMsg2) + if(Failed()) return; - OutFileName = trim(LinRootName)//'.'//TRIM(y_FAST%Module_Abrev(Module_MAP)) - call WrLinFile_txt_Head(t_global, p_FAST, y_FAST, y_FAST%Lin%Modules(Module_MAP)%Instance(1), OutFileName, Un, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if (ErrStat >=AbortErrLev) then - call cleanup() - return - end if - if (p_FAST%LinOutJac) then ! Jacobians - !dYdu: - call WrPartialMatrix( y_FAST%Lin%Modules(Module_MAP)%Instance(1)%D, Un, p_FAST%OutFmt, 'dYdu', & - UseRow=y_FAST%Lin%Modules(Module_MAP)%Instance(1)%use_y, & - UseCol=y_FAST%Lin%Modules(Module_MAP)%Instance(1)%use_u ) - end if - - ! finish writing the file - call WrLinFile_txt_End(Un, p_FAST, y_FAST%Lin%Modules(Module_MAP)%Instance(1) ) - - end if ! if ( p_FAST%LinOutMod ) - end if ! if ( p_FAST%CompMooring == Module_MAP ) - !..................... - ! ExtPtfm - !..................... - if ( p_FAST%CompSub == Module_ExtPtfm ) then + call WrPartialMatrix(y_FAST%Lin%Modules(Module_SD)%Instance(1)%A, Un, p_FAST%OutFmt, 'dXdx') + call WrPartialMatrix(y_FAST%Lin%Modules(Module_SD)%Instance(1)%B, Un, p_FAST%OutFmt, 'dXdu', UseCol=y_FAST%Lin%Modules(Module_SD)%Instance(1)%use_u) + call WrPartialMatrix(y_FAST%Lin%Modules(Module_SD)%Instance(1)%C, Un, p_FAST%OutFmt, 'dYdx', UseRow=y_FAST%Lin%Modules(Module_SD)%Instance(1)%use_y) + call WrPartialMatrix(y_FAST%Lin%Modules(Module_SD)%Instance(1)%D, Un, p_FAST%OutFmt, 'dYdu', UseRow=y_FAST%Lin%Modules(Module_SD)%Instance(1)%use_y, & + UseCol=y_FAST%Lin%Modules(Module_SD)%Instance(1)%use_u) + end if + ! finish writing the file + call WrLinFile_txt_End(Un, p_FAST, y_FAST%Lin%Modules(Module_SD)%Instance(1) ) + end if + elseif ( p_FAST%CompSub == Module_ExtPtfm ) then ! get the jacobians call ExtPtfm_JacobianPInput( t_global, ExtPtfm%Input(1), ExtPtfm%p, ExtPtfm%x(STATE_CURR), ExtPtfm%xd(STATE_CURR), & ExtPtfm%z(STATE_CURR), ExtPtfm%OtherSt(STATE_CURR), ExtPtfm%y, ExtPtfm%m, ErrStat2, ErrMsg2, & @@ -1038,8 +1043,54 @@ SUBROUTINE FAST_Linearize_OP(t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, ! finish writing the file call WrLinFile_txt_End(Un, p_FAST, y_FAST%Lin%Modules(Module_ExtPtfm)%Instance(1) ) end if - end if ! ExtPtfm + end if ! SubDyn/ExtPtfm + + !..................... + ! MAP + !..................... + if ( p_FAST%CompMooring == Module_MAP ) then + ! LIN-TODO: We need this to compute the dYdu total derivative which is D for MAP, and the template uses OtherSt(STATE_CURR), but the FAST MAP DATA has OtherSt as a scalar + call MAP_JacobianPInput( t_global, MAPp%Input(1), MAPp%p, MAPp%x(STATE_CURR), MAPp%xd(STATE_CURR), MAPp%z(STATE_CURR), & + MAPp%OtherSt, MAPp%y, ErrStat2, ErrMsg2, y_FAST%Lin%Modules(Module_MAP)%Instance(1)%D ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + ! get the operating point + !LIN-TODO: template uses OtherSt(STATE_CURR), but the FAST MAP DATA has OtherSt as a scalar + ! email bonnie for a discussion on this. + call MAP_GetOP( t_global, MAPp%Input(1), MAPp%p, MAPp%x(STATE_CURR), MAPp%xd(STATE_CURR), MAPp%z(STATE_CURR), & + MAPp%OtherSt, MAPp%y, ErrStat2, ErrMsg2, & + y_FAST%Lin%Modules(Module_MAP)%Instance(1)%op_u, y_FAST%Lin%Modules(Module_MAP)%Instance(1)%op_y ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + if (ErrStat >=AbortErrLev) then + call cleanup() + return + end if + + ! write the module matrices: + if (p_FAST%LinOutMod) then + + OutFileName = trim(LinRootName)//'.'//TRIM(y_FAST%Module_Abrev(Module_MAP)) + call WrLinFile_txt_Head(t_global, p_FAST, y_FAST, y_FAST%Lin%Modules(Module_MAP)%Instance(1), OutFileName, Un, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + if (ErrStat >=AbortErrLev) then + call cleanup() + return + end if + + if (p_FAST%LinOutJac) then + ! Jacobians + !dYdu: + call WrPartialMatrix( y_FAST%Lin%Modules(Module_MAP)%Instance(1)%D, Un, p_FAST%OutFmt, 'dYdu', & + UseRow=y_FAST%Lin%Modules(Module_MAP)%Instance(1)%use_y, & + UseCol=y_FAST%Lin%Modules(Module_MAP)%Instance(1)%use_u ) + end if + + ! finish writing the file + call WrLinFile_txt_End(Un, p_FAST, y_FAST%Lin%Modules(Module_MAP)%Instance(1) ) + + end if ! if ( p_FAST%LinOutMod ) + end if ! if ( p_FAST%CompMooring == Module_MAP ) !..................... ! Linearization of glue code Input/Output solve: @@ -1546,7 +1597,7 @@ SUBROUTINE Glue_Jacobians( p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, IfW, OpFM, !! 0 & 0 & 0 & 0 & \frac{\partial U_\Lambda^{AD}}{\partial u^{AD}} \\ !! \end{bmatrix} \f$ !..................................... -! LIN-TODO: Add doc strings for new modules: HD & MAP +! LIN-TODO: Add doc strings for new modules: HD & MAP & SD if (.not. allocated(dUdu)) then call AllocAry(dUdu, y_FAST%Lin%Glue%SizeLin(LIN_INPUT_COL), y_FAST%Lin%Glue%SizeLin(LIN_INPUT_COL), 'dUdu', ErrStat2, ErrMsg2) @@ -1583,24 +1634,26 @@ SUBROUTINE Glue_Jacobians( p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, IfW, OpFM, call Linear_IfW_InputSolve_du_AD( p_FAST, y_FAST, AD%Input(1), dUdu ) end if ! we're using the InflowWind module + !............ + ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial u^{BD}} \end{bmatrix} = \f$ and + ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial u^{AD}} \end{bmatrix} = \f$ and + ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial u^{HD}} \end{bmatrix} = \f$ and + ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial u^{SD}} \end{bmatrix} = \f$ and + ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial u^{MAP}} \end{bmatrix} = \f$ (dUdu block row 3=ED) + !............ + ! we need to do this for CompElast=ED and CompElast=BD - !............ - ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial u^{AD}} \end{bmatrix} = \f$ and - ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial u^{BD}} \end{bmatrix} = \f$ (dUdu block row 3=ED) - !............ - ! we need to do this for CompElast=ED and CompElast=BD - - call Linear_ED_InputSolve_du( p_FAST, y_FAST, ED%Input(1), ED%y, AD%y, AD%Input(1), BD, HD, MAPp, MeshMapData, dUdu, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call Linear_ED_InputSolve_du( p_FAST, y_FAST, ED%Input(1), ED%y, AD%y, AD%Input(1), BD, HD, SD, MAPp, MeshMapData, dUdu, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - !............ - ! \f$ \frac{\partial U_\Lambda^{BD}}{\partial u^{AD}} \end{bmatrix} = \f$ and - ! \f$ \frac{\partial U_\Lambda^{BD}}{\partial u^{BD}} \end{bmatrix} = \f$ (dUdu block row 4=BD) - !............ - IF (p_FAST%CompElast == Module_BD) THEN - call Linear_BD_InputSolve_du( p_FAST, y_FAST, ED%y, AD%y, AD%Input(1), BD, MeshMapData, dUdu, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - END IF + !............ + ! \f$ \frac{\partial U_\Lambda^{BD}}{\partial u^{BD}} \end{bmatrix} = \f$ and + ! \f$ \frac{\partial U_\Lambda^{BD}}{\partial u^{AD}} \end{bmatrix} = \f$ (dUdu block row 4=BD) + !............ + IF (p_FAST%CompElast == Module_BD) THEN + call Linear_BD_InputSolve_du( p_FAST, y_FAST, ED%y, AD%y, AD%Input(1), BD, MeshMapData, dUdu, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + END IF !............ ! \f$ \frac{\partial U_\Lambda^{AD}}{\partial u^{AD}} \end{bmatrix} = \f$ (dUdu block row 5=AD) @@ -1610,19 +1663,29 @@ SUBROUTINE Glue_Jacobians( p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, IfW, OpFM, call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) end if - IF (p_FAST%CompSub == Module_ExtPtfm) THEN - CALL WrScr('>>> FAST_LIN: Linear_ExtPtfm_InputSolve_du, TODO') - ENDIF + !............ ! \f$ \frac{\partial U_\Lambda^{HD}}{\partial u^{HD}} \end{bmatrix} = \f$ (dUdu block row 6=HD) !............ IF (p_FAST%CompHydro == MODULE_HD) THEN - call Linear_HD_InputSolve_du( p_FAST, y_FAST, HD%Input(1), ED%y, MeshMapData, dUdu, ErrStat2, ErrMsg2 ) + call Linear_HD_InputSolve_du( p_FAST, y_FAST, HD%Input(1), ED%y, SD%y, MeshMapData, dUdu, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) end if - ! LIN-TODO: Update the doc lines below to include HD and MAP + !............ + ! \f$ \frac{\partial U_\Lambda^{SD}}{\partial u^{HD}} \end{bmatrix} = \f$ and + ! \f$ \frac{\partial U_\Lambda^{SD}}{\partial u^{SD}} \end{bmatrix} = \f$ and + ! \f$ \frac{\partial U_\Lambda^{SD}}{\partial u^{MAP}} \end{bmatrix} = \f$ (dUdu block row 7=SD) + !............ + IF (p_FAST%CompSub == MODULE_SD) THEN + call Linear_SD_InputSolve_du( p_FAST, y_FAST, SD%Input(1), SD%y, ED%y, HD, MAPp, MeshMapData, dUdu, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + ELSE IF (p_FAST%CompSub == Module_ExtPtfm) THEN + CALL WrScr('>>> FAST_LIN: Linear_ExtPtfm_InputSolve_du, TODO') + ENDIF + + ! LIN-TODO: Update the doc lines below to include HD, SD, and MAP !..................................... ! dUdy !> \f$ \frac{\partial U_\Lambda}{\partial y} = @@ -1660,25 +1723,28 @@ SUBROUTINE Glue_Jacobians( p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, IfW, OpFM, end if - !............ - ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial y^{SrvD}} \end{bmatrix} = \f$ - ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial y^{ED}} \end{bmatrix} = \f$ - ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial y^{BD}} \end{bmatrix} = \f$ - ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial y^{AD}} \end{bmatrix} = \f$ (dUdy block row 3=ED) - !............ + !............ + ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial y^{SrvD}} \end{bmatrix} = \f$ + ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial y^{ED}} \end{bmatrix} = \f$ + ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial y^{BD}} \end{bmatrix} = \f$ + ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial y^{AD}} \end{bmatrix} = \f$ + ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial y^{HD}} \end{bmatrix} = \f$ + ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial y^{SD}} \end{bmatrix} = \f$ + ! \f$ \frac{\partial U_\Lambda^{ED}}{\partial y^{MAP}} \end{bmatrix} = \f$ (dUdy block row 3=ED) + !............ - call Linear_ED_InputSolve_dy( p_FAST, y_FAST, ED%Input(1), ED%y, AD%y, AD%Input(1), BD, HD, MAPp, MeshMapData, dUdy, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call Linear_ED_InputSolve_dy( p_FAST, y_FAST, ED%Input(1), ED%y, AD%y, AD%Input(1), BD, HD, SD, MAPp, MeshMapData, dUdy, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - !............ - ! \f$ \frac{\partial U_\Lambda^{BD}}{\partial y^{ED}} \end{bmatrix} = \f$ - ! \f$ \frac{\partial U_\Lambda^{BD}}{\partial y^{BD}} \end{bmatrix} = \f$ - ! \f$ \frac{\partial U_\Lambda^{BD}}{\partial y^{AD}} \end{bmatrix} = \f$ (dUdy block row 4=BD) - !............ - if (p_FAST%CompElast == MODULE_BD) then - call Linear_BD_InputSolve_dy( p_FAST, y_FAST, ED%Input(1), ED%y, AD%y, AD%Input(1), BD, MeshMapData, dUdy, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - end if + !............ + ! \f$ \frac{\partial U_\Lambda^{BD}}{\partial y^{ED}} \end{bmatrix} = \f$ + ! \f$ \frac{\partial U_\Lambda^{BD}}{\partial y^{BD}} \end{bmatrix} = \f$ + ! \f$ \frac{\partial U_\Lambda^{BD}}{\partial y^{AD}} \end{bmatrix} = \f$ (dUdy block row 4=BD) + !............ + if (p_FAST%CompElast == MODULE_BD) then + call Linear_BD_InputSolve_dy( p_FAST, y_FAST, ED%Input(1), ED%y, AD%y, AD%Input(1), BD, MeshMapData, dUdy, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + end if !............ ! \f$ \frac{\partial U_\Lambda^{AD}}{\partial y^{IfW}} \end{bmatrix} = \f$ @@ -1696,27 +1762,45 @@ SUBROUTINE Glue_Jacobians( p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, IfW, OpFM, end if -! LIN-TODO: Implement HD-related solve + !............ - ! \f$ \frac{\partial U_\Lambda^{HD}}{\partial y^{ED}} \end{bmatrix} = \f$ (dUdy block row 6=HD) + ! \f$ \frac{\partial U_\Lambda^{HD}}{\partial y^{ED}} \end{bmatrix} = \f$ + ! \f$ \frac{\partial U_\Lambda^{HD}}{\partial y^{SD}} \end{bmatrix} = \f$ (dUdy block row 6=HD) !............ if (p_FAST%CompHydro == MODULE_HD) then - call Linear_HD_InputSolve_dy( p_FAST, y_FAST, HD%Input(1), ED%y, MeshMapData, dUdy, ErrStat2, ErrMsg2 ) + call Linear_HD_InputSolve_dy( p_FAST, y_FAST, HD%Input(1), ED%y, SD%y, MeshMapData, dUdy, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) end if -! LIN-TODO: Implement Map-related solve !............ - ! \f$ \frac{\partial U_\Lambda^{MAP}}{\partial y^{ED}} \end{bmatrix} = \f$ (dUdy block row 7=MAP) + ! \f$ \frac{\partial U_\Lambda^{SD}}{\partial y^{ED}} \end{bmatrix} = \f$ + ! \f$ \frac{\partial U_\Lambda^{SD}}{\partial y^{HD}} \end{bmatrix} = \f$ + ! \f$ \frac{\partial U_\Lambda^{SD}}{\partial y^{SD}} \end{bmatrix} = \f$ + ! \f$ \frac{\partial U_\Lambda^{SD}}{\partial y^{MAP}} \end{bmatrix} = \f$ (dUdy block row 7=AD) + !............ + if (p_FAST%CompHydro == MODULE_HD) then + call Linear_HD_InputSolve_dy( p_FAST, y_FAST, HD%Input(1), ED%y, SD%y, MeshMapData, dUdy, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + end if + + !LIN-TODO: Add doc strings and look at above doc string + IF (p_FAST%CompSub == Module_SD) THEN + call Linear_SD_InputSolve_dy( p_FAST, y_FAST, SD%Input(1), SD%y, ED%y, HD, MAPp, MeshMapData, dUdy, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + ELSE IF (p_FAST%CompSub == Module_ExtPtfm) THEN + write(*,*)'>>> FAST_LIN: Linear_ExtPtfm_InputSolve_dy, TODO' + ENDIF + + !............ + ! \f$ \frac{\partial U_\Lambda^{MAP}}{\partial y^{ED}} \end{bmatrix} = \f$ + ! \f$ \frac{\partial U_\Lambda^{MAP}}{\partial y^{SD}} \end{bmatrix} = \f$ (dUdy block row 8=MAP) !............ if (p_FAST%CompMooring == MODULE_MAP) then - call Linear_MAP_InputSolve_dy( p_FAST, y_FAST, MAPp%Input(1), ED%y, MeshMapData, dUdy, ErrStat2, ErrMsg2 ) + call Linear_MAP_InputSolve_dy( p_FAST, y_FAST, MAPp%Input(1), ED%y, SD%y, MeshMapData, dUdy, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) end if - IF (p_FAST%CompSub == Module_ExtPtfm) THEN - CALL WrScr('>>> FAST_LIN: Linear_ExtPtfm_InputSolve_dy, TODO') - ENDIF + END SUBROUTINE Glue_Jacobians !---------------------------------------------------------------------------------------------------------------------------------- @@ -1781,8 +1865,8 @@ SUBROUTINE Linear_IfW_InputSolve_du_AD( p_FAST, y_FAST, u_AD, dUdu ) END SUBROUTINE Linear_IfW_InputSolve_du_AD !---------------------------------------------------------------------------------------------------------------------------------- !> This routine forms the dU^{ED}/du^{BD} and dU^{ED}/du^{AD} blocks (ED row) of dUdu. (i.e., how do changes in the AD and BD inputs affect the ED inputs?) -SUBROUTINE Linear_ED_InputSolve_du( p_FAST, y_FAST, u_ED, y_ED, y_AD, u_AD, BD, HD, MAPp, MeshMapData, dUdu, ErrStat, ErrMsg ) -!LIN-TODO: Augment this interface for HD and MAP +SUBROUTINE Linear_ED_InputSolve_du( p_FAST, y_FAST, u_ED, y_ED, y_AD, u_AD, BD, HD, SD, MAPp, MeshMapData, dUdu, ErrStat, ErrMsg ) + TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Glue-code simulation parameters TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< Glue-code output parameters (for linearization) TYPE(ED_InputType), INTENT(INOUT) :: u_ED !< ED Inputs at t @@ -1791,6 +1875,7 @@ SUBROUTINE Linear_ED_InputSolve_du( p_FAST, y_FAST, u_ED, y_ED, y_AD, u_AD, BD, TYPE(AD_InputType), INTENT(INOUT) :: u_AD !< AD inputs (for AD-ED load linerization) TYPE(BeamDyn_Data), INTENT(INOUT) :: BD !< BD data at t TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HD data at t + TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SD data at t TYPE(MAP_Data), INTENT(INOUT) :: MAPp !< MAP data at t TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules REAL(R8Ki), INTENT(INOUT) :: dUdu(:,:) !< Jacobian matrix of which we are computing the dU^(ED)/du^(AD) block @@ -1802,8 +1887,9 @@ SUBROUTINE Linear_ED_InputSolve_du( p_FAST, y_FAST, u_ED, y_ED, y_AD, u_AD, BD, INTEGER(IntKi) :: BD_Start ! starting index of dUdu (column) where BD root motion inputs are located INTEGER(IntKi) :: AD_Start_Bl ! starting index of dUdu (column) where AD blade motion inputs are located INTEGER(IntKi) :: ED_Start_mt ! starting index of dUdu (row) where ED blade/tower or hub moment inputs are located - INTEGER(IntKi) :: HD_Start - INTEGER(IntKi) :: MAP_Start + INTEGER(IntKi) :: HD_Start ! starting index of dUdu (column) where HD motion inputs are located + INTEGER(IntKi) :: SD_Start ! starting index of dUdu (column) where SD TP motion inputs are located + INTEGER(IntKi) :: MAP_Start ! starting index of dUdu (column) where MAP fairlead motion inputs are located INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None @@ -1887,61 +1973,326 @@ SUBROUTINE Linear_ED_InputSolve_du( p_FAST, y_FAST, u_ED, y_ED, y_AD, u_AD, BD, END IF + ED_Start_mt = Indx_u_ED_Platform_Start(u_ED, y_FAST) & + + u_ED%PlatformPtMesh%NNodes * 3 ! 3 forces at each node (we're going to start at the moments) + + if ( p_FAST%CompSub == Module_SD ) then + !.......... + ! dU^{ED}/du^{SD} + !.......... + ! Transfer SD load outputs to ED PlatformPtMesh input: + ! we're mapping loads, so we also need the sibling meshes' displacements: + SD_Start = Indx_u_SD_TPMesh_Start(SD%Input(1), y_FAST) + + call Linearize_Point_to_Point( SD%y%Y1Mesh, u_ED%PlatformPtMesh, MeshMapData%SD_TP_2_ED_P, ErrStat2, ErrMsg2, SD%Input(1)%TPMesh, y_ED%PlatformPtMesh) !SD%Input(1)%TPMesh and y_ED%PlatformPtMesh contain the displaced positions for load calculations + call SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + + ! SD is source in the mapping, so we want M_{uSm} + if (allocated(MeshMapData%SD_TP_2_ED_P%dM%m_us )) then + call SetBlockMatrix( dUdu, MeshMapData%SD_TP_2_ED_P%dM%m_us, ED_Start_mt, SD_Start ) + end if + + else if ( p_FAST%CompSub == Module_None ) then + !.......... + ! dU^{ED}/du^{HD} + !.......... + + if ( p_FAST%CompHydro == Module_HD ) then ! HydroDyn-{ElastoDyn} + + ! we're just going to assume u_ED%PlatformPtMesh is committed + if ( HD%y%Morison%Mesh%Committed ) then ! meshes for floating + + + ! Transfer HD load outputs to ED PlatformPtMesh input: + ! we're mapping loads, so we also need the sibling meshes' displacements: + HD_Start = Indx_u_HD_Morison_Start(HD%Input(1), y_FAST) + + call Linearize_Point_to_Point( HD%y%Morison%Mesh, u_ED%PlatformPtMesh, MeshMapData%HD_M_P_2_ED_P, ErrStat2, ErrMsg2, HD%Input(1)%Morison%Mesh, y_ED%PlatformPtMesh) !HD%Input(1)%Morison and y_ED%PlatformPtMesh contain the displaced positions for load calculations + call SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + + ! HD is source in the mapping, so we want M_{uSm} + if (allocated(MeshMapData%HD_M_P_2_ED_P%dM%m_us )) then + call SetBlockMatrix( dUdu, MeshMapData%HD_M_P_2_ED_P%dM%m_us, ED_Start_mt, HD_Start ) + end if + + end if + if ( HD%y%WAMITMesh%Committed ) then ! meshes for floating + + ! Transfer HD load outputs to ED PlatformPtMesh input: + ! we're mapping loads, so we also need the sibling meshes' displacements: + HD_Start = Indx_u_HD_WAMIT_Start(HD%Input(1), y_FAST) + + call Linearize_Point_to_Point( HD%y%WAMITMesh, u_ED%PlatformPtMesh, MeshMapData%HD_W_P_2_ED_P, ErrStat2, ErrMsg2, HD%Input(1)%WAMITMesh, y_ED%PlatformPtMesh) !HD%Input(1)%WAMITMesh and y_ED%PlatformPtMesh contain the displaced positions for load calculations + call SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + + ! HD is source in the mapping, so we want M_{uSm} + if (allocated(MeshMapData%HD_W_P_2_ED_P%dM%m_us )) then + call SetBlockMatrix( dUdu, MeshMapData%HD_W_P_2_ED_P%dM%m_us, ED_Start_mt, HD_Start ) + end if + + end if + end if + + !.......... + ! dU^{ED}/du^{MAP} + !.......... + + if ( p_FAST%CompMooring == Module_MAP ) then + + ED_Start_mt = Indx_u_ED_Platform_Start(u_ED, y_FAST) & + + u_ED%PlatformPtMesh%NNodes * 3 ! 3 forces at each node (we're going to start at the moments) + + ! Transfer MAP loads to ED PlatformPtmesh input: + ! we're mapping loads, so we also need the sibling meshes' displacements: + + MAP_Start = y_FAST%Lin%Modules(MODULE_MAP)%Instance(1)%LinStartIndx(LIN_INPUT_COL) + + ! NOTE: Assumes at least one MAP Fairlead point + + CALL Linearize_Point_to_Point( MAPp%y%ptFairleadLoad, u_ED%PlatformPtMesh, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, MAPp%Input(1)%PtFairDisplacement, y_ED%PlatformPtMesh) !MAPp%Input(1)%ptFairleadLoad and y_ED%PlatformPtMesh contain the displaced positions for load calculations + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + + ! HD is source in the mapping, so we want M_{uSm} + if (allocated(MeshMapData%Mooring_P_2_ED_P%dM%m_us )) then + call SetBlockMatrix( dUdu, MeshMapData%Mooring_P_2_ED_P%dM%m_us, ED_Start_mt, MAP_Start ) + end if + + end if + + end if +END SUBROUTINE Linear_ED_InputSolve_du + +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine forms the dU^{SD}/du^{HD} and dU^{SD}/du^{SD} and dU^{SD}/du^{MAP} blocks (SD row) of dUdu. (i.e., how do changes in the HD and SD inputs affect the SD inputs?) +SUBROUTINE Linear_SD_InputSolve_du( p_FAST, y_FAST, u_SD, y_SD, y_ED, HD, MAPp, MeshMapData, dUdu, ErrStat, ErrMsg ) + + TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Glue-code simulation parameters + TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< Glue-code output parameters (for linearization) + TYPE(SD_InputType), INTENT(INOUT) :: u_SD !< SD Inputs at t + TYPE(SD_OutputType), INTENT(IN ) :: y_SD !< SubDyn outputs (need translation displacement on meshes for loads mapping) + TYPE(ED_OutputType), INTENT(IN ) :: y_ED !< ElastoDyn outputs + TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HD data at t + TYPE(MAP_Data), INTENT(INOUT) :: MAPp !< MAP data at t + TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules + REAL(R8Ki), INTENT(INOUT) :: dUdu(:,:) !< Jacobian matrix of which we are computing the dU^(SD)/du^(AD) block + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message + + ! local variables + INTEGER(IntKi) :: HD_Start + INTEGER(IntKi) :: MAP_Start + INTEGER(IntKi) :: SD_Start, SD_Start_td, SD_Start_tr + INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation + CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None + + CHARACTER(*), PARAMETER :: RoutineName = 'Linear_SD_InputSolve_du' + + + ! Initialize error status + + ErrStat = ErrID_None + ErrMsg = "" + + IF ( p_FAST%CompSub == Module_SD ) THEN ! see routine U_ED_SD_HD_BD_Orca_Residual() in SolveOption1 + + !.......... + ! dU^{SD}/du^{SD} + !.......... + + call Linearize_Point_to_Point( y_ED%PlatformPtMesh, u_SD%TPMesh, MeshMapData%ED_P_2_SD_TP, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + ! SD is destination in the mapping, so we want M_{tv_uD} and M_{ta_uD} + + SD_Start_td = y_FAST%Lin%Modules(MODULE_SD)%Instance(1)%LinStartIndx(LIN_INPUT_COL) + SD_Start_tr = SD_Start_td + u_SD%TPMesh%NNodes * 6 ! skip 2 fields (TranslationDisp and Orientation) with 3 components before translational velocity field + + ! translational velocity: + if (allocated(MeshMapData%ED_P_2_SD_TP%dM%tv_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_SD_TP%dM%tv_ud, SD_Start_tr, SD_Start_td ) + end if + + ! translational acceleration: + SD_Start_tr = SD_Start_tr + u_SD%TPMesh%NNodes * 6 ! skip 2 fields ( TranslationVel and RotationVel) + if (allocated(MeshMapData%ED_P_2_SD_TP%dM%ta_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_SD_TP%dM%ta_ud, SD_Start_tr, SD_Start_td ) + end if + + + !.......... - ! dU^{ED}/du^{HD} + ! dU^{SD}/du^{HD} !.......... + ! we're just going to assume u_SD%LMesh is committed + SD_Start = Indx_u_SD_LMesh_Start(u_SD, y_FAST) & + + u_SD%LMesh%NNodes * 3 ! 3 forces at each node (we're going to start at the moments) + if ( p_FAST%CompHydro == Module_HD ) then ! HydroDyn-{ElastoDyn or SubDyn} - ! we're just going to assume u_ED%PlatformPtMesh is committed + + ! Transfer HD load outputs to SD LMesh input: + if ( HD%y%Morison%Mesh%Committed ) then ! meshes for floating + + ! dU^{SD}/du^{HD} + + ! we're mapping loads, so we also need the sibling meshes' displacements: + HD_Start = Indx_u_HD_Morison_Start(HD%Input(1), y_FAST) + + call Linearize_Point_to_Point( HD%y%Morison%Mesh, u_SD%LMesh, MeshMapData%HD_M_P_2_SD_P, ErrStat2, ErrMsg2, HD%Input(1)%Morison%Mesh, y_SD%Y2Mesh) !HD%Input(1)%Mesh and y_ED%PlatformPtMesh contain the displaced positions for load calculations + call SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) - if ( HD%y%AllHdroOrigin%Committed ) then ! meshes for floating - ED_Start_mt = Indx_u_ED_Platform_Start(u_ED, y_FAST) & - + u_ED%PlatformPtMesh%NNodes * 3 ! 3 forces at each node (we're going to start at the moments) + ! HD is source in the mapping, so we want M_{uSm} + if (allocated(MeshMapData%HD_M_P_2_SD_P%dM%m_us )) then + call SetBlockMatrix( dUdu, MeshMapData%HD_M_P_2_SD_P%dM%m_us, SD_Start, HD_Start ) + end if + + + + end if + if ( HD%y%WAMITMesh%Committed ) then ! meshes for floating + ! Transfer HD load outputs to ED PlatformPtMesh input: ! we're mapping loads, so we also need the sibling meshes' displacements: - HD_Start = Indx_u_HD_PlatformRef_Start(HD%Input(1), y_FAST) + HD_Start = Indx_u_HD_WAMIT_Start(HD%Input(1), y_FAST) - call Linearize_Point_to_Point( HD%y%AllHdroOrigin, u_ED%PlatformPtMesh, MeshMapData%HD_W_P_2_ED_P, ErrStat2, ErrMsg2, HD%Input(1)%Mesh, y_ED%PlatformPtMesh) !HD%Input(1)%Mesh and y_ED%PlatformPtMesh contain the displaced positions for load calculations + call Linearize_Point_to_Point( HD%y%WAMITMesh, u_SD%LMesh, MeshMapData%HD_W_P_2_SD_P, ErrStat2, ErrMsg2, HD%Input(1)%WAMITMesh, y_SD%Y2Mesh) !HD%Input(1)%Mesh and y_ED%PlatformPtMesh contain the displaced positions for load calculations call SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) ! HD is source in the mapping, so we want M_{uSm} - if (allocated(MeshMapData%HD_W_P_2_ED_P%dM%m_us )) then - call SetBlockMatrix( dUdu, MeshMapData%HD_W_P_2_ED_P%dM%m_us, ED_Start_mt, HD_Start ) + if (allocated(MeshMapData%HD_W_P_2_SD_P%dM%m_us )) then + call SetBlockMatrix( dUdu, MeshMapData%HD_W_P_2_SD_P%dM%m_us, SD_Start, HD_Start ) end if + end if end if !.......... - ! dU^{ED}/du^{MAP} + ! dU^{SD}/du^{MAP} + !.......... + + if ( p_FAST%CompMooring == Module_MAP ) then + + ! Transfer MAP loads to ED PlatformPtmesh input: + ! we're mapping loads, so we also need the sibling meshes' displacements: + + MAP_Start = y_FAST%Lin%Modules(MODULE_MAP)%Instance(1)%LinStartIndx(LIN_INPUT_COL) + + ! NOTE: Assumes at least one MAP Fairlead point + + CALL Linearize_Point_to_Point( MAPp%y%ptFairleadLoad, u_SD%LMesh, MeshMapData%Mooring_P_2_SD_P, ErrStat2, ErrMsg2, MAPp%Input(1)%PtFairDisplacement, y_SD%Y2Mesh) !MAPp%Input(1)%ptFairleadLoad and y_SD%Y2Mesh contain the displaced positions for load calculations + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + + ! SD is source in the mapping, so we want M_{uSm} + if (allocated(MeshMapData%Mooring_P_2_SD_P%dM%m_us )) then + call SetBlockMatrix( dUdu, MeshMapData%Mooring_P_2_SD_P%dM%m_us, SD_Start, MAP_Start ) + end if + + end if + END IF +END SUBROUTINE Linear_SD_InputSolve_du + +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine forms the dU^{SD}/du^{HD} and dU^{SD}/du^{SD} blocks (SD row) of dUdu. (i.e., how do changes in the HD and SD inputs affect the SD inputs?) +SUBROUTINE Linear_SD_InputSolve_dy( p_FAST, y_FAST, u_SD, y_SD, y_ED, HD, MAPp, MeshMapData, dUdy, ErrStat, ErrMsg ) + + TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Glue-code simulation parameters + TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< Glue-code output parameters (for linearization) + TYPE(SD_InputType), INTENT(INOUT) :: u_SD !< SD Inputs at t + TYPE(SD_OutputType), INTENT(IN ) :: y_SD !< SubDyn outputs (need translation displacement on meshes for loads mapping) + TYPE(ED_OutputType), INTENT(IN ) :: y_ED !< ElastoDyn outputs + TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HD data at t + TYPE(MAP_Data), INTENT(INOUT) :: MAPp !< MAP data at t + TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules + REAL(R8Ki), INTENT(INOUT) :: dUdy(:,:) !< Jacobian matrix of which we are computing the dU^(SD)/dy^(SD) block + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message + + ! local variables + INTEGER(IntKi) :: SD_Start, SD_Out_Start, HD_Start, HD_Out_Start, ED_Out_Start, MAP_Out_Start + INTEGER(IntKi) :: MAP_Start + INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation + CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None + + CHARACTER(*), PARAMETER :: RoutineName = 'Linear_SD_InputSolve_du' + + + ! Initialize error status + + ErrStat = ErrID_None + ErrMsg = "" + if ( p_FAST%CompSub /= Module_SD ) return + + !.......... + ! dU^{SD}/dy^{ED} !.......... - ! LIN-TODO: Implement - if ( p_FAST%CompMooring == Module_MAP ) then - - ED_Start_mt = Indx_u_ED_Platform_Start(u_ED, y_FAST) & - + u_ED%PlatformPtMesh%NNodes * 3 ! 3 forces at each node (we're going to start at the moments) - - ! Transfer MAP loads to ED PlatformPtmesh input: - ! we're mapping loads, so we also need the sibling meshes' displacements: - - MAP_Start = y_FAST%Lin%Modules(MODULE_MAP)%Instance(1)%LinStartIndx(LIN_INPUT_COL) - - ! NOTE: Assumes at least one MAP Fairlead point + + !!! ! This linearization was done in forming dUdu (see Linear_SD_InputSolve_du()), so we don't need to re-calculate these matrices + !!! ! while forming dUdy, too. + !!!call Linearize_Point_to_Line2( y_ED%PlatformPtMesh, u_SD%TPMesh, MeshMapData%ED_P_2_SD_TP, ErrStat2, ErrMsg2 ) - CALL Linearize_Point_to_Point( MAPp%y%ptFairleadLoad, u_ED%PlatformPtMesh, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, MAPp%Input(1)%PtFairDisplacement, y_ED%PlatformPtMesh) !MAPp%Input(1)%ptFairleadLoad and y_ED%PlatformPtMesh contain the displaced positions for load calculations - CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) - - ! HD is source in the mapping, so we want M_{uSm} - if (allocated(MeshMapData%Mooring_P_2_ED_P%dM%m_us )) then - call SetBlockMatrix( dUdu, MeshMapData%Mooring_P_2_ED_P%dM%m_us, ED_Start_mt, MAP_Start ) + SD_Start = Indx_u_SD_TPMesh_Start(u_SD, y_FAST) ! start of u_SD%MTPMesh%TranslationDisp field + ED_Out_Start = Indx_y_ED_Platform_Start(y_ED, y_FAST) ! start of y_ED%PlatformPtMesh%TranslationDisp field + call Assemble_dUdy_Motions(y_ED%PlatformPtMesh, u_SD%TPMesh, MeshMapData%ED_P_2_SD_TP, SD_Start, ED_Out_Start, dUdy, .false.) + + !.......... + ! dU^{SD}/dy^{HD} + !.......... + ! HD + ! parts of dU^{SD}/dy^{HD} and dU^{SD}/dy^{SD}: + if ( p_FAST%CompHydro == Module_HD ) then ! HydroDyn-SubDyn + SD_Out_Start = Indx_y_SD_Y2Mesh_Start(y_SD, y_FAST) ! start of y_SD%Y2Mesh%TranslationDisp field + ! we're just going to assume u_SD%LMesh is committed + if ( HD%y%Morison%Mesh%Committed ) then ! meshes for floating + !!! ! This linearization was done in forming dUdu (see Linear_ED_InputSolve_du()), so we don't need to re-calculate these matrices + !!! ! while forming dUdy, too. + ! call Linearize_Point_to_Point( HD%y%Morison, u_ED%PlatformPtMesh, MeshMapData%HD_M_P_2_ED_P, ErrStat2, ErrMsg2, HD%Input(1)%Morison, y_ED%PlatformPtMesh) !HD%Input(1)%Morison and y_ED%PlatformPtMesh contain the displaced positions for load calculations + HD_Out_Start = Indx_y_HD_Morison_Start(HD%y, y_FAST) + SD_Start = Indx_u_SD_LMesh_Start(u_SD, y_FAST) ! start of u_SD%LMesh%Force field + call Assemble_dUdy_Loads(HD%y%Morison%Mesh, u_SD%LMesh, MeshMapData%HD_M_P_2_SD_P, SD_Start, HD_Out_Start, dUdy) + + ! SD translation displacement-to-SD moment transfer (dU^{SD}/dy^{SD}): + SD_Start = Indx_u_SD_LMesh_Start(u_SD, y_FAST) + u_SD%LMesh%NNodes*3 ! start of u_SD%LMesh%Moment field (skip the SD forces) + call SetBlockMatrix( dUdy, MeshMapData%HD_M_P_2_SD_P%dM%m_uD, SD_Start, SD_Out_Start ) +! maybe this should be SumBlockMatrix with future changes to linearized modules??? + end if + if ( HD%y%WAMITMesh%Committed ) then ! meshes for floating + !!! ! This linearization was done in forming dUdu (see Linear_ED_InputSolve_du()), so we don't need to re-calculate these matrices + !!! ! while forming dUdy, too. + ! call Linearize_Point_to_Point( HD%y%WAMITMesh, u_ED%PlatformPtMesh, MeshMapData%HD_W_P_2_ED_P, ErrStat2, ErrMsg2, HD%Input(1)%WAMITMesh, y_ED%PlatformPtMesh) !HD%Input(1)%WAMITMesh and y_ED%PlatformPtMesh contain the displaced positions for load calculations + HD_Out_Start = Indx_y_HD_WAMIT_Start(HD%y, y_FAST) + SD_Start = Indx_u_SD_LMesh_Start(u_SD, y_FAST) ! start of u_SD%LMesh%Force field + call Assemble_dUdy_Loads(HD%y%WAMITMesh, u_SD%LMesh, MeshMapData%HD_W_P_2_SD_P, SD_Start, HD_Out_Start, dUdy) + + ! SD translation displacement-to-SD moment transfer (dU^{SD}/dy^{SD}): + SD_Start = Indx_u_SD_LMesh_Start(u_SD, y_FAST) + u_SD%LMesh%NNodes*3 ! start of u_SD%LMesh%Moment field (skip the SD forces) + call SumBlockMatrix( dUdy, MeshMapData%HD_W_P_2_SD_P%dM%m_uD, SD_Start, SD_Out_Start ) +! maybe this should be SumBlockMatrix with future changes to linearized modules??? end if + end if + !.......... + ! dU^{SD}/dy^{MAP} + !.......... + if ( p_FAST%CompMooring == Module_MAP ) then + if ( MAPp%y%ptFairleadLoad%Committed ) then ! meshes for floating + !!! ! This linearization was done in forming dUdu (see Linear_SD_InputSolve_du()), so we don't need to re-calculate these matrices + !!! ! while forming dUdy, too. + ! CALL Linearize_Point_to_Point( MAPp%y%ptFairleadLoad, u_SD%LMesh, MeshMapData%Mooring_P_2_SD_P, ErrStat2, ErrMsg2, MAPp%Input(1)%PtFairDisplacement, y_SD%Y2Mesh) !MAPp%Input(1)%ptFairleadLoad and y_ED%Y2Mesh contain the displaced positions for load calculations + MAP_Out_Start = y_FAST%Lin%Modules(MODULE_MAP)%Instance(1)%LinStartIndx(LIN_OUTPUT_COL) + SD_Start = Indx_u_SD_LMesh_Start(u_SD, y_FAST) ! start of u_SD%LMesh%TranslationDisp field + call Assemble_dUdy_Loads(MAPp%y%ptFairLeadLoad, u_SD%LMesh, MeshMapData%Mooring_P_2_SD_P, SD_Start, MAP_Out_Start, dUdy) + + ! SD translation displacement-to-SD moment transfer (dU^{SD}/dy^{SD}): + SD_Start = Indx_u_SD_LMesh_Start(u_SD, y_FAST) + u_SD%LMesh%NNodes*3 ! start of u_ED%LMesh%Moment field (skip the SD forces) + SD_Out_Start = Indx_y_SD_Y2Mesh_Start(y_SD, y_FAST) ! start of y_SD%Y2Mesh%TranslationDisp field + call SumBlockMatrix( dUdy, MeshMapData%Mooring_P_2_SD_P%dM%m_uD, SD_Start, SD_Out_Start ) + end if end if - -END SUBROUTINE Linear_ED_InputSolve_du - +END SUBROUTINE Linear_SD_InputSolve_dy + !---------------------------------------------------------------------------------------------------------------------------------- !> This routine forms the dU^{BD}/du^{BD} and dU^{BD}/du^{AD} blocks (BD row) of dUdu. (i.e., how do changes in the AD and BD inputs @@ -2194,7 +2545,7 @@ END SUBROUTINE Linear_SrvD_InputSolve_dy !---------------------------------------------------------------------------------------------------------------------------------- !> This routine forms the dU^{ED}/dy^{SrvD}, dU^{ED}/dy^{ED}, dU^{ED}/dy^{BD}, dU^{ED}/dy^{AD}, dU^{ED}/dy^{HD}, and dU^{ED}/dy^{MAP} !! blocks of dUdy. (i.e., how do changes in the SrvD, ED, BD, AD, HD, and MAP outputs effect the ED inputs?) -SUBROUTINE Linear_ED_InputSolve_dy( p_FAST, y_FAST, u_ED, y_ED, y_AD, u_AD, BD, HD, MAPp, MeshMapData, dUdy, ErrStat, ErrMsg ) +SUBROUTINE Linear_ED_InputSolve_dy( p_FAST, y_FAST, u_ED, y_ED, y_AD, u_AD, BD, HD, SD, MAPp, MeshMapData, dUdy, ErrStat, ErrMsg ) TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< Glue-code simulation parameters TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< FAST output file data (for linearization) @@ -2204,6 +2555,7 @@ SUBROUTINE Linear_ED_InputSolve_dy( p_FAST, y_FAST, u_ED, y_ED, y_AD, u_AD, BD, TYPE(AD_InputType), INTENT(INOUT) :: u_AD !< AD inputs (for AD-ED load linerization) TYPE(BeamDyn_Data), INTENT(INOUT) :: BD !< BD data at t TYPE(HydroDyn_Data), INTENT(INOUT) :: HD !< HD data at t + TYPE(SubDyn_Data), INTENT(INOUT) :: SD !< SD data at t TYPE(MAP_Data), INTENT(INOUT) :: MAPp !< MAP data at t TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules @@ -2212,15 +2564,15 @@ SUBROUTINE Linear_ED_InputSolve_dy( p_FAST, y_FAST, u_ED, y_ED, y_AD, u_AD, BD, CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message ! local variables - !LIN-TODO: Add comments INTEGER(IntKi) :: i ! rows/columns INTEGER(IntKi) :: K ! Loops through blades INTEGER(IntKi) :: AD_Out_Start ! starting index of dUdy (column) where particular AD fields are located INTEGER(IntKi) :: BD_Out_Start ! starting index of dUdy (column) where particular BD fields are located INTEGER(IntKi) :: ED_Start ! starting index of dUdy (row) where ED input fields are located INTEGER(IntKi) :: ED_Out_Start ! starting index of dUdy (column) where ED output fields are located - INTEGER(IntKi) :: HD_Out_Start - INTEGER(IntKi) :: MAP_Out_Start + INTEGER(IntKi) :: HD_Out_Start ! starting index of dUdy (column) where HD output fields are located + INTEGER(IntKi) :: SD_Out_Start ! starting index of dUdy (column) where SD output fields are located + INTEGER(IntKi) :: MAP_Out_Start ! starting index of dUdy (column) where MAP output fields are located CHARACTER(*), PARAMETER :: RoutineName = 'Linear_ED_InputSolve_dy' @@ -2321,49 +2673,75 @@ SUBROUTINE Linear_ED_InputSolve_dy( p_FAST, y_FAST, u_ED, y_ED, y_AD, u_AD, BD, END IF - ! HD - ! parts of dU^{ED}/dy^{HD} and dU^{ED}/dy^{ED}: - if ( p_FAST%CompHydro == Module_HD ) then ! HydroDyn-{ElastoDyn or SubDyn} + if ( p_FAST%CompSub == Module_None ) then + ! HD + ! parts of dU^{ED}/dy^{HD} and dU^{ED}/dy^{ED}: + if ( p_FAST%CompHydro == Module_HD ) then ! HydroDyn-{ElastoDyn or SubDyn} + ED_Out_Start = Indx_y_ED_Platform_Start(y_ED, y_FAST) ! start of y_ED%PlatformPtMesh%TranslationDisp field + ! we're just going to assume u_ED%PlatformPtMesh is committed + if ( HD%y%Morison%Mesh%Committed ) then ! meshes for floating + !!! ! This linearization was done in forming dUdu (see Linear_ED_InputSolve_du()), so we don't need to re-calculate these matrices + !!! ! while forming dUdy, too. + ! call Linearize_Point_to_Point( HD%y%Morison, u_ED%PlatformPtMesh, MeshMapData%HD_M_P_2_ED_P, ErrStat2, ErrMsg2, HD%Input(1)%Morison, y_ED%PlatformPtMesh) !HD%Input(1)%Morison and y_ED%PlatformPtMesh contain the displaced positions for load calculations + HD_Out_Start = Indx_y_HD_Morison_Start(HD%y, y_FAST) + ED_Start = Indx_u_ED_Platform_Start(u_ED, y_FAST) ! start of u_ED%PlatformPtMesh%Force field + call Assemble_dUdy_Loads(HD%y%Morison%Mesh, u_ED%PlatformPtMesh, MeshMapData%HD_M_P_2_ED_P, ED_Start, HD_Out_Start, dUdy) + + ! ED translation displacement-to-ED moment transfer (dU^{ED}/dy^{ED}): + ED_Start = Indx_u_ED_Platform_Start(u_ED, y_FAST) + u_ED%PlatformPtMesh%NNodes*3 ! start of u_ED%PlatformPtMesh%Moment field (skip the ED forces) + call SumBlockMatrix( dUdy, MeshMapData%HD_M_P_2_ED_P%dM%m_uD, ED_Start, ED_Out_Start ) + + end if + if ( HD%y%WAMITMesh%Committed ) then ! meshes for floating + !!! ! This linearization was done in forming dUdu (see Linear_ED_InputSolve_du()), so we don't need to re-calculate these matrices + !!! ! while forming dUdy, too. + ! call Linearize_Point_to_Point( HD%y%WAMITMesh, u_ED%PlatformPtMesh, MeshMapData%HD_W_P_2_ED_P, ErrStat2, ErrMsg2, HD%Input(1)%WAMITMesh, y_ED%PlatformPtMesh) !HD%Input(1)%WAMITMesh and y_ED%PlatformPtMesh contain the displaced positions for load calculations + HD_Out_Start = Indx_y_HD_WAMIT_Start(HD%y, y_FAST) + ED_Start = Indx_u_ED_Platform_Start(u_ED, y_FAST) ! start of u_ED%PlatformPtMesh%Force field + call Assemble_dUdy_Loads(HD%y%WAMITMesh, u_ED%PlatformPtMesh, MeshMapData%HD_W_P_2_ED_P, ED_Start, HD_Out_Start, dUdy) + + ! ED translation displacement-to-ED moment transfer (dU^{ED}/dy^{ED}): + ED_Start = Indx_u_ED_Platform_Start(u_ED, y_FAST) + u_ED%PlatformPtMesh%NNodes*3 ! start of u_ED%PlatformPtMesh%Moment field (skip the ED forces) + call SumBlockMatrix( dUdy, MeshMapData%HD_W_P_2_ED_P%dM%m_uD, ED_Start, ED_Out_Start ) + + end if + - ! we're just going to assume u_ED%PlatformPtMesh is committed - - if ( HD%y%AllHdroOrigin%Committed ) then ! meshes for floating + end if + + ! MAP + ! parts of dU^{ED}/dy^{MAP} and dU^{ED}/dy^{ED}: + if ( p_FAST%CompMooring == Module_MAP ) then + if ( MAPp%y%ptFairleadLoad%Committed ) then ! meshes for floating !!! ! This linearization was done in forming dUdu (see Linear_ED_InputSolve_du()), so we don't need to re-calculate these matrices !!! ! while forming dUdy, too. - ! call Linearize_Point_to_Point( HD%y%AllHdroOrigin, u_ED%PlatformPtMesh, MeshMapData%HD_W_P_2_ED_P, ErrStat2, ErrMsg2, HD%Input(1)%Mesh, y_ED%PlatformPtMesh) !HD%Input(1)%Mesh and y_ED%PlatformPtMesh contain the displaced positions for load calculations - HD_Out_Start = Indx_y_HD_AllHdro_Start(HD%y, y_FAST) - ED_Start = Indx_u_ED_Platform_Start(u_ED, y_FAST) ! start of u_ED%PlatformPtMesh%Moment field - call Assemble_dUdy_Loads(HD%y%AllHdroOrigin, u_ED%PlatformPtMesh, MeshMapData%HD_W_P_2_ED_P, ED_Start, HD_Out_Start, dUdy) - - ! ED translation displacement-to-ED moment transfer (dU^{ED}/dy^{ED}): + ! CALL Linearize_Point_to_Point( MAPp%y%ptFairleadLoad, u_ED%PlatformPtMesh, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, MAPp%Input(1)%PtFairDisplacement, y_ED%PlatformPtMesh) !MAPp%Input(1)%ptFairleadLoad and y_ED%PlatformPtMesh contain the displaced positions for load calculations + MAP_Out_Start = y_FAST%Lin%Modules(MODULE_MAP)%Instance(1)%LinStartIndx(LIN_OUTPUT_COL) + ED_Start = Indx_u_ED_Platform_Start(u_ED, y_FAST) ! start of u_ED%PlatformPtMesh%TranslationDisp field + call Assemble_dUdy_Loads(MAPp%y%ptFairLeadLoad, u_ED%PlatformPtMesh, MeshMapData%Mooring_P_2_ED_P, ED_Start, MAP_Out_Start, dUdy) + + ! ED translation displacement-to-ED moment transfer (dU^{ED}/dy^{ED}): ED_Start = Indx_u_ED_Platform_Start(u_ED, y_FAST) + u_ED%PlatformPtMesh%NNodes*3 ! start of u_ED%PlatformPtMesh%Moment field (skip the ED forces) ED_Out_Start = Indx_y_ED_Platform_Start(y_ED, y_FAST) ! start of y_ED%PlatformPtMesh%TranslationDisp field - call SetBlockMatrix( dUdy, MeshMapData%HD_W_P_2_ED_P%dM%m_uD, ED_Start, ED_Out_Start ) -! maybe this should be SumBlockMatrix with future changes to linearized modules??? + call SumBlockMatrix( dUdy, MeshMapData%Mooring_P_2_ED_P%dM%m_uD, ED_Start, ED_Out_Start ) end if - - - end if - - ! MAP - ! parts of dU^{ED}/dy^{MAP} and dU^{ED}/dy^{ED}: - if ( p_FAST%CompMooring == Module_MAP ) then - if ( MAPp%y%ptFairleadLoad%Committed ) then ! meshes for floating - !!! ! This linearization was done in forming dUdu (see Linear_ED_InputSolve_du()), so we don't need to re-calculate these matrices - !!! ! while forming dUdy, too. - ! CALL Linearize_Point_to_Point( MAPp%y%ptFairleadLoad, u_ED%PlatformPtMesh, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, MAPp%Input(1)%PtFairDisplacement, y_ED%PlatformPtMesh) !MAPp%Input(1)%ptFairleadLoad and y_ED%PlatformPtMesh contain the displaced positions for load calculations - MAP_Out_Start = y_FAST%Lin%Modules(MODULE_MAP)%Instance(1)%LinStartIndx(LIN_OUTPUT_COL) - ED_Start = Indx_u_ED_Platform_Start(u_ED, y_FAST) ! start of u_ED%PlatformPtMesh%TranslationDisp field - call Assemble_dUdy_Loads(MAPp%y%ptFairLeadLoad, u_ED%PlatformPtMesh, MeshMapData%Mooring_P_2_ED_P, ED_Start, MAP_Out_Start, dUdy) - - ! ED translation displacement-to-ED moment transfer (dU^{ED}/dy^{ED}): - ED_Start = Indx_u_ED_Platform_Start(u_ED, y_FAST) + u_ED%PlatformPtMesh%NNodes*3 ! start of u_ED%PlatformPtMesh%Moment field (skip the ED forces) - ED_Out_Start = Indx_y_ED_Platform_Start(y_ED, y_FAST) ! start of y_ED%PlatformPtMesh%TranslationDisp field - call SumBlockMatrix( dUdy, MeshMapData%Mooring_P_2_ED_P%dM%m_uD, ED_Start, ED_Out_Start ) - end if + end if + else if ( p_FAST%CompSub == Module_SD ) then + ! SubDyn + ! parts of dU^{ED}/dy^{SD} and dU^{ED}/dy^{ED}: + !!! ! This linearization was done in forming dUdu (see Linear_ED_InputSolve_du()), so we don't need to re-calculate these matrices + !!! ! while forming dUdy, too. + ! CALL Linearize_Point_to_Point( SD%y%Y1Mesh, u_ED%PlatformPtMesh, MeshMapData%SD_TP_2_ED_P, ErrStat2, ErrMsg2, SD%Input(1)%TPMesh, y_ED%PlatformPtMesh) !SD%Input(1)%TPMesh and y_ED%PlatformPtMesh contain the displaced positions for load calculations + SD_Out_Start = y_FAST%Lin%Modules(MODULE_SD)%Instance(1)%LinStartIndx(LIN_OUTPUT_COL) + ED_Start = Indx_u_ED_Platform_Start(u_ED, y_FAST) ! start of u_ED%PlatformPtMesh%TranslationDisp field + call Assemble_dUdy_Loads(SD%y%Y1Mesh, u_ED%PlatformPtMesh, MeshMapData%SD_TP_2_ED_P, ED_Start, SD_Out_Start, dUdy) + + ! ED translation displacement-to-ED moment transfer (dU^{ED}/dy^{ED}): + ED_Start = Indx_u_ED_Platform_Start(u_ED, y_FAST) + u_ED%PlatformPtMesh%NNodes*3 ! start of u_ED%PlatformPtMesh%Moment field (skip the ED forces) + ED_Out_Start = Indx_y_ED_Platform_Start(y_ED, y_FAST) ! start of y_ED%PlatformPtMesh%TranslationDisp field + call SetBlockMatrix( dUdy, MeshMapData%SD_TP_2_ED_P%dM%m_uD, ED_Start, ED_Out_Start ) end if - END SUBROUTINE Linear_ED_InputSolve_dy !---------------------------------------------------------------------------------------------------------------------------------- !> This routine forms the dU^{BD}/dy^{ED}, dU^{BD}/dy^{BD}, and dU^{BD}/dy^{AD} blocks of dUdy. (i.e., how do @@ -2657,13 +3035,14 @@ END SUBROUTINE Linear_AD_InputSolve_NoIfW_dy !---------------------------------------------------------------------------------------------------------------------------------- !> This routine forms the dU^{HD}/du^{HD} blocks of dUdu. -SUBROUTINE Linear_HD_InputSolve_du( p_FAST, y_FAST, u_HD, y_ED, MeshMapData, dUdu, ErrStat, ErrMsg ) +SUBROUTINE Linear_HD_InputSolve_du( p_FAST, y_FAST, u_HD, y_ED, y_SD, MeshMapData, dUdu, ErrStat, ErrMsg ) ! Passed variables TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< FAST parameter data TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< FAST output file data (for linearization) TYPE(HydroDyn_InputType), INTENT(INOUT) :: u_HD !< The inputs to HydroDyn - TYPE(ED_OutputType), INTENT(IN) :: y_ED !< The outputs from the structural dynamics module + TYPE(ED_OutputType), INTENT(IN) :: y_ED !< The outputs from the ElastoDyn structural dynamics module + TYPE(SD_OutputType), INTENT(IN) :: y_SD !< The outputs from the SubDyn structural dynamics module TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules REAL(R8Ki), INTENT(INOUT) :: dUdu(:,:) !< Jacobian matrix of which we are computing the dU^{HD}/du^{HD} block @@ -2682,95 +3061,149 @@ SUBROUTINE Linear_HD_InputSolve_du( p_FAST, y_FAST, u_HD, y_ED, MeshMapData, dUd ErrStat = ErrID_None ErrMsg = "" - ! note that we assume this block matrix has been initialized to the identity matrix before calling this routine - ! We need to make six calls to SetBlockMatrix for the different output to input mappings - ! 1) Row 3, Col 1 - ! 2) Row 5, Col 1 - ! 3) Row 9, Col 7 - ! 4) Row 11, Col 7 - ! 5) Row 15, Col 13 - ! 6) Row 17, Col 13 ! look at how the translational displacement gets transfered to the translational velocity and translational acceleration: !------------------------------------------------------------------------------------------------- ! Set the inputs from ElastoDyn: !------------------------------------------------------------------------------------------------- - !.......... + !.......... ! dU^{HD}/du^{HD} ! note that the 1s on the diagonal have already been set, so we will fill in the off diagonal terms. !.......... if ( p_FAST%CompHydro == Module_HD ) then ! HydroDyn-{ElastoDyn or SubDyn} - + !=================================================== - ! y_ED%PlatformPtMesh and u_HD%Morison%DistribMesh - !=================================================== - - ! Transfer ED motions to HD motion input (HD inputs depend on previously calculated HD inputs from ED): - - call Linearize_Point_to_Line2( y_ED%PlatformPtMesh, u_HD%Morison%DistribMesh, MeshMapData%ED_P_2_HD_M_L, ErrStat2, ErrMsg2 ) + ! y_ED%PlatformPtMesh and u_HD%PRPMesh ! this is always done with ED, even if using SD + !=================================================== + + ! Transfer ED motions to HD motion input (HD inputs depend on previously calculated HD inputs from ED): + if ( u_HD%PRPMesh%Committed ) then + call Linearize_Point_to_Point( y_ED%PlatformPtMesh, u_HD%PRPMesh, MeshMapData%ED_P_2_HD_PRP_P, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - + ! HD is destination in the mapping, so we want M_{tv_uD} and M_{ta_uD} - HD_Start_td = y_FAST%Lin%Modules(MODULE_HD)%Instance(1)%LinStartIndx(LIN_INPUT_COL) - HD_Start_tr = HD_Start_td + u_HD%Morison%DistribMesh%NNodes * 6 ! skip 2 fields (TranslationDisp and Orientation) with 3 components before translational velocity field - + HD_Start_td = Indx_u_HD_PRP_Start(u_HD, y_FAST) + HD_Start_tr = HD_Start_td + u_HD%PRPMesh%NNodes * 6 ! skip 2 fields (TranslationDisp and Orientation) with 3 components before translational velocity field + ! translational velocity: - if (allocated(MeshMapData%ED_P_2_HD_M_L%dM%tv_uD )) then - call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_HD_M_L%dM%tv_ud, HD_Start_tr, HD_Start_td ) + if (allocated(MeshMapData%ED_P_2_HD_PRP_P%dM%tv_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_HD_PRP_P%dM%tv_ud, HD_Start_tr, HD_Start_td ) end if - + ! translational acceleration: - HD_Start_tr = HD_Start_tr + u_HD%Morison%DistribMesh%NNodes * 6 ! skip 2 fields ( TranslationVel and RotationVel) - if (allocated(MeshMapData%ED_P_2_HD_M_L%dM%ta_uD )) then - call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_HD_M_L%dM%ta_ud, HD_Start_tr, HD_Start_td ) + HD_Start_tr = HD_Start_tr + u_HD%PRPMesh%NNodes * 6 ! skip 2 fields ( TranslationVel and RotationVel) + if (allocated(MeshMapData%ED_P_2_HD_PRP_P%dM%ta_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_HD_PRP_P%dM%ta_ud, HD_Start_tr, HD_Start_td ) end if - + end if + + if ( p_FAST%CompSub == Module_None ) then + + !=================================================== + ! y_ED%PlatformPtMesh and u_HD%Morison%Mesh + !=================================================== + + ! Transfer ED motions to HD motion input (HD inputs depend on previously calculated HD inputs from ED): + if ( u_HD%Morison%Mesh%Committed ) then + call Linearize_Point_to_Point( y_ED%PlatformPtMesh, u_HD%Morison%Mesh, MeshMapData%ED_P_2_HD_M_P, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + ! HD is destination in the mapping, so we want M_{tv_uD} and M_{ta_uD} + + HD_Start_td = Indx_u_HD_Morison_Start(u_HD, y_FAST) + HD_Start_tr = HD_Start_td + u_HD%Morison%Mesh%NNodes * 6 ! skip 2 fields (TranslationDisp and Orientation) with 3 components before translational velocity field + + ! translational velocity: + if (allocated(MeshMapData%ED_P_2_HD_M_P%dM%tv_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_HD_M_P%dM%tv_ud, HD_Start_tr, HD_Start_td ) + end if + + ! translational acceleration: + HD_Start_tr = HD_Start_tr + u_HD%Morison%Mesh%NNodes * 6 ! skip 2 fields ( TranslationVel and RotationVel) + if (allocated(MeshMapData%ED_P_2_HD_M_P%dM%ta_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_HD_M_P%dM%ta_ud, HD_Start_tr, HD_Start_td ) + end if + end if + !=================================================== - ! y_ED%PlatformPtMesh and u_HD%Morison%LumpedMesh - !=================================================== - - call Linearize_Point_to_Point( y_ED%PlatformPtMesh, u_HD%Morison%LumpedMesh, MeshMapData%ED_P_2_HD_M_P, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + ! y_ED%PlatformPtMesh and u_HD%WAMITMesh + !=================================================== + if ( u_HD%WAMITMesh%Committed ) then - ! HD is destination in the mapping, so we want M_{tv_uD} and M_{ta_uD} - HD_Start_td = HD_Start_tr + u_HD%Morison%DistribMesh%NNodes * 6 ! skip 1 field ( TranslationAcc and RotationAcc) - HD_Start_tr = HD_Start_td + u_HD%Morison%LumpedMesh%NNodes * 6 ! skip 2 fields (TranslationDisp and Orientation) with 3 components before translational velocity field - ! translational velocity: - if (allocated(MeshMapData%ED_P_2_HD_M_P%dM%tv_uD )) then - call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_HD_M_P%dM%tv_ud, HD_Start_tr, HD_Start_td ) - end if + call Linearize_Point_to_Point( y_ED%PlatformPtMesh, u_HD%WAMITMesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + HD_Start_td = Indx_u_HD_WAMIT_Start(u_HD, y_FAST) + HD_Start_tr = HD_Start_td + u_HD%WAMITMesh%NNodes * 6 ! skip 2 fields (TranslationDisp and Orientation) with 3 components before translational velocity field + ! translational velocity: + if (allocated(MeshMapData%ED_P_2_HD_W_P%dM%tv_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_HD_W_P%dM%tv_ud, HD_Start_tr, HD_Start_td ) + end if - ! translational acceleration: - HD_Start_tr = HD_Start_tr + u_HD%Morison%LumpedMesh%NNodes * 6 ! skip 2 fields ( TranslationVel and RotationVel) + ! translational acceleration: + HD_Start_tr = HD_Start_tr + u_HD%WAMITMesh%NNodes * 6 ! skip 2 fields ( TranslationVel and RotationVel) - if (allocated(MeshMapData%ED_P_2_HD_M_P%dM%ta_uD )) then - call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_HD_M_P%dM%ta_ud, HD_Start_tr, HD_Start_td ) + if (allocated(MeshMapData%ED_P_2_HD_W_P%dM%ta_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_HD_W_P%dM%ta_ud, HD_Start_tr, HD_Start_td ) + end if + end if + + + else if ( p_FAST%CompSub == Module_SD ) then + + + !=================================================== + ! y_SD%Y2Mesh and u_HD%Morison%Mesh + !=================================================== + if ( u_HD%Morison%Mesh%Committed ) then + ! Transfer ED motions to HD motion input (HD inputs depend on previously calculated HD inputs from ED): + + call Linearize_Point_to_Point( y_SD%Y2Mesh, u_HD%Morison%Mesh, MeshMapData%SD_P_2_HD_M_P, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + ! HD is destination in the mapping, so we want M_{tv_uD} and M_{ta_uD} + + HD_Start_td = Indx_u_HD_Morison_Start(u_HD, y_FAST) + HD_Start_tr = HD_Start_td + u_HD%Morison%Mesh%NNodes * 6 ! skip 2 fields (TranslationDisp and Orientation) with 3 components before translational velocity field + + ! translational velocity: + if (allocated(MeshMapData%SD_P_2_HD_M_P%dM%tv_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%SD_P_2_HD_M_P%dM%tv_ud, HD_Start_tr, HD_Start_td ) + end if + + ! translational acceleration: + HD_Start_tr = HD_Start_tr + u_HD%Morison%Mesh%NNodes * 6 ! skip 2 fields ( TranslationVel and RotationVel) + if (allocated(MeshMapData%SD_P_2_HD_M_P%dM%ta_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%SD_P_2_HD_M_P%dM%ta_ud, HD_Start_tr, HD_Start_td ) + end if end if - + !=================================================== - ! y_ED%PlatformPtMesh and u_HD%Mesh + ! y_SD%Y2Mesh and u_HD%WAMITMesh !=================================================== + if ( u_HD%WAMITMesh%Committed ) then + call Linearize_Point_to_Point( y_SD%Y2Mesh, u_HD%WAMITMesh, MeshMapData%SD_P_2_HD_W_P, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call Linearize_Point_to_Point( y_ED%PlatformPtMesh, u_HD%Mesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - HD_Start_td = HD_Start_tr + u_HD%Morison%LumpedMesh%NNodes * 6 ! skip 2 field ( TranslationalAcc and RotationAcc) - HD_Start_tr = HD_Start_td + u_HD%Mesh%NNodes * 6 ! skip 2 fields (TranslationDisp and Orientation) with 3 components before translational velocity field - ! translational velocity: - if (allocated(MeshMapData%ED_P_2_HD_W_P%dM%tv_uD )) then - call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_HD_W_P%dM%tv_ud, HD_Start_tr, HD_Start_td ) - end if + HD_Start_td = Indx_u_HD_WAMIT_Start(u_HD, y_FAST) + HD_Start_tr = HD_Start_td + u_HD%WAMITMesh%NNodes * 6 ! skip 2 fields (TranslationDisp and Orientation) with 3 components before translational velocity field + ! translational velocity: + if (allocated(MeshMapData%SD_P_2_HD_W_P%dM%tv_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%SD_P_2_HD_W_P%dM%tv_ud, HD_Start_tr, HD_Start_td ) + end if - ! translational acceleration: - HD_Start_tr = HD_Start_tr + u_HD%Mesh%NNodes * 6 ! skip 2 fields ( TranslationVel and RotationVel) + ! translational acceleration: + HD_Start_tr = HD_Start_tr + u_HD%WAMITMesh%NNodes * 6 ! skip 2 fields ( TranslationVel and RotationVel) - if (allocated(MeshMapData%ED_P_2_HD_W_P%dM%ta_uD )) then - call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_HD_W_P%dM%ta_ud, HD_Start_tr, HD_Start_td ) + if (allocated(MeshMapData%SD_P_2_HD_W_P%dM%ta_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_HD_W_P%dM%ta_ud, HD_Start_tr, HD_Start_td ) + end if end if - + + end if + end if @@ -2778,13 +3211,14 @@ END SUBROUTINE Linear_HD_InputSolve_du !---------------------------------------------------------------------------------------------------------------------------------- !> This routine forms the dU^{HD}/dy^{ED} block of dUdy. (i.e., how do changes in the ED outputs affect !! the HD inputs?) -SUBROUTINE Linear_HD_InputSolve_dy( p_FAST, y_FAST, u_HD, y_ED, MeshMapData, dUdy, ErrStat, ErrMsg ) +SUBROUTINE Linear_HD_InputSolve_dy( p_FAST, y_FAST, u_HD, y_ED, y_SD, MeshMapData, dUdy, ErrStat, ErrMsg ) ! Passed variables TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< FAST parameter data TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< FAST output file data (for linearization) TYPE(HydroDyn_InputType), INTENT(INOUT) :: u_HD !< The inputs to HydroDyn - TYPE(ED_OutputType), INTENT(IN) :: y_ED !< The outputs from the structural dynamics module + TYPE(ED_OutputType), INTENT(IN) :: y_ED !< The outputs from the ElastoDyn structural dynamics module + TYPE(SD_OutputType), INTENT(IN) :: y_SD !< The outputs from the SubDyn structural dynamics module TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules REAL(R8Ki), INTENT(INOUT) :: dUdy(:,:) !< Jacobian matrix of which we are computing the dU^{HD}/dy^{ED} block @@ -2795,72 +3229,93 @@ SUBROUTINE Linear_HD_InputSolve_dy( p_FAST, y_FAST, u_HD, y_ED, MeshMapData, dUd INTEGER(IntKi) :: HD_Start ! starting index of dUdy (column) where particular HD fields are located INTEGER(IntKi) :: ED_Out_Start! starting index of dUdy (row) where particular ED fields are located + INTEGER(IntKi) :: SD_Out_Start! starting index of dUdy (row) where particular SD fields are located CHARACTER(*), PARAMETER :: RoutineName = 'Linear_HD_InputSolve_dy' ErrStat = ErrID_None ErrMsg = "" - - - !................................... - ! Distributed Morison Mesh - !................................... - IF (u_HD%Morison%DistribMesh%Committed) THEN + + ! Add ED Platform mesh to HD PRP Mesh + ! use Indx_u_HD_PRP_Start + HD_Start = Indx_u_HD_PRP_Start(u_HD, y_FAST) ! start of u_HD%Morison%Mesh%TranslationDisp field + ED_Out_Start = Indx_y_ED_Platform_Start(y_ED, y_FAST) ! start of y_ED%PlatformPtMesh%TranslationDisp field + call Assemble_dUdy_Motions(y_ED%PlatformPtMesh, u_HD%PRPMesh, MeshMapData%ED_P_2_HD_PRP_P, HD_Start, ED_Out_Start, dUdy, .false.) + + + if ( p_FAST%CompSub == Module_None ) then + ! dU^{HD}/dy^{ED} + !................................... + ! Morison Mesh + !................................... + IF (u_HD%Morison%Mesh%Committed) THEN - !!! ! This linearization was done in forming dUdu (see Linear_HD_InputSolve_du()), so we don't need to re-calculate these matrices - !!! ! while forming dUdy, too. - !!!call Linearize_Point_to_Line2( y_ED%PlatformPtMesh, u_HD%Morison%DistribMesh, MeshMapData%ED_P_2_HD_M_L, ErrStat2, ErrMsg2 ) + !!! ! This linearization was done in forming dUdu (see Linear_HD_InputSolve_du()), so we don't need to re-calculate these matrices + !!! ! while forming dUdy, too. + !!!call Linearize_Point_to_Line2( y_ED%PlatformPtMesh, u_HD%Morison%Mesh, MeshMapData%ED_P_2_HD_M_P, ErrStat2, ErrMsg2 ) - HD_Start = Indx_u_HD_Distrib_Start(u_HD, y_FAST) ! start of u_HD%Morison%DistribMesh%TranslationDisp field - ED_Out_Start = Indx_y_ED_Platform_Start(y_ED, y_FAST) ! start of y_ED%PlatformPtMesh%TranslationDisp field - call Assemble_dUdy_Motions(y_ED%PlatformPtMesh, u_HD%Morison%DistribMesh, MeshMapData%ED_P_2_HD_M_L, HD_Start, ED_Out_Start, dUdy) - END IF - - !................................... - ! Lumped Morison Mesh - !................................... - IF (u_HD%Morison%LumpedMesh%Committed) THEN + HD_Start = Indx_u_HD_Morison_Start(u_HD, y_FAST) ! start of u_HD%Morison%Mesh%TranslationDisp field + call Assemble_dUdy_Motions(y_ED%PlatformPtMesh, u_HD%Morison%Mesh, MeshMapData%ED_P_2_HD_M_P, HD_Start, ED_Out_Start, dUdy, .false.) + END IF + + !................................... + ! Lumped Platform Reference Pt Mesh + !................................... + IF (u_HD%WAMITMesh%Committed) THEN - !!! ! This linearization was done in forming dUdu (see Linear_HD_InputSolve_du()), so we don't need to re-calculate these matrices - !!! ! while forming dUdy, too. - !!!call Linearize_Point_to_Point( y_ED%PlatformPtMesh, u_HD%Morison%LumpedMesh, MeshMapData%ED_P_2_HD_M_P, ErrStat2, ErrMsg2 ) + !!! ! This linearization was done in forming dUdu (see Linear_HD_InputSolve_du()), so we don't need to re-calculate these matrices + !!! ! while forming dUdy, too. + !!!call Linearize_Point_to_Point( y_ED%PlatformPtMesh, u_HD%Mesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2 ) - HD_Start = Indx_u_HD_Lumped_Start(u_HD, y_FAST) ! start of u_HD%Morison%LumpedMesh%TranslationDisp field + HD_Start = Indx_u_HD_WAMIT_Start(u_HD, y_FAST) ! start of u_HD%Mesh%TranslationDisp field + call Assemble_dUdy_Motions(y_ED%PlatformPtMesh, u_HD%WAMITMesh, MeshMapData%ED_P_2_HD_W_P, HD_Start, ED_Out_Start, dUdy, .false.) + END IF - ED_Out_Start = Indx_y_ED_Platform_Start(y_ED, y_FAST) ! start of y_ED%PlatformPtMesh%TranslationDisp field - call Assemble_dUdy_Motions(y_ED%PlatformPtMesh, u_HD%Morison%LumpedMesh, MeshMapData%ED_P_2_HD_M_P, HD_Start, ED_Out_Start, dUdy) - END IF - - !................................... - ! Lumped Platform Reference Pt Mesh - !................................... - IF (u_HD%Mesh%Committed) THEN + else if ( p_FAST%CompSub == Module_SD ) then + ! dU^{HD}/dy^{SD} + SD_Out_Start = Indx_y_SD_Y2Mesh_Start(y_SD, y_FAST) ! start of y_SD%Y2Mesh%TranslationDisp field + !................................... + ! Morison Mesh + !................................... + IF (u_HD%Morison%Mesh%Committed) THEN - !!! ! This linearization was done in forming dUdu (see Linear_HD_InputSolve_du()), so we don't need to re-calculate these matrices - !!! ! while forming dUdy, too. - !!!call Linearize_Point_to_Point( y_ED%PlatformPtMesh, u_HD%Mesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2 ) - - HD_Start = Indx_u_HD_PlatformRef_Start(u_HD, y_FAST) ! start of u_HD%Mesh%TranslationDisp field + !!! ! This linearization was done in forming dUdu (see Linear_HD_InputSolve_du()), so we don't need to re-calculate these matrices + !!! ! while forming dUdy, too. + !!!call Linearize_Point_to_Line2( y_SD%Y2Mesh, u_HD%Morison%Mesh, MeshMapData%SD_P_2_HD_M_P, ErrStat2, ErrMsg2 ) - ED_Out_Start = Indx_y_ED_Platform_Start(y_ED, y_FAST) ! start of y_ED%PlatformPtMesh%TranslationDisp field - call Assemble_dUdy_Motions(y_ED%PlatformPtMesh, u_HD%Mesh, MeshMapData%ED_P_2_HD_W_P, HD_Start, ED_Out_Start, dUdy) - - - END IF + HD_Start = Indx_u_HD_Morison_Start(u_HD, y_FAST) ! start of u_HD%Morison%Mesh%TranslationDisp field + call Assemble_dUdy_Motions(y_SD%Y2Mesh, u_HD%Morison%Mesh, MeshMapData%SD_P_2_HD_M_P, HD_Start, SD_Out_Start, dUdy, .false.) + END IF + !................................... + ! Lumped Platform Reference Pt Mesh + !................................... + IF (u_HD%WAMITMesh%Committed) THEN + + !!! ! This linearization was done in forming dUdu (see Linear_HD_InputSolve_du()), so we don't need to re-calculate these matrices + !!! ! while forming dUdy, too. + !!!call Linearize_Point_to_Point( y_SD%Y2Mesh, u_HD%Mesh, MeshMapData%SD_P_2_HD_W_P, ErrStat2, ErrMsg2 ) + + HD_Start = Indx_u_HD_WAMIT_Start(u_HD, y_FAST) ! start of u_HD%Mesh%TranslationDisp field + call Assemble_dUdy_Motions(y_SD%Y2Mesh, u_HD%WAMITMesh, MeshMapData%SD_P_2_HD_W_P, HD_Start, SD_Out_Start, dUdy, .false.) + END IF + + end if + END SUBROUTINE Linear_HD_InputSolve_dy !---------------------------------------------------------------------------------------------------------------------------------- !> This routine forms the dU^{MAP}/dy^{ED} block of dUdy. (i.e., how do changes in the ED outputs affect !! the MAP inputs?) -SUBROUTINE Linear_MAP_InputSolve_dy( p_FAST, y_FAST, u_MAP, y_ED, MeshMapData, dUdy, ErrStat, ErrMsg ) +SUBROUTINE Linear_MAP_InputSolve_dy( p_FAST, y_FAST, u_MAP, y_ED, y_SD, MeshMapData, dUdy, ErrStat, ErrMsg ) ! Passed variables TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< FAST parameter data TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< FAST output file data (for linearization) TYPE(MAP_InputType), INTENT(INOUT) :: u_MAP !< The inputs to MAP - TYPE(ED_OutputType), INTENT(IN) :: y_ED !< The outputs from the structural dynamics module + TYPE(ED_OutputType), INTENT(IN) :: y_ED !< The outputs from the ElastoDyn structural dynamics module + TYPE(SD_OutputType), INTENT(IN) :: y_SD !< The outputs from the SubDyn structural dynamics module TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules REAL(R8Ki), INTENT(INOUT) :: dUdy(:,:) !< Jacobian matrix of which we are computing the dU^{MAP}/dy^{ED} block @@ -2871,6 +3326,7 @@ SUBROUTINE Linear_MAP_InputSolve_dy( p_FAST, y_FAST, u_MAP, y_ED, MeshMapData, d INTEGER(IntKi) :: MAP_Start ! starting index of dUdy (column) where particular MAP fields are located INTEGER(IntKi) :: ED_Out_Start! starting index of dUdy (row) where particular ED fields are located + INTEGER(IntKi) :: SD_Out_Start! starting index of dUdy (row) where particular SD fields are located INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'Linear_MAP_InputSolve_dy' @@ -2878,100 +3334,29 @@ SUBROUTINE Linear_MAP_InputSolve_dy( p_FAST, y_FAST, u_MAP, y_ED, MeshMapData, d ErrStat = ErrID_None ErrMsg = "" - - - !................................... - ! FairLead Mesh - !................................... - IF (u_MAP%PtFairDisplacement%Committed) THEN + IF (u_MAP%PtFairDisplacement%Committed) THEN + !................................... + ! FairLead Mesh + !................................... + MAP_Start = y_FAST%Lin%Modules(MODULE_MAP)%Instance(1)%LinStartIndx(LIN_INPUT_COL) - ED_Out_Start = Indx_y_ED_Platform_Start(y_ED, y_FAST) ! start of y_ED%PlatformPtMesh%TranslationDisp field - - call Linearize_Point_to_Point( y_ED%PlatformPtMesh, u_MAP%PtFairDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) - call Assemble_dUdy_Motions(y_ED%PlatformPtMesh, u_MAP%PtFairDisplacement, MeshMapData%ED_P_2_Mooring_P, MAP_Start, ED_Out_Start, dUdy, OnlyTranslationDisp=.true.) + if ( p_FAST%CompSub == Module_SD ) THEN + ! dU^{MAP}/dy^{SD} + SD_Out_Start = Indx_y_SD_Y2Mesh_Start(y_SD, y_FAST) ! start of y_SD%Y2Mesh%TranslationDisp field + call Linearize_Point_to_Point( y_SD%Y2Mesh, u_MAP%PtFairDisplacement, MeshMapData%SD_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + call Assemble_dUdy_Motions(y_SD%Y2Mesh , u_MAP%PtFairDisplacement, MeshMapData%SD_P_2_Mooring_P, MAP_Start, SD_Out_Start, dUdy, OnlyTranslationDisp=.true.) + + else if ( p_FAST%CompSub == Module_None ) THEN + ! dU^{MAP}/dy^{ED} + ED_Out_Start = Indx_y_ED_Platform_Start(y_ED, y_FAST) ! start of y_ED%PlatformPtMesh%TranslationDisp field + call Linearize_Point_to_Point( y_ED%PlatformPtMesh, u_MAP%PtFairDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + call Assemble_dUdy_Motions(y_ED%PlatformPtMesh, u_MAP%PtFairDisplacement, MeshMapData%ED_P_2_Mooring_P, MAP_Start, ED_Out_Start, dUdy, OnlyTranslationDisp=.true.) + end if END IF - -END SUBROUTINE Linear_MAP_InputSolve_dy - -! LIN-TODO: Clean up if not used. -!!---------------------------------------------------------------------------------------------------------------------------------- -!!> This routine forms the dU^{MAP}/dy^{ED} blocks of dUdu. -!SUBROUTINE Linear_MAP_InputSolve_du( p_FAST, y_FAST, u_MAP, y_ED, MeshMapData, dUdy, ErrStat, ErrMsg ) -! -! ! Passed variables -! TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< FAST parameter data -! TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< FAST output file data (for linearization) -! TYPE(HD_InputType), INTENT(INOUT) :: u_MAP !< The inputs to HydroDyn - -! TYPE(ED_OutputType), INTENT(IN) :: y_ED !< The outputs from the structural dynamics module -! TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules -! REAL(R8Ki), INTENT(INOUT) :: dUdy(:,:) !< Jacobian matrix of which we are computing the dU^{MAP}/dy^{ED} block -! -! INTEGER(IntKi) :: ErrStat !< Error status of the operation -! CHARACTER(*) :: ErrMsg !< Error message if ErrStat /= ErrID_None -! -! ! Local variables: -! -! INTEGER(IntKi) :: MAP_Start ! starting index of dUdy (column) where particular MAP fields are located -! INTEGER(IntKi) :: ED_Start ! starting index of dUdy (row) where particular ED fields are located -! INTEGER(IntKi) :: ErrStat2 -! CHARACTER(ErrMsgLen) :: ErrMsg2 -! CHARACTER(*), PARAMETER :: RoutineName = 'Linear_MAP_InputSolve_dy' -! -! -! ErrStat = ErrID_None -! ErrMsg = "" -! -! ! note that we assume this block matrix has been initialized to the identity matrix before calling this routine -! ! We need to make six calls to SetBlockMatrix for the different output to input mappings -! ! 1) Row 3, Col 1 -! ! 2) Row 4, Col 1 -! -! -! ! look at how the translational displacement gets transfered to the translational velocity and translational acceleration: -! !------------------------------------------------------------------------------------------------- -! ! Set the inputs from ElastoDyn: -! !------------------------------------------------------------------------------------------------- -! -! !.......... -! ! dU^{MAP}/dy^{ED} -! ! note that the 1s on the diagonal have already been set, so we will fill in the off diagonal terms. -! !.......... -! -! if ( p_FAST%CompMooring == Module_MAP ) then ! MAP- ElastoDyn -! -! !=================================================== -! ! y_ED%PlatformPtMesh and u_MAP%Morison%DistribMesh -! !=================================================== -! -! ! Transfer ED motions to HD motion input (HD inputs depend on previously calculated HD inputs from ED): -! -! call Linearize_Point_to_Line2( y_ED%PlatformPtMesh, u_MAP%Morison%DistribMesh, MeshMapData%ED_P_2_MAP_M_L, ErrStat2, ErrMsg2 ) -! call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) -! -! ! HD is destination in the mapping, so we want M_{tv_uD} and M_{ta_uD} -! -! HD_Start_td = y_FAST%Lin%Modules(MODULE_MAP)%Instance(1)%LinStartIndx(LIN_INPUT_COL) -! HD_Start_tr = HD_Start_td + u_MAP%Morison%DistribMesh%%NNodes * 6 ! skip 2 fields (TranslationDisp and Orientation) with 3 components before translational velocity field -! -! ! translational velocity: -! if (allocated(MeshMapData%ED_P_2_MAP_M_L%dM%tv_uD )) then -! call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_MAP_M_L%dM%tv_ud, HD_Start_tr, HD_Start_td ) -! end if -! -! ! translational acceleration: -! HD_Start_tr = HD_Start_tr + u_MAP%Morison%DistribMesh%%NNodes * 6 ! skip 2 fields ( TranslationVel and RotationVel) -! if (allocated(MeshMapData%ED_P_2_MAP_M_L%dM%ta_uD )) then -! call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_MAP_M_L%dM%ta_ud, HD_Start_tr, HD_Start_td ) -! end if -! -! end if -! -! -!END SUBROUTINE Linear_MAP_InputSolve_du +END SUBROUTINE Linear_MAP_InputSolve_dy !---------------------------------------------------------------------------------------------------------------------------------- @@ -3154,7 +3539,7 @@ SUBROUTINE Glue_StateMatrices( p_FAST, y_FAST, dUdu, dUdy, ErrStat, ErrMsg ) ErrStat = ErrID_None ErrMsg = "" - + !LIN-TODO: Update doc string comments below for HD, MAP, SD !..................................... ! allocate the glue-code state matrices; after this call they will contain the state matrices from the @@ -3843,67 +4228,78 @@ FUNCTION Indx_u_AD_BladeInflow_Start(u_AD, y_FAST) RESULT(AD_Start) END FUNCTION Indx_u_AD_BladeInflow_Start !---------------------------------------------------------------------------------------------------------------------------------- + +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine returns the starting index for the u_SD%TPMesh mesh in the FAST linearization inputs. +FUNCTION Indx_u_SD_TPMesh_Start(u_SD, y_FAST) RESULT(SD_Start) + TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< FAST output file data (for linearization) + TYPE(SD_InputType), INTENT(IN ) :: u_SD !< SD Inputs at t + + INTEGER :: SD_Start !< starting index of this mesh in SubDyn inputs + + SD_Start = y_FAST%Lin%Modules(Module_SD)%Instance(1)%LinStartIndx(LIN_INPUT_COL) + +END FUNCTION Indx_u_SD_TPMesh_Start !---------------------------------------------------------------------------------------------------------------------------------- -!> This routine returns the starting index for the u_HD%Morison%DistribMesh mesh in the FAST linearization inputs. -FUNCTION Indx_u_HD_Distrib_Start(u_HD, y_FAST) RESULT(HD_Start) +!> This routine returns the starting index for the u_SD%TPMesh mesh in the FAST linearization inputs. +FUNCTION Indx_u_SD_LMesh_Start(u_SD, y_FAST) RESULT(SD_Start) TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< FAST output file data (for linearization) - TYPE(HydroDyn_InputType), INTENT(IN ) :: u_HD !< HD Inputs at t + TYPE(SD_InputType), INTENT(IN ) :: u_SD !< SD Inputs at t - INTEGER :: HD_Start !< starting index of this mesh in HydroDyn inputs + INTEGER :: SD_Start !< starting index of this mesh in SubDyn inputs - HD_Start = y_FAST%Lin%Modules(Module_HD)%Instance(1)%LinStartIndx(LIN_INPUT_COL) + SD_Start = Indx_u_SD_TPMesh_Start(u_SD, y_FAST) + u_SD%TPMesh%NNodes*18 ! 6 fields with 3 components -END FUNCTION Indx_u_HD_Distrib_Start +END FUNCTION Indx_u_SD_LMesh_Start !---------------------------------------------------------------------------------------------------------------------------------- -!> This routine returns the starting index for the u_HD%Morison%LumpedMesh mesh in the FAST linearization inputs. -FUNCTION Indx_u_HD_Lumped_Start(u_HD, y_FAST) RESULT(HD_Start) +!> This routine returns the starting index for the u_HD%Morison%Mesh mesh in the FAST linearization inputs. +FUNCTION Indx_u_HD_Morison_Start(u_HD, y_FAST) RESULT(HD_Start) TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< FAST output file data (for linearization) TYPE(HydroDyn_InputType), INTENT(IN ) :: u_HD !< HD Inputs at t INTEGER :: HD_Start !< starting index of this mesh in HydroDyn inputs - HD_Start = Indx_u_HD_Distrib_Start(u_HD, y_FAST) - if (u_HD%Morison%DistribMesh%committed) HD_Start = HD_Start + u_HD%Morison%DistribMesh%NNodes * 18 ! 6 fields (MASKID_TRANSLATIONDISP,MASKID_Orientation,MASKID_TRANSLATIONVel,MASKID_ROTATIONVel,MASKID_TRANSLATIONAcc,MASKID_ROTATIONAcc) with 3 components + HD_Start = y_FAST%Lin%Modules(Module_HD)%Instance(1)%LinStartIndx(LIN_INPUT_COL) -END FUNCTION Indx_u_HD_Lumped_Start +END FUNCTION Indx_u_HD_Morison_Start !---------------------------------------------------------------------------------------------------------------------------------- -!> This routine returns the starting index for the u_HD%Mesh mesh in the FAST linearization inputs. -FUNCTION Indx_u_HD_PlatformRef_Start(u_HD, y_FAST) RESULT(HD_Start) +!> This routine returns the starting index for the u_HD%WAMITMesh mesh in the FAST linearization inputs. +FUNCTION Indx_u_HD_WAMIT_Start(u_HD, y_FAST) RESULT(HD_Start) TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< FAST output file data (for linearization) TYPE(HydroDyn_InputType), INTENT(IN ) :: u_HD !< HD Inputs at t INTEGER :: HD_Start !< starting index of this mesh in HydroDyn inputs - HD_Start = Indx_u_HD_Lumped_Start(u_HD, y_FAST) - if (u_HD%Morison%LumpedMesh%committed) HD_Start = HD_Start + u_HD%Morison%LumpedMesh%NNodes * 18 ! 6 fields (MASKID_TRANSLATIONDISP,MASKID_Orientation,MASKID_TRANSLATIONVel,MASKID_ROTATIONVel,MASKID_TRANSLATIONAcc,MASKID_ROTATIONAcc) with 3 components + HD_Start = Indx_u_HD_Morison_Start(u_HD, y_FAST) + if (u_HD%Morison%Mesh%committed) HD_Start = HD_Start + u_HD%Morison%Mesh%NNodes * 18 ! 6 fields (MASKID_TRANSLATIONDISP,MASKID_Orientation,MASKID_TRANSLATIONVel,MASKID_ROTATIONVel,MASKID_TRANSLATIONAcc,MASKID_ROTATIONAcc) with 3 components - END FUNCTION Indx_u_HD_PlatformRef_Start +END FUNCTION Indx_u_HD_WAMIT_Start !---------------------------------------------------------------------------------------------------------------------------------- -!> This routine returns the starting index for the y_HD%Morison%DistribMesh mesh in the FAST linearization outputs. -FUNCTION Indx_y_HD_Distrib_Start(y_HD, y_FAST) RESULT(HD_Start) +!> This routine returns the starting index for the u_HD%PRPMesh mesh in the FAST linearization inputs. +FUNCTION Indx_u_HD_PRP_Start(u_HD, y_FAST) RESULT(HD_Start) TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< FAST output file data (for linearization) - TYPE(HydroDyn_OutputType), INTENT(IN ) :: y_HD !< HD Outputs at t + TYPE(HydroDyn_InputType), INTENT(IN ) :: u_HD !< HD Inputs at t - INTEGER :: HD_Start !< starting index of this mesh in HydroDyn Outputs + INTEGER :: HD_Start !< starting index of this mesh in HydroDyn inputs - HD_Start = y_FAST%Lin%Modules(Module_HD)%Instance(1)%LinStartIndx(LIN_OUTPUT_COL) + HD_Start = Indx_u_HD_WAMIT_Start(u_HD, y_FAST) + if (u_HD%WAMITMesh%committed) HD_Start = HD_Start + u_HD%WAMITMesh%NNodes * 18 ! 6 fields (MASKID_TRANSLATIONDISP,MASKID_Orientation,MASKID_TRANSLATIONVel,MASKID_ROTATIONVel,MASKID_TRANSLATIONAcc,MASKID_ROTATIONAcc) with 3 components -END FUNCTION Indx_y_HD_Distrib_Start + END FUNCTION Indx_u_HD_PRP_Start !---------------------------------------------------------------------------------------------------------------------------------- -!> This routine returns the starting index for the y_HD%Morison%LumpedMesh mesh in the FAST linearization outputs. -FUNCTION Indx_y_HD_Lumped_Start(y_HD, y_FAST) RESULT(HD_Start) +!> This routine returns the starting index for the y_HD%Morison%DistribMesh mesh in the FAST linearization outputs. +FUNCTION Indx_y_HD_Morison_Start(y_HD, y_FAST) RESULT(HD_Start) TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< FAST output file data (for linearization) TYPE(HydroDyn_OutputType), INTENT(IN ) :: y_HD !< HD Outputs at t INTEGER :: HD_Start !< starting index of this mesh in HydroDyn Outputs - HD_Start = Indx_y_HD_Distrib_Start(y_HD, y_FAST) - if (y_HD%Morison%DistribMesh%committed) HD_Start = HD_Start + y_HD%Morison%DistribMesh%NNodes * 6 ! 2 fields (MASKID_FORCE,MASKID_MOMENT) with 3 components + HD_Start = y_FAST%Lin%Modules(Module_HD)%Instance(1)%LinStartIndx(LIN_OUTPUT_COL) -END FUNCTION Indx_y_HD_Lumped_Start +END FUNCTION Indx_y_HD_Morison_Start !---------------------------------------------------------------------------------------------------------------------------------- !> This routine returns the starting index for the y_HD%Mesh mesh in the FAST linearization outputs. -FUNCTION Indx_y_HD_PlatformRef_Start(y_HD, y_FAST) RESULT(HD_Start) +FUNCTION Indx_y_HD_WAMIT_Start(y_HD, y_FAST) RESULT(HD_Start) TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< FAST output file data (for linearization) TYPE(HydroDyn_OutputType), INTENT(IN ) :: y_HD !< HD Outputs at t @@ -3911,25 +4307,29 @@ FUNCTION Indx_y_HD_PlatformRef_Start(y_HD, y_FAST) RESULT(HD_Start) !< starting index of this mesh in HydroDyn Outputs - HD_Start = Indx_y_HD_Lumped_Start(y_HD, y_FAST) - if (y_HD%Morison%LumpedMesh%committed) HD_Start = HD_Start + y_HD%Morison%LumpedMesh%NNodes * 6 ! 2 fields (MASKID_FORCE,MASKID_MOMENT) with 3 components + HD_Start = Indx_y_HD_Morison_Start(y_HD, y_FAST) + if (y_HD%Morison%Mesh%committed) HD_Start = HD_Start + y_HD%Morison%Mesh%NNodes * 6 ! 2 fields (MASKID_FORCE,MASKID_MOMENT) with 3 components - END FUNCTION Indx_y_HD_PlatformRef_Start + END FUNCTION Indx_y_HD_WAMIT_Start !---------------------------------------------------------------------------------------------------------------------------------- -!> This routine returns the starting index for the y_HD%AllHdroOrigin mesh in the FAST linearization outputs. -FUNCTION Indx_y_HD_AllHdro_Start(y_HD, y_FAST) RESULT(HD_Start) +!> This routine returns the starting index for the y_SD%Y1Mesh mesh in the FAST linearization outputs. +FUNCTION Indx_y_SD_Y1Mesh_Start(y_SD, y_FAST) RESULT(SD_Out_Start) TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< FAST output file data (for linearization) - TYPE(HydroDyn_OutputType), INTENT(IN ) :: y_HD !< HD Outputs at t + TYPE(SD_OutputType), INTENT(IN ) :: y_SD !< SD outputs at t - INTEGER :: HD_Start - - !< starting index of this mesh in HydroDyn Outputs + INTEGER :: SD_Out_Start !< starting index of this mesh in ElastoDyn outputs - HD_Start = Indx_y_HD_PlatformRef_Start(y_HD, y_FAST) - if (y_HD%Mesh%committed) HD_Start = HD_Start + y_HD%Mesh%NNodes * 6 ! 2 fields (MASKID_FORCE,MASKID_MOMENT) with 3 components + SD_Out_Start = y_FAST%Lin%Modules(MODULE_SD)%Instance(1)%LinStartIndx(LIN_OUTPUT_COL) +END FUNCTION Indx_y_SD_Y1Mesh_Start!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine returns the starting index for the y_SD%Y2Mesh mesh in the FAST linearization outputs. +FUNCTION Indx_y_SD_Y2Mesh_Start(y_SD, y_FAST) RESULT(SD_Out_Start) + TYPE(FAST_OutputFileType), INTENT(IN ) :: y_FAST !< FAST output file data (for linearization) + TYPE(SD_OutputType), INTENT(IN ) :: y_SD !< SD outputs at t -END FUNCTION Indx_y_HD_AllHdro_Start + INTEGER :: SD_Out_Start !< starting index of this mesh in ElastoDyn outputs + SD_Out_Start = Indx_y_SD_Y1Mesh_Start(y_SD, y_FAST) + y_SD%Y1Mesh%NNodes * 6 ! 3 forces + 3 moments at each node! skip all of the Y1Mesh data and get to the beginning of +END FUNCTION Indx_y_SD_Y2Mesh_Start !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine allocates the arrays that store the operating point at each linearization time for later producing VTK @@ -4407,7 +4807,8 @@ SUBROUTINE PerturbOP(t, iLinTime, iMode, p_FAST, y_FAST, ED, BD, SrvD, AD, IfW, ! local variables INTEGER(IntKi) :: k ! generic loop counters - INTEGER(IntKi) :: i ! generic loop counters + INTEGER(IntKi) :: i, iStart ! generic loop counters + INTEGER(IntKi) :: iBody ! WAMIT body loop counter INTEGER(IntKi) :: j ! generic loop counters INTEGER(IntKi) :: indx ! generic loop counters INTEGER(IntKi) :: indx_last ! generic loop counters @@ -4431,7 +4832,7 @@ SUBROUTINE PerturbOP(t, iLinTime, iMode, p_FAST, y_FAST, ED, BD, SrvD, AD, IfW, if (allocated(y_FAST%Lin%Modules(ThisModule)%Instance(k)%op_x_eig_mag)) then do j=1,size(y_FAST%Lin%Modules(ThisModule)%Instance(k)%op_x) ! use this for the loop because ED may have a larger op_x_eig_mag array than op_x - + ! this is a hack because not all modules pack the continuous states in the same way: if (ThisModule == Module_ED) then if (j<= ED%p%DOFs%NActvDOF) then @@ -4536,42 +4937,42 @@ SUBROUTINE PerturbOP(t, iLinTime, iMode, p_FAST, y_FAST, ED, BD, SrvD, AD, IfW, !!!IF ( p_FAST%CompServo == Module_SrvD ) THEN !!!END IF - ! HydroDyn: copy op to actual states and inputs IF ( p_FAST%CompHydro == Module_HD ) THEN ThisModule = Module_HD if (allocated(y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_mag)) then - nStates = HD%p%WAMIT%SS_Exctn%N - if (nStates > 0) then - call GetStateAry(p_FAST, iMode, t, HD%x( STATE_CURR)%WAMIT%SS_Exctn%x, y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_mag( :nStates), y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_phase( :nStates)) - end if - if (nStates < size(y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_mag)) then - call GetStateAry(p_FAST, iMode, t, HD%x( STATE_CURR)%WAMIT%SS_Rdtn%x, y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_mag(1+nStates: ), y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_phase(1+nStates: )) - end if + ! WAMIT parameter and continuous states are now an arrays of length NBody + ! All Excitation states are stored first and then Radiation states. + ! We will try to loop over each of the NBody(s) and add each body's states to the overall state array + iStart = 1 + do iBody = 1, HD%p%NBody + nStates = HD%p%WAMIT(iBody)%SS_Exctn%numStates + if (nStates > 0) then + call GetStateAry(p_FAST, iMode, t, HD%x( STATE_CURR)%WAMIT(iBody)%SS_Exctn%x, y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_mag(iStart:iStart+nStates-1), y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_phase(iStart:iStart+nStates-1)) + iStart = iStart + nStates + end if + end do + do iBody = 1, HD%p%NBody + nStates = HD%p%WAMIT(iBody)%SS_Rdtn%numStates + if (nStates > 0) then + call GetStateAry(p_FAST, iMode, t, HD%x( STATE_CURR)%WAMIT(iBody)%SS_Rdtn%x, y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_mag(iStart:iStart+nStates-1), y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_phase(iStart:iStart+nStates-1)) + iStart = iStart + nStates + end if + end do end if END IF - - - !!!! SubDyn: copy final predictions to actual states - !!!IF ( p_FAST%CompSub == Module_SD ) THEN - !!!ELSE IF ( p_FAST%CompSub == Module_ExtPtfm ) THEN - !!!END IF - !!! - !!! - !!!! MAP/MoorDyn/FEAM: copy op to actual states and inputs - !!!IF (p_FAST%CompMooring == Module_MAP) THEN - !!!ELSEIF (p_FAST%CompMooring == Module_MD) THEN - !!!ELSEIF (p_FAST%CompMooring == Module_FEAM) THEN - !!!!ELSEIF (p_FAST%CompMooring == Module_Orca) THEN - !!!END IF - !!! - !!! ! IceFloe/IceDyn: copy op to actual states and inputs - !!!IF ( p_FAST%CompIce == Module_IceF ) THEN - !!!ELSEIF ( p_FAST%CompIce == Module_IceD ) THEN - !!! DO k=1,p_FAST%numIceLegs - !!! END DO - !!!END IF + + ! SubDyn: copy final predictions to actual states + IF ( p_FAST%CompSub == Module_SD ) THEN + ThisModule = Module_SD + if (allocated(y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_mag)) then + nStates = size(y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_mag)/2 + call GetStateAry(p_FAST, iMode, t, SD%x( STATE_CURR)%qm, y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_mag( :nStates), y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_phase( :nStates)) + call GetStateAry(p_FAST, iMode, t, SD%x( STATE_CURR)%qmdot, y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_mag(1+nStates: ), y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_phase(1+nStates: )) + end if + ELSE IF ( p_FAST%CompSub == Module_ExtPtfm ) THEN + END IF END SUBROUTINE PerturbOP !---------------------------------------------------------------------------------------------------------------------------------- @@ -5113,12 +5514,23 @@ SUBROUTINE FAST_InitSteadyOutputs( psi, p_FAST, m_FAST, ED, BD, SrvD, AD, IfW, H end if END IF ! HydroDyn - !! SubDyn/ExtPtfm_MCKF - !IF ( p_FAST%CompSub == Module_SD ) THEN - !ELSE IF ( p_FAST%CompSub == Module_ExtPtfm ) THEN - !END IF ! SubDyn/ExtPtfm_MCKF + IF ( p_FAST%CompSub == Module_SD ) THEN + allocate( SD%Output( p_FAST%LinInterpOrder+1 ), STAT = ErrStat2 ) + if (ErrStat2 /= 0) then + call SetErrStat(ErrID_Fatal, "Error allocating SD%Output.", ErrStat, ErrMsg, RoutineName ) + else + do j = 1, p_FAST%LinInterpOrder + 1 + call SD_CopyOutput(SD%y, SD%Output(j), MESH_NEWCOPY, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) + end do + + call SD_CopyOutput(SD%y, SD%y_interp, MESH_NEWCOPY, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) + end if + ELSE IF ( p_FAST%CompSub == Module_ExtPtfm ) THEN + END IF ! SubDyn/ExtPtfm_MCKF ! Mooring (MAP , FEAM , MoorDyn) @@ -5290,11 +5702,17 @@ SUBROUTINE FAST_SaveOutputs( psi, p_FAST, m_FAST, ED, BD, SrvD, AD, IfW, HD, SD, END IF ! HydroDyn - !! SubDyn/ExtPtfm_MCKF - !IF ( p_FAST%CompSub == Module_SD ) THEN - !ELSE IF ( p_FAST%CompSub == Module_ExtPtfm ) THEN - !END IF ! SubDyn/ExtPtfm_MCKF + IF ( p_FAST%CompSub == Module_SD ) THEN + DO j = p_FAST%LinInterpOrder, 1, -1 + CALL SD_CopyOutput (SD%Output(j), SD%Output(j+1), MESH_UPDATECOPY, ErrStat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) + END DO + + CALL SD_CopyOutput (SD%y, SD%Output(1), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) + ELSE IF ( p_FAST%CompSub == Module_ExtPtfm ) THEN + END IF ! SubDyn/ExtPtfm_MCKF ! Mooring (MAP , FEAM , MoorDyn) @@ -5447,11 +5865,18 @@ SUBROUTINE FAST_DiffInterpOutputs( psi_target, p_FAST, y_FAST, m_FAST, ED, BD, S call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) END IF ! HydroDyn - + !! SubDyn/ExtPtfm_MCKF - !IF ( p_FAST%CompSub == Module_SD ) THEN - !ELSE IF ( p_FAST%CompSub == Module_ExtPtfm ) THEN - !END IF ! SubDyn/ExtPtfm_MCKF + IF ( p_FAST%CompSub == Module_SD ) THEN + + CALL SD_Output_ExtrapInterp (SD%Output, m_FAST%Lin%Psi, SD%y_interp, psi_target, ErrStat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) + + call SD_GetOP( t_global, SD%Input(1), SD%p, SD%x(STATE_CURR), SD%xd(STATE_CURR), SD%z(STATE_CURR), SD%OtherSt(STATE_CURR), & + SD%y_interp, SD%m, ErrStat2, ErrMsg2, y_op=y_FAST%Lin%Modules(Module_SD)%Instance(1)%op_y) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + ELSE IF ( p_FAST%CompSub == Module_ExtPtfm ) THEN + END IF ! SubDyn/ExtPtfm_MCKF ! Mooring (MAP , FEAM , MoorDyn) diff --git a/modules/openfast-library/src/FAST_Registry.txt b/modules/openfast-library/src/FAST_Registry.txt index d599f93262..563d6b8ee5 100644 --- a/modules/openfast-library/src/FAST_Registry.txt +++ b/modules/openfast-library/src/FAST_Registry.txt @@ -463,6 +463,8 @@ typedef ^ ^ SD_InputType u - - - "System inputs" typedef ^ ^ SD_OutputType y - - - "System outputs" typedef ^ ^ SD_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ SD_InputType Input {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ SD_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" +typedef ^ ^ SD_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" # ..... ExtPtfm data ....................................................................................................... @@ -556,27 +558,29 @@ typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" # ..... FAST_ModuleMapType data ....................................................................................................... # ! Data structures for mapping and coupling the various modules together # ED <-> BD -typedef FAST FAST_ModuleMapType MeshMapType ED_P_2_BD_P {:} - - "Map ElastoDyn BladeRootMotion meshes to BeamDyn RootMotion point meshes" -typedef FAST FAST_ModuleMapType MeshMapType BD_P_2_ED_P {:} - - "Map BeamDyn ReactionForce loads point meshes to ElastoDyn HubPtLoad point mesh" -typedef FAST FAST_ModuleMapType MeshMapType ED_P_2_BD_P_Hub {:} - - "ElastoDyn hub to BeamDyn for hub orientation necessary for pitch actuator" +typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_BD_P {:} - - "Map ElastoDyn BladeRootMotion meshes to BeamDyn RootMotion point meshes" +typedef ^ FAST_ModuleMapType MeshMapType BD_P_2_ED_P {:} - - "Map BeamDyn ReactionForce loads point meshes to ElastoDyn HubPtLoad point mesh" +typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_BD_P_Hub {:} - - "ElastoDyn hub to BeamDyn for hub orientation necessary for pitch actuator" # ED <-> HD -typedef FAST FAST_ModuleMapType MeshMapType ED_P_2_HD_W_P - - - "Map ElastoDyn PlatformPtMesh to HydroDyn WAMIT Point" -typedef ^ FAST_ModuleMapType MeshMapType HD_W_P_2_ED_P - - - "Map HydroDyn WAMIT Point (from either y%Mesh or y%AllHydroOrigin) to ElastoDyn PlatformPtMesh" +typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_HD_PRP_P - - - "Map ElastoDyn PlatformPtMesh to HydroDyn platform reference Point" +typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_HD_W_P - - - "Map ElastoDyn PlatformPtMesh to HydroDyn WAMIT Point" +typedef ^ FAST_ModuleMapType MeshMapType HD_W_P_2_ED_P - - - "Map HydroDyn WAMIT Point from y%WAMITMesh to ElastoDyn PlatformPtMesh" typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_HD_M_P - - - "Map ElastoDyn PlatformPtMesh to HydroDyn Morison Point" typedef ^ FAST_ModuleMapType MeshMapType HD_M_P_2_ED_P - - - "Map HydroDyn Morison Point to ElastoDyn PlatformPtMesh" -typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_HD_M_L - - - "Map ElastoDyn PlatformPtMesh to HydroDyn Morison Line2" -typedef ^ FAST_ModuleMapType MeshMapType HD_M_L_2_ED_P - - - "Map HydroDyn Morison Line2 to ElastoDyn PlatformPtMesh" # ED <-> Mooring (MAP, FEAM, MoorDyn, OrcaFlex) typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_Mooring_P - - - "Map ElastoDyn PlatformPtMesh to MAP/FEAM/MoorDyn/OrcaFlex point mesh" typedef ^ FAST_ModuleMapType MeshMapType Mooring_P_2_ED_P - - - "Map FEAM/MAP/MoorDyn/OrcaFlex point mesh to ElastoDyn PlatformPtMesh" +# SD <-> Mooring (MAP, FEAM, MoorDyn, OrcaFlex) +typedef ^ FAST_ModuleMapType MeshMapType SD_P_2_Mooring_P - - - "Map SD Motions (y2Mesh) to MAP/FEAM/MoorDyn/OrcaFlex point mesh" +typedef ^ FAST_ModuleMapType MeshMapType Mooring_P_2_SD_P - - - "Map FEAM/MAP/MoorDyn/OrcaFlex point mesh to SD point loads (LMesh) mesh" # ED <-> SD or User-Platform (ExtPtfm_MCKF) typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_SD_TP - - - "Map ElastoDyn PlatformPtMesh to SubDyn transition-piece point mesh" typedef ^ FAST_ModuleMapType MeshMapType SD_TP_2_ED_P - - - "Map SubDyn transition-piece point mesh to ElastoDyn PlatformPtMesh" # SD <-> HD typedef ^ FAST_ModuleMapType MeshMapType SD_P_2_HD_M_P - - - "Map SubDyn y2Mesh Point to HydroDyn Morison Point" typedef ^ FAST_ModuleMapType MeshMapType HD_M_P_2_SD_P - - - "Map HydroDyn Morison Point to SubDyn y2Mesh Point" -typedef ^ FAST_ModuleMapType MeshMapType SD_P_2_HD_M_L - - - "Map SubDyn y2Mesh Point to HydroDyn Morison Line2" -typedef ^ FAST_ModuleMapType MeshMapType HD_M_L_2_SD_P - - - "Map HydroDyn Morison Line2 to SubDyn y2Mesh Point" +typedef ^ FAST_ModuleMapType MeshMapType SD_P_2_HD_W_P - - - "Map SubDyn y2Mesh Point to HydroDyn WAMIT Point" +typedef ^ FAST_ModuleMapType MeshMapType HD_W_P_2_SD_P - - - "Map HydroDyn WAMIT Point to SubDyn y2Mesh Point" # ED <-> SrvD/TMD typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_SrvD_P_N - - - "Map ElastoDyn Nacelle point mesh to ServoDyn/TMD point mesh" typedef ^ FAST_ModuleMapType MeshMapType SrvD_P_2_ED_P_N - - - "Map ServoDyn nacelle point mesh to ElastoDyn point mesh on the nacelle" @@ -592,10 +596,10 @@ typedef ^ FAST_ModuleMapType MeshMapType AD_L_2_ED_P_T - - - "Map AeroDyn14 Twr_ typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_AD_P_R {:} - - "Map ElastoDyn BladeRootMotion point meshes to AeroDyn BladeRootMotion point meshes" typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_AD_P_H - - - "Map ElastoDyn HubPtMotion point mesh to AeroDyn HubMotion point mesh" # IceF <-> SD -typedef ^ FAST_ModuleMapType MeshMapType IceF_P_2_SD_P - - - "Map IceFloe point mesh to SubDyn y2Mesh point mesh" +typedef ^ FAST_ModuleMapType MeshMapType IceF_P_2_SD_P - - - "Map IceFloe point mesh to SubDyn LMesh point mesh" typedef ^ FAST_ModuleMapType MeshMapType SD_P_2_IceF_P - - - "Map SubDyn y2Mesh point mesh to IceFloe point mesh" # IceD <-> SD -typedef ^ FAST_ModuleMapType MeshMapType IceD_P_2_SD_P {:} - - "Map IceDyn point mesh to SubDyn y2Mesh point mesh" +typedef ^ FAST_ModuleMapType MeshMapType IceD_P_2_SD_P {:} - - "Map IceDyn point mesh to SubDyn LMesh point mesh" typedef ^ FAST_ModuleMapType MeshMapType SD_P_2_IceD_P {:} - - "Map SubDyn y2Mesh point mesh to IceDyn point mesh" # Stored Jacobians: typedef ^ FAST_ModuleMapType ReKi Jacobian_Opt1 {:}{:} - - "Stored Jacobian in ED_HD_InputOutputSolve or FullOpt1_InputOutputSolve" @@ -607,9 +611,10 @@ typedef ^ FAST_ModuleMapType MeshType u_ED_PlatformPtMesh_2 - - - "copy of ED in typedef ^ FAST_ModuleMapType MeshType u_SD_TPMesh - - - "copy of SD input mesh" typedef ^ FAST_ModuleMapType MeshType u_SD_LMesh - - - "copy of SD input mesh" typedef ^ FAST_ModuleMapType MeshType u_SD_LMesh_2 - - - "copy of SD input mesh (used only for temporary storage)" -typedef ^ FAST_ModuleMapType MeshType u_HD_M_LumpedMesh - - - "copy of HD input mesh" -typedef ^ FAST_ModuleMapType MeshType u_HD_M_DistribMesh - - - "copy of HD input mesh" -typedef ^ FAST_ModuleMapType MeshType u_HD_Mesh - - - "copy of HD input mesh" +#typedef ^ FAST_ModuleMapType MeshType u_HD_M_LumpedMesh - - - "copy of HD input mesh" +typedef ^ FAST_ModuleMapType MeshType u_HD_M_Mesh - - - "copy of HD morison input mesh" +typedef ^ FAST_ModuleMapType MeshType u_HD_W_Mesh - - - "copy of HD wamit input mesh" +#typedef ^ FAST_ModuleMapType MeshType u_HD_PRP_Mesh - - - "copy of HD PRP input mesh" typedef ^ FAST_ModuleMapType MeshType u_ED_HubPtLoad - - - "copy of ED input mesh" typedef ^ FAST_ModuleMapType MeshType u_ED_HubPtLoad_2 - - - "copy of ED input mesh" typedef ^ FAST_ModuleMapType MeshType u_BD_RootMotion {:} - - "copy of BD input meshes" diff --git a/modules/openfast-library/src/FAST_Solver.f90 b/modules/openfast-library/src/FAST_Solver.f90 index c6ab8755fa..6a0423af5f 100644 --- a/modules/openfast-library/src/FAST_Solver.f90 +++ b/modules/openfast-library/src/FAST_Solver.f90 @@ -962,11 +962,11 @@ SUBROUTINE SrvD_SetExternalInputs( p_FAST, m_FAST, u_SrvD ) END SUBROUTINE SrvD_SetExternalInputs !---------------------------------------------------------------------------------------------------------------------------------- !> This routine transfers the SD outputs into inputs required for HD -SUBROUTINE Transfer_SD_to_HD( y_SD, u_HD_M_LumpedMesh, u_HD_M_DistribMesh, MeshMapData, ErrStat, ErrMsg ) +SUBROUTINE Transfer_SD_to_HD( y_SD, u_HD_W_Mesh, u_HD_M_Mesh, MeshMapData, ErrStat, ErrMsg ) !.................................................................................................................................. TYPE(SD_OutputType), INTENT(IN ) :: y_SD !< The outputs of the structural dynamics module - TYPE(MeshType), INTENT(INOUT) :: u_HD_M_LumpedMesh !< HydroDyn input mesh (separated here so that we can use temp meshes in ED_SD_HD_InputSolve) - TYPE(MeshType), INTENT(INOUT) :: u_HD_M_DistribMesh !< HydroDyn input mesh (separated here so that we can use temp meshes in ED_SD_HD_InputSolve) + TYPE(MeshType), INTENT(INOUT) :: u_HD_W_Mesh !< HydroDyn input mesh (separated here so that we can use temp meshes in ED_SD_HD_InputSolve) + TYPE(MeshType), INTENT(INOUT) :: u_HD_M_Mesh !< HydroDyn input mesh (separated here so that we can use temp meshes in ED_SD_HD_InputSolve) TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< data for mapping meshes INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation @@ -980,20 +980,19 @@ SUBROUTINE Transfer_SD_to_HD( y_SD, u_HD_M_LumpedMesh, u_HD_M_DistribMesh, MeshM ErrStat = ErrID_None ErrMsg = "" - - IF ( u_HD_M_LumpedMesh%Committed ) THEN + IF ( u_HD_W_Mesh%Committed ) THEN ! These are the motions for the lumped point loads associated viscous drag on the WAMIT body and/or filled/flooded lumped forces of the WAMIT body - CALL Transfer_Point_to_Point( y_SD%y2Mesh, u_HD_M_LumpedMesh, MeshMapData%SD_P_2_HD_M_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,'Transfer_SD_to_HD (u_HD%Morison%LumpedMesh)' ) + CALL Transfer_Point_to_Point( y_SD%y2Mesh, u_HD_W_Mesh, MeshMapData%SD_P_2_HD_W_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,'Transfer_SD_to_HD (u_HD%WAMITMesh)' ) - END IF - - IF ( u_HD_M_DistribMesh%Committed ) THEN + END IF + IF ( u_HD_M_Mesh%Committed ) THEN + + ! These are the motions for the lumped point loads associated viscous drag on the WAMIT body and/or filled/flooded lumped forces of the WAMIT body + CALL Transfer_Point_to_Point( y_SD%y2Mesh, u_HD_M_Mesh, MeshMapData%SD_P_2_HD_M_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,'Transfer_SD_to_HD (u_HD%Morison%Mesh)' ) - ! These are the motions for the HD line2 (distributed) loads associated viscous drag on the WAMIT body and/or filled/flooded distributed forces of the WAMIT body - CALL Transfer_Point_to_Line2( y_SD%y2Mesh, u_HD_M_DistribMesh, MeshMapData%SD_P_2_HD_M_L, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,'Transfer_SD_to_HD (u_HD%Morison%DistribMesh)' ) END IF END SUBROUTINE Transfer_SD_to_HD @@ -1017,34 +1016,32 @@ SUBROUTINE Transfer_PlatformMotion_to_HD( PlatformMotion, u_HD, MeshMapData, Err ErrStat = ErrID_None ErrMsg = "" + ! This is for case of rigid substructure + !bjj: We do this without all the extra meshcopy/destroy calls with u_mapped because these inputs are only from one mesh - IF ( u_HD%Mesh%Committed ) THEN - - ! These are the motions for the lumped point loads associated the WAMIT body and include: hydrostatics, radiation memory effect, + ! Transfer the ED outputs of the platform motions to the HD input of which represents the same data + CALL Transfer_Point_to_Point( PlatformMotion, u_HD%PRPMesh, MeshMapData%ED_P_2_HD_PRP_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,'Transfer_ED_to_HD (u_HD%PRPMesh)' ) + + IF ( u_HD%WAMITMesh%Committed ) THEN + + ! These are the motions for the lumped point loads associated the WAMIT body(ies) and include: hydrostatics, radiation memory effect, ! wave kinematics, additional preload, additional stiffness, additional linear damping, additional quadratic damping, ! hydrodynamic added mass - CALL Transfer_Point_to_Point( PlatformMotion, u_HD%Mesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg, RoutineName//' (u_HD%Mesh)' ) + CALL Transfer_Point_to_Point( PlatformMotion, u_HD%WAMITMesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg, RoutineName//' (u_HD%WAMITMesh)' ) END IF !WAMIT - IF ( u_HD%Morison%LumpedMesh%Committed ) THEN + IF ( u_HD%Morison%Mesh%Committed ) THEN ! These are the motions for the lumped point loads associated viscous drag on the WAMIT body and/or filled/flooded lumped forces of the WAMIT body - CALL Transfer_Point_to_Point( PlatformMotion, u_HD%Morison%LumpedMesh, MeshMapData%ED_P_2_HD_M_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg, RoutineName//' (u_HD%Morison%LumpedMesh)' ) - - END IF - - IF ( u_HD%Morison%DistribMesh%Committed ) THEN + CALL Transfer_Point_to_Point( PlatformMotion, u_HD%Morison%Mesh, MeshMapData%ED_P_2_HD_M_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg, RoutineName//' (u_HD%Morison%Mesh)' ) - ! These are the motions for the line2 (distributed) loads associated viscous drag on the WAMIT body and/or filled/flooded distributed forces of the WAMIT body - CALL Transfer_Point_to_Line2( PlatformMotion, u_HD%Morison%DistribMesh, MeshMapData%ED_P_2_HD_M_L, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg, RoutineName//' (u_HD%Morison%DistribMesh)' ) - END IF END SUBROUTINE Transfer_PlatformMotion_to_HD @@ -1083,7 +1080,7 @@ SUBROUTINE Transfer_ED_to_HD_SD_BD_Mooring( p_FAST, y_ED, u_HD, u_SD, u_ExtPtfm, CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_SD%TPMesh, MeshMapData%ED_P_2_SD_TP, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,RoutineName//':u_SD%TPMesh' ) - IF ( p_FAST%CompHydro == Module_HD ) call TransferFixedBottomToHD() + IF ( p_FAST%CompHydro == Module_HD ) call TransferEDToHD_PRP() ELSEIF ( p_FAST%CompSub == Module_ExtPtfm ) THEN @@ -1091,7 +1088,14 @@ SUBROUTINE Transfer_ED_to_HD_SD_BD_Mooring( p_FAST, y_ED, u_HD, u_SD, u_ExtPtfm, CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_ExtPtfm%PtfmMesh, MeshMapData%ED_P_2_SD_TP, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,RoutineName//':u_ExtPtfm%PtfmMesh' ) - IF ( p_FAST%CompHydro == Module_HD ) call TransferFixedBottomToHD() + if ( p_FAST%CompHydro == Module_HD ) then + ! Map ED outputs to HD inputs: + CALL Transfer_PlatformMotion_to_HD( y_ED%PlatformPtMesh, u_HD, MeshMapData, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,RoutineName ) + ! TODO: GJH Used to be the following GJH 5/13/2020 + ! call TransferFixedBottomToHD() + end if + ELSEIF ( p_FAST%CompHydro == Module_HD ) THEN ! Map ED outputs to HD inputs: @@ -1110,109 +1114,56 @@ SUBROUTINE Transfer_ED_to_HD_SD_BD_Mooring( p_FAST, y_ED, u_HD, u_SD, u_ExtPtfm, END IF - - IF ( p_FAST%CompMooring == Module_MAP ) THEN - - ! motions: - CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_MAP%PtFairDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,RoutineName//'u_MAP%PtFairDisplacement' ) + if ( p_FAST%CompSub /= Module_SD ) then + IF ( p_FAST%CompMooring == Module_MAP ) THEN + !TODO: GJH I do not have plan documentation for the External Platform connection to MAP GJH 8/11/2020 + ! motions: + CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_MAP%PtFairDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,RoutineName//'u_MAP%PtFairDisplacement' ) - ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN - ! motions: - CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_MD%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,RoutineName//'u_MD%PtFairleadDisplacement' ) + ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN + ! motions: + CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_MD%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,RoutineName//'u_MD%PtFairleadDisplacement' ) - ELSEIF ( p_FAST%CompMooring == Module_FEAM ) THEN - ! motions: - CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_FEAM%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,RoutineName//'u_FEAM%PtFairleadDisplacement' ) + ELSEIF ( p_FAST%CompMooring == Module_FEAM ) THEN + ! motions: + CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_FEAM%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,RoutineName//'u_FEAM%PtFairleadDisplacement' ) - ELSEIF ( p_FAST%CompMooring == Module_Orca ) THEN - ! motions: - CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_Orca%PtfmMesh, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,RoutineName//'u_Orca%PtfmMesh' ) - END IF + ELSEIF ( p_FAST%CompMooring == Module_Orca ) THEN + ! motions: + CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_Orca%PtfmMesh, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,RoutineName//'u_Orca%PtfmMesh' ) + END IF + end if contains - subroutine TransferFixedBottomToHD() - IF ( u_HD%Mesh%Committed ) THEN + subroutine TransferEDToHD_PRP() + + ! These are the motions for the lumped point loads associated the WAMIT body and include: hydrostatics, radiation memory effect, + ! wave kinematics, additional preload, additional stiffness, additional linear damping, additional quadratic damping, + ! hydrodynamic added mass + CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_HD%PRPMesh, MeshMapData%ED_P_2_HD_PRP_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg, RoutineName//' (u_HD%PRPMesh)' ) + + end subroutine + + subroutine TransferFixedBottomToHD() + IF ( u_HD%WAMITMesh%Committed ) THEN +!TODO: GJH Do we still need this? ExtPtfm ? GJH 5/11/2020 ! These are the motions for the lumped point loads associated the WAMIT body and include: hydrostatics, radiation memory effect, ! wave kinematics, additional preload, additional stiffness, additional linear damping, additional quadratic damping, ! hydrodynamic added mass - CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_HD%Mesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2 ) + CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_HD%WAMITMesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg, RoutineName//' (u_HD%Mesh)' ) END IF !WAMIT end subroutine END SUBROUTINE Transfer_ED_to_HD_SD_BD_Mooring -!---------------------------------------------------------------------------------------------------------------------------------- -!> This routine sets the inputs required for MAP. -SUBROUTINE MAP_InputSolve( u_MAP, y_ED, MeshMapData, ErrStat, ErrMsg ) -!.................................................................................................................................. - - ! Passed variables - TYPE(MAP_InputType), INTENT(INOUT) :: u_MAP !< MAP input - TYPE(ED_OutputType), INTENT(IN ) :: y_ED !< The outputs of the structural dynamics module - TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< data for mapping meshes between modules - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*) , INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - !---------------------------------------------------------------------------------------------------- - ! Map ED outputs to MAP inputs - !---------------------------------------------------------------------------------------------------- - ! motions: - CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_MAP%PtFairDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) - - -END SUBROUTINE MAP_InputSolve -!---------------------------------------------------------------------------------------------------------------------------------- -!> This routine sets the inputs required for FEAM. -SUBROUTINE FEAM_InputSolve( u_FEAM, y_ED, MeshMapData, ErrStat, ErrMsg ) -!.................................................................................................................................. - - ! Passed variables - TYPE(FEAM_InputType), INTENT(INOUT) :: u_FEAM !< FEAM input - TYPE(ED_OutputType), INTENT(IN ) :: y_ED !< The outputs of the structural dynamics module - TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< data for mapping meshes between modules - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*) , INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - !---------------------------------------------------------------------------------------------------- - ! Map ED outputs to FEAM inputs - !---------------------------------------------------------------------------------------------------- - ! motions: - CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_FEAM%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) - - -END SUBROUTINE FEAM_InputSolve -!---------------------------------------------------------------------------------------------------------------------------------- -!> This routine sets the inputs required for MoorDyn. -SUBROUTINE MD_InputSolve( u_MD, y_ED, MeshMapData, ErrStat, ErrMsg ) -!.................................................................................................................................. - - ! Passed variables - TYPE(MD_InputType), INTENT(INOUT) :: u_MD !< MoorDyn input - TYPE(ED_OutputType), INTENT(IN ) :: y_ED !< The outputs of the structural dynamics module - TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< data for mapping meshes between modules - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*) , INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - !---------------------------------------------------------------------------------------------------- - ! Map ED outputs to MoorDyn inputs - !---------------------------------------------------------------------------------------------------- - ! motions: - CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_MD%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) - -END SUBROUTINE MD_InputSolve !---------------------------------------------------------------------------------------------------------------------------------- !> This routine sets the inputs required for IceFloe. SUBROUTINE IceFloe_InputSolve( u_IceF, y_SD, MeshMapData, ErrStat, ErrMsg ) @@ -1336,14 +1287,14 @@ END SUBROUTINE Transfer_ED_to_BD_tmp !---------------------------------------------------------------------------------------------------------------------------------- !> This routine transfers the HD outputs into inputs required for ED. Note that this *adds* to the values already in !! u_SD_LMesh (so initialize it before calling this routine). -SUBROUTINE Transfer_HD_to_SD( u_mapped, u_SD_LMesh, u_mapped_positions, y_HD, u_HD_M_LumpedMesh, u_HD_M_DistribMesh, MeshMapData, ErrStat, ErrMsg ) +SUBROUTINE Transfer_HD_to_SD( u_mapped, u_SD_LMesh, u_mapped_positions, y_HD, u_HD_W_Mesh, u_HD_M_Mesh, MeshMapData, ErrStat, ErrMsg ) !.................................................................................................................................. TYPE(MeshType), INTENT(INOUT) :: u_mapped !< temporary copy of SD mesh (an argument to avoid another temporary mesh copy) TYPE(MeshType), INTENT(INOUT) :: u_SD_LMesh !< SD Inputs on LMesh at t (separate so we can call from FullOpt1_InputOutputSolve with temp meshes) TYPE(MeshType), INTENT(IN ) :: u_mapped_positions !< Mesh sibling of u_mapped, with displaced positions TYPE(HydroDyn_OutputType), INTENT(IN ) :: y_HD !< HydroDyn outputs - TYPE(MeshType), INTENT(IN ) :: u_HD_M_LumpedMesh !< HydroDyn input mesh (separate so we can call from FullOpt1_InputOutputSolve with temp meshes) - TYPE(MeshType), INTENT(IN ) :: u_HD_M_DistribMesh !< HydroDyn input mesh (separate so we can call from FullOpt1_InputOutputSolve with temp meshes) + TYPE(MeshType), INTENT(IN ) :: u_HD_W_Mesh !< HydroDyn WAMIT input mesh (separate so we can call from FullOpt1_InputOutputSolve with temp meshes) + TYPE(MeshType), INTENT(IN ) :: u_HD_M_Mesh !< HydroDyn Morison input mesh (separate so we can call from FullOpt1_InputOutputSolve with temp meshes) TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status @@ -1359,10 +1310,9 @@ SUBROUTINE Transfer_HD_to_SD( u_mapped, u_SD_LMesh, u_mapped_positions, y_HD, u_ ErrMsg = "" !assumes u_SD%LMesh%Committed (i.e., u_SD_LMesh%Committed) - - IF ( y_HD%Morison%LumpedMesh%Committed ) THEN + IF ( y_HD%WAMITMesh%Committed ) THEN ! we're mapping loads, so we also need the sibling meshes' displacements: - CALL Transfer_Point_to_Point( y_HD%Morison%LumpedMesh, u_mapped, MeshMapData%HD_M_P_2_SD_P, ErrStat2, ErrMsg2, u_HD_M_LumpedMesh, u_mapped_positions ) + CALL Transfer_Point_to_Point( y_HD%WAMITMesh, u_mapped, MeshMapData%HD_W_P_2_SD_P, ErrStat2, ErrMsg2, u_HD_W_Mesh, u_mapped_positions ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1371,39 +1321,40 @@ SUBROUTINE Transfer_HD_to_SD( u_mapped, u_SD_LMesh, u_mapped_positions, y_HD, u_ #ifdef DEBUG_MESH_TRANSFER CALL WrScr('********************************************************') - CALL WrScr('**** SD to HD point-to-point (morison lumped) *****') + CALL WrScr('**** SD to HD point-to-point (WAMIT) *****') CALL WrScr('********************************************************') - CALL WriteMappingTransferToFile(u_mapped, u_mapped_positions, u_HD_M_LumpedMesh, y_HD%Morison%LumpedMesh,& - MeshMapData%SD_P_2_HD_M_P, MeshMapData%HD_M_P_2_SD_P, & - 'SD_y2_HD_ML_Meshes_t'//TRIM(Num2LStr(0))//'.bin' ) + CALL WriteMappingTransferToFile(u_mapped, u_mapped_positions, u_HD_W_Mesh, y_HD%WAMITMesh,& + MeshMapData%SD_P_2_HD_W_P, MeshMapData%HD_M_P_2_SD_P, & + 'SD_y2_HD_WP_Meshes_t'//TRIM(Num2LStr(0))//'.bin' ) !print * !pause -#endif - - END IF +#endif + END IF - IF ( y_HD%Morison%DistribMesh%Committed ) THEN + IF ( y_HD%Morison%Mesh%Committed ) THEN ! we're mapping loads, so we also need the sibling meshes' displacements: - CALL Transfer_Line2_to_Point( y_HD%Morison%DistribMesh, u_mapped, MeshMapData%HD_M_L_2_SD_P, ErrStat2, ErrMsg2, u_HD_M_DistribMesh, u_mapped_positions ) + CALL Transfer_Point_to_Point( y_HD%Morison%Mesh, u_mapped, MeshMapData%HD_M_P_2_SD_P, ErrStat2, ErrMsg2, u_HD_M_Mesh, u_mapped_positions ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN u_SD_LMesh%Force = u_SD_LMesh%Force + u_mapped%Force - u_SD_LMesh%Moment = u_SD_LMesh%Moment + u_mapped%Moment - -#ifdef DEBUG_MESH_TRANSFER + u_SD_LMesh%Moment = u_SD_LMesh%Moment + u_mapped%Moment + +#ifdef DEBUG_MESH_TRANSFER CALL WrScr('********************************************************') - CALL WrScr('**** SD to HD point-to-line2 (morison distributed) *****') + CALL WrScr('**** SD to HD point-to-point (morison) *****') CALL WrScr('********************************************************') - CALL WriteMappingTransferToFile(u_mapped, u_mapped_positions, u_HD_M_DistribMesh,y_HD%Morison%DistribMesh,& - MeshMapData%SD_P_2_HD_M_L, MeshMapData%HD_M_L_2_SD_P, & - 'SD_y2_HD_MD_Meshes_t'//TRIM(Num2LStr(0))//'.bin' ) + CALL WriteMappingTransferToFile(u_mapped, u_mapped_positions, u_HD_M_Mesh, y_HD%Morison%Mesh,& + MeshMapData%SD_P_2_HD_M_P, MeshMapData%HD_M_P_2_SD_P, & + 'SD_y2_HD_MP_Meshes_t'//TRIM(Num2LStr(0))//'.bin' ) !print * - ! pause + !pause + #endif END IF + END SUBROUTINE Transfer_HD_to_SD !---------------------------------------------------------------------------------------------------------------------------------- @@ -1419,6 +1370,7 @@ END FUNCTION GetPerturb !---------------------------------------------------------------------------------------------------------------------------------- !> This routine performs the Input-Output solve for ED and HD. !! Note that this has been customized for the physics in the problems and is not a general solution. +!! This is only called is there is no substructure model (RIGID substructure) SUBROUTINE ED_HD_InputOutputSolve( this_time, p_FAST, calcJacobian & , u_ED, p_ED, x_ED, xd_ED, z_ED, OtherSt_ED, y_ED, m_ED & , u_HD, p_HD, x_HD, xd_HD, z_HD, OtherSt_HD, y_HD, m_HD & @@ -1565,7 +1517,8 @@ SUBROUTINE ED_HD_InputOutputSolve( this_time, p_FAST, calcJacobian & CALL HydroDyn_CalcOutput( this_time, u_HD, p_HD, x_HD, xd_HD, z_HD, OtherSt_HD, y_HD, m_HD, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - + !write(*,*) 'y_HD%Morison%Mesh%Force', y_HD%Morison%Mesh%Force + !write(*,*) 'y_HD%Morison%Mesh%Moment', y_HD%Morison%Mesh%Moment IF (ErrStat >= AbortErrLev) THEN CALL CleanUp() RETURN @@ -1788,61 +1741,75 @@ SUBROUTINE U_ED_HD_Residual( y_ED2, y_HD2, u_IN, U_Resid) PlatformMotions => y_ED2%PlatformPtMesh + ! This is only called is there is no flexible substructure model (RIGID substructure) + ! ! Transfer motions: - + !.................. ! Set mooring line inputs (which don't have acceleration fields) !.................. IF ( p_FAST%CompMooring == Module_MAP ) THEN - ! note: MAP_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) - CALL MAP_InputSolve( u_map, y_ED2, MeshMapData, ErrStat2, ErrMsg2 ) + ! note: MAP_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) + CALL Transfer_Point_to_Point( y_ED2%PlatformPtMesh, u_MAP%PtFairDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Transfer_Point_to_Point( y_MAP%PtFairleadLoad, MeshMapData%u_ED_PlatformPtMesh_2, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, u_MAP%PtFairDisplacement, PlatformMotions ) !u_MAP and y_ED contain the displacements needed for moment calculations + CALL Transfer_Point_to_Point( y_MAP%PtFairleadLoad, MeshMapData%u_ED_PlatformPtMesh, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, u_MAP%PtFairDisplacement, PlatformMotions ) !u_MAP and y_ED contain the displacements needed for moment calculations CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN - ! note: MD_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) - CALL MD_InputSolve( u_MD, y_ED2, MeshMapData, ErrStat2, ErrMsg2 ) + ! note: MD_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) + CALL Transfer_Point_to_Point( y_ED2%PlatformPtMesh, u_MD%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Transfer_Point_to_Point( y_MD%PtFairleadLoad, MeshMapData%u_ED_PlatformPtMesh_2, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, u_MD%PtFairleadDisplacement, PlatformMotions ) !u_MD and y_ED contain the displacements needed for moment calculations + CALL Transfer_Point_to_Point( y_MD%PtFairleadLoad, MeshMapData%u_ED_PlatformPtMesh, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, u_MD%PtFairleadDisplacement, PlatformMotions ) !u_MD and y_ED contain the displacements needed for moment calculations CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF ( p_FAST%CompMooring == Module_FEAM ) THEN - ! note: FEAM_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) - CALL FEAM_InputSolve( u_FEAM, y_ED2, MeshMapData, ErrStat2, ErrMsg2 ) + ! note: FEAM_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) + CALL Transfer_Point_to_Point( y_ED2%PlatformPtMesh, u_FEAM%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL Transfer_Point_to_Point( y_FEAM%PtFairleadLoad, MeshMapData%u_ED_PlatformPtMesh_2, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, u_FEAM%PtFairleadDisplacement, PlatformMotions ) !u_FEAM and y_ED contain the displacements needed for moment calculations + CALL Transfer_Point_to_Point( y_FEAM%PtFairleadLoad, MeshMapData%u_ED_PlatformPtMesh, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, u_FEAM%PtFairleadDisplacement, PlatformMotions ) !u_FEAM and y_ED contain the displacements needed for moment calculations CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSE - MeshMapData%u_ED_PlatformPtMesh_2%Force = 0.0_ReKi - MeshMapData%u_ED_PlatformPtMesh_2%Moment = 0.0_ReKi + MeshMapData%u_ED_PlatformPtMesh%Force = 0.0_ReKi + MeshMapData%u_ED_PlatformPtMesh%Moment = 0.0_ReKi END IF ! we use copies of the input meshes (we don't need to update values in the original data structures): !bjj: why don't we update u_HD2 here? shouldn't we update before using it to transfer the loads? - - CALL Transfer_Point_to_Point( PlatformMotions, MeshMapData%u_HD_Mesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if ( y_HD2%WAMITMesh%Committed ) then + ! Need to transfer motions first + CALL Transfer_Point_to_Point( PlatformMotions, MeshMapData%u_HD_W_Mesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ! we're mapping loads, so we also need the sibling meshes' displacements: - CALL Transfer_Point_to_Point( y_HD2%AllHdroOrigin, MeshMapData%u_ED_PlatformPtMesh, MeshMapData%HD_W_P_2_ED_P, ErrStat2, ErrMsg2, MeshMapData%u_HD_Mesh, PlatformMotions) !u_HD and u_mapped_positions contain the displaced positions for load calculations - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! we're mapping loads, so we also need the sibling meshes' displacements: + CALL Transfer_Point_to_Point( y_HD2%WAMITMesh, MeshMapData%u_ED_PlatformPtMesh_2, MeshMapData%HD_W_P_2_ED_P, ErrStat2, ErrMsg2, MeshMapData%u_HD_W_Mesh, PlatformMotions) !u_HD and u_mapped_positions contain the displaced positions for load calculations + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - MeshMapData%u_ED_PlatformPtMesh%Force = MeshMapData%u_ED_PlatformPtMesh%Force + MeshMapData%u_ED_PlatformPtMesh_2%Force - MeshMapData%u_ED_PlatformPtMesh%Moment = MeshMapData%u_ED_PlatformPtMesh%Moment + MeshMapData%u_ED_PlatformPtMesh_2%Moment - - + MeshMapData%u_ED_PlatformPtMesh%Force = MeshMapData%u_ED_PlatformPtMesh%Force + MeshMapData%u_ED_PlatformPtMesh_2%Force + MeshMapData%u_ED_PlatformPtMesh%Moment = MeshMapData%u_ED_PlatformPtMesh%Moment + MeshMapData%u_ED_PlatformPtMesh_2%Moment + end if + if ( y_HD2%Morison%Mesh%Committed ) then + ! Need to transfer motions first + CALL Transfer_Point_to_Point( PlatformMotions, MeshMapData%u_HD_M_Mesh, MeshMapData%ED_P_2_HD_M_P, ErrStat2, ErrMsg2) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! we're mapping loads, so we also need the sibling meshes' displacements: + CALL Transfer_Point_to_Point( y_HD2%Morison%Mesh, MeshMapData%u_ED_PlatformPtMesh_2, MeshMapData%HD_M_P_2_ED_P, ErrStat2, ErrMsg2, MeshMapData%u_HD_M_Mesh, PlatformMotions) !u_HD and u_mapped_positions contain the displaced positions for load calculations + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + MeshMapData%u_ED_PlatformPtMesh%Force = MeshMapData%u_ED_PlatformPtMesh%Force + MeshMapData%u_ED_PlatformPtMesh_2%Force + MeshMapData%u_ED_PlatformPtMesh%Moment = MeshMapData%u_ED_PlatformPtMesh%Moment + MeshMapData%u_ED_PlatformPtMesh_2%Moment + end if U_Resid( 1: 3) = u_in( 1: 3) - MeshMapData%u_ED_PlatformPtMesh%Force(:,1) / p_FAST%UJacSclFact U_Resid( 4: 6) = u_in( 4: 6) - MeshMapData%u_ED_PlatformPtMesh%Moment(:,1) / p_FAST%UJacSclFact @@ -2112,8 +2079,8 @@ SUBROUTINE FullOpt1_InputOutputSolve( this_time, p_FAST, calcJacobian & CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END DO - CALL Create_FullOpt1_UVector(u, u_ED%PlatformPtMesh, u_SD%TPMesh, u_SD%LMesh, u_HD%Morison%LumpedMesh, & - u_HD%Morison%DistribMesh, u_HD%Mesh, u_ED%HubPtLoad, MeshMapData%u_BD_RootMotion, u_Orca%PtfmMesh, & + CALL Create_FullOpt1_UVector(u, u_ED%PlatformPtMesh, u_SD%TPMesh, u_SD%LMesh, & + u_HD%Morison%Mesh, u_HD%WAMITMesh, u_ED%HubPtLoad, MeshMapData%u_BD_RootMotion, u_Orca%PtfmMesh, & u_ExtPtfm%PtfmMesh, p_FAST ) K = 0 @@ -2427,37 +2394,26 @@ SUBROUTINE FullOpt1_InputOutputSolve( this_time, p_FAST, calcJacobian & END DO END IF - DO TmpIndx=1,u_HD%Morison%LumpedMesh%NNodes - CALL WrFileNR(UnJac, ' HD_M_Lumped_TranslationAcc_X_'//TRIM(Num2LStr(TmpIndx))) - CALL WrFileNR(UnJac, ' HD_M_Lumped_TranslationAcc_Y_'//TRIM(Num2LStr(TmpIndx))) - CALL WrFileNR(UnJac, ' HD_M_Lumped_TranslationAcc_Z_'//TRIM(Num2LStr(TmpIndx))) + DO TmpIndx=1,u_HD%Morison%Mesh%NNodes + CALL WrFileNR(UnJac, ' HD_M_Mesh_TranslationAcc_X_'//TRIM(Num2LStr(TmpIndx))) + CALL WrFileNR(UnJac, ' HD_M_Mesh_TranslationAcc_Y_'//TRIM(Num2LStr(TmpIndx))) + CALL WrFileNR(UnJac, ' HD_M_Mesh_TranslationAcc_Z_'//TRIM(Num2LStr(TmpIndx))) END DO - DO TmpIndx=1,u_HD%Morison%LumpedMesh%NNodes - CALL WrFileNR(UnJac, ' HD_M_Lumped_RotationAcc_X_'//TRIM(Num2LStr(TmpIndx))) - CALL WrFileNR(UnJac, ' HD_M_Lumped_RotationAcc_Y_'//TRIM(Num2LStr(TmpIndx))) - CALL WrFileNR(UnJac, ' HD_M_Lumped_RotationAcc_Z_'//TRIM(Num2LStr(TmpIndx))) - END DO - - DO TmpIndx=1,u_HD%Morison%DistribMesh%NNodes - CALL WrFileNR(UnJac, ' HD_M_Distrib_TranslationAcc_X_'//TRIM(Num2LStr(TmpIndx))) - CALL WrFileNR(UnJac, ' HD_M_Distrib_TranslationAcc_Y_'//TRIM(Num2LStr(TmpIndx))) - CALL WrFileNR(UnJac, ' HD_M_Distrib_TranslationAcc_Z_'//TRIM(Num2LStr(TmpIndx))) + DO TmpIndx=1,u_HD%Morison%Mesh%NNodes + CALL WrFileNR(UnJac, ' HD_M_Mesh_RotationAcc_X_'//TRIM(Num2LStr(TmpIndx))) + CALL WrFileNR(UnJac, ' HD_M_Mesh_RotationAcc_Y_'//TRIM(Num2LStr(TmpIndx))) + CALL WrFileNR(UnJac, ' HD_M_Mesh_RotationAcc_Z_'//TRIM(Num2LStr(TmpIndx))) END DO - DO TmpIndx=1,u_HD%Morison%DistribMesh%NNodes - CALL WrFileNR(UnJac, ' HD_M_Distrib_RotationAcc_X_'//TRIM(Num2LStr(TmpIndx))) - CALL WrFileNR(UnJac, ' HD_M_Distrib_RotationAcc_Y_'//TRIM(Num2LStr(TmpIndx))) - CALL WrFileNR(UnJac, ' HD_M_Distrib_RotationAcc_Z_'//TRIM(Num2LStr(TmpIndx))) - END DO - DO TmpIndx=1,u_HD%Mesh%NNodes - CALL WrFileNR(UnJac, ' HD_Mesh_TranslationAcc_X_'//TRIM(Num2LStr(TmpIndx))) - CALL WrFileNR(UnJac, ' HD_Mesh_TranslationAcc_Y_'//TRIM(Num2LStr(TmpIndx))) - CALL WrFileNR(UnJac, ' HD_Mesh_TranslationAcc_Z_'//TRIM(Num2LStr(TmpIndx))) + DO TmpIndx=1,u_HD%WAMITMesh%NNodes + CALL WrFileNR(UnJac, ' HD_W_Mesh_TranslationAcc_X_'//TRIM(Num2LStr(TmpIndx))) + CALL WrFileNR(UnJac, ' HD_W_Mesh_TranslationAcc_Y_'//TRIM(Num2LStr(TmpIndx))) + CALL WrFileNR(UnJac, ' HD_W_Mesh_TranslationAcc_Z_'//TRIM(Num2LStr(TmpIndx))) END DO - DO TmpIndx=1,u_HD%Mesh%NNodes - CALL WrFileNR(UnJac, ' HD_Mesh_RotationAcc_X_'//TRIM(Num2LStr(TmpIndx))) - CALL WrFileNR(UnJac, ' HD_Mesh_RotationAcc_Y_'//TRIM(Num2LStr(TmpIndx))) - CALL WrFileNR(UnJac, ' HD_Mesh_RotationAcc_Z_'//TRIM(Num2LStr(TmpIndx))) + DO TmpIndx=1,u_HD%WAMITMesh%NNodes + CALL WrFileNR(UnJac, ' HD_W_Mesh_RotationAcc_X_'//TRIM(Num2LStr(TmpIndx))) + CALL WrFileNR(UnJac, ' HD_W_Mesh_RotationAcc_Y_'//TRIM(Num2LStr(TmpIndx))) + CALL WrFileNR(UnJac, ' HD_W_Mesh_RotationAcc_Z_'//TRIM(Num2LStr(TmpIndx))) END DO DO nb=1,p_FAST%nBeams @@ -2570,17 +2526,14 @@ SUBROUTINE FullOpt1_InputOutputSolve( this_time, p_FAST, calcJacobian & IF (p_FAST%CompHydro == Module_HD ) THEN ! Make copies of the accelerations we just solved for (so we don't overwrite them) - IF (MeshMapData%u_HD_M_LumpedMesh%Committed) THEN - MeshMapData%u_HD_M_LumpedMesh%RotationAcc = u_HD%Morison%LumpedMesh%RotationAcc - MeshMapData%u_HD_M_LumpedMesh%TranslationAcc = u_HD%Morison%LumpedMesh%TranslationAcc + IF (MeshMapData%u_HD_M_Mesh%Committed) THEN + MeshMapData%u_HD_M_Mesh%RotationAcc = u_HD%Morison%Mesh%RotationAcc + MeshMapData%u_HD_M_Mesh%TranslationAcc = u_HD%Morison%Mesh%TranslationAcc ENDIF - IF (MeshMapData%u_HD_M_DistribMesh%Committed) THEN - MeshMapData%u_HD_M_DistribMesh%RotationAcc = u_HD%Morison%DistribMesh%RotationAcc - MeshMapData%u_HD_M_DistribMesh%TranslationAcc = u_HD%Morison%DistribMesh%TranslationAcc - ENDIF - IF (MeshMapData%u_HD_Mesh%Committed) THEN - MeshMapData%u_HD_Mesh%RotationAcc = u_HD%Mesh%RotationAcc - MeshMapData%u_HD_Mesh%TranslationAcc = u_HD%Mesh%TranslationAcc + + IF (MeshMapData%u_HD_W_Mesh%Committed) THEN + MeshMapData%u_HD_W_Mesh%RotationAcc = u_HD%WAMITMesh%RotationAcc + MeshMapData%u_HD_W_Mesh%TranslationAcc = u_HD%WAMITMesh%TranslationAcc ENDIF ! transfer the output data to inputs @@ -2588,13 +2541,14 @@ SUBROUTINE FullOpt1_InputOutputSolve( this_time, p_FAST, calcJacobian & IF ( p_FAST%CompSub == Module_SD ) THEN ! Map SD outputs to HD inputs (keeping the accelerations we just calculated) - CALL Transfer_SD_to_HD( y_SD, u_HD%Morison%LumpedMesh, u_HD%Morison%DistribMesh, MeshMapData, ErrStat2, ErrMsg2 ) + CALL Transfer_SD_to_HD( y_SD, u_HD%WAMITMesh, u_HD%Morison%Mesh, MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ! Map ED outputs to HD inputs (keeping the accelerations we just calculated): + ! Map ED outputs to HD inputs (keeping the accelerations we just calculated): - CALL Transfer_Point_to_Point( PlatformMotionMesh, u_HD%Mesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! Transfer the ED outputs of the platform motions to the HD input of which represents the same data + CALL Transfer_Point_to_Point( PlatformMotionMesh, u_HD%PRPMesh, MeshMapData%ED_P_2_HD_PRP_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg, RoutineName ) ELSE @@ -2605,17 +2559,14 @@ SUBROUTINE FullOpt1_InputOutputSolve( this_time, p_FAST, calcJacobian & ! put the acceleration data (calucluted in this routine) back - IF (MeshMapData%u_HD_M_LumpedMesh%Committed) THEN - u_HD%Morison%LumpedMesh%RotationAcc = MeshMapData%u_HD_M_LumpedMesh%RotationAcc - u_HD%Morison%LumpedMesh%TranslationAcc = MeshMapData%u_HD_M_LumpedMesh%TranslationAcc + IF (MeshMapData%u_HD_M_Mesh%Committed) THEN + u_HD%Morison%Mesh%RotationAcc = MeshMapData%u_HD_M_Mesh%RotationAcc + u_HD%Morison%Mesh%TranslationAcc = MeshMapData%u_HD_M_Mesh%TranslationAcc ENDIF - IF (MeshMapData%u_HD_M_DistribMesh%Committed) THEN - u_HD%Morison%DistribMesh%RotationAcc = MeshMapData%u_HD_M_DistribMesh%RotationAcc - u_HD%Morison%DistribMesh%TranslationAcc = MeshMapData%u_HD_M_DistribMesh%TranslationAcc - ENDIF - IF (MeshMapData%u_HD_Mesh%Committed) THEN - u_HD%Mesh%RotationAcc = MeshMapData%u_HD_Mesh%RotationAcc - u_HD%Mesh%TranslationAcc = MeshMapData%u_HD_Mesh%TranslationAcc + + IF (MeshMapData%u_HD_W_Mesh%Committed) THEN + u_HD%WAMITMesh%RotationAcc = MeshMapData%u_HD_W_Mesh%RotationAcc + u_HD%WAMITMesh%TranslationAcc = MeshMapData%u_HD_W_Mesh%TranslationAcc ENDIF !...... @@ -2696,28 +2647,45 @@ SUBROUTINE U_FullOpt1_Residual( y_ED2, y_SD2, y_HD2, y_BD2, y_Orca2, y_ExtPtfm2, PlatformMotions => y_ED2%PlatformPtMesh + !.................. ! Set mooring line and ice inputs (which don't have acceleration fields and aren't used elsewhere in this routine, thus we're using the actual inputs (not a copy) ! Note that these values get overwritten at the completion of this routine.) !.................. + IF ( p_FAST%CompMooring == Module_MAP ) THEN ! note: MAP_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) - CALL MAP_InputSolve( u_map, y_ED2, MeshMapData, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) - + if ( p_FAST%CompSub == Module_SD ) then + CALL Transfer_Point_to_Point( y_SD2%y2Mesh, u_MAP%PtFairDisplacement, MeshMapData%SD_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + else + CALL Transfer_Point_to_Point( y_ED2%PlatformPtMesh, u_MAP%PtFairDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + end if + ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN - ! note: MD_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) - CALL MD_InputSolve( u_MD, y_ED2, MeshMapData, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) - + ! note: MD_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) + if ( p_FAST%CompSub == Module_SD ) then + CALL Transfer_Point_to_Point( y_SD2%y2Mesh, u_MD%PtFairleadDisplacement, MeshMapData%SD_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + else + CALL Transfer_Point_to_Point( y_ED2%PlatformPtMesh, u_MD%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + end if + ELSEIF ( p_FAST%CompMooring == Module_FEAM ) THEN - ! note: FEAM_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) - CALL FEAM_InputSolve( u_FEAM, y_ED2, MeshMapData, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + ! note: FEAM_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) + if ( p_FAST%CompSub == Module_SD ) then + CALL Transfer_Point_to_Point( y_SD2%y2Mesh, u_FEAM%PtFairleadDisplacement, MeshMapData%SD_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + else + CALL Transfer_Point_to_Point( y_ED2%PlatformPtMesh, u_FEAM%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + end if ELSEIF ( p_FAST%CompMooring == Module_Orca ) THEN @@ -2775,25 +2743,21 @@ SUBROUTINE U_FullOpt1_Residual( y_ED2, y_SD2, y_HD2, y_BD2, y_Orca2, y_ExtPtfm2, !.................. - ! Get HD inputs on Morison%LumpedMesh and Morison%DistribMesh + ! Get HD inputs on Morison%Mesh and WAMITMesh !.................. ! SD motions to HD: - CALL Transfer_SD_to_HD( y_SD2, MeshMapData%u_HD_M_LumpedMesh, MeshMapData%u_HD_M_DistribMesh, MeshMapData, ErrStat2, ErrMsg2 ) + CALL Transfer_SD_to_HD( y_SD2, MeshMapData%u_HD_W_Mesh, MeshMapData%u_HD_M_Mesh, MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) - - ! Map ED motion output to HD inputs: - CALL Transfer_Point_to_Point( PlatformMotions, MeshMapData%u_HD_Mesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) !.................. - ! Get SD loads inputs (MeshMapData%u_HD_M_LumpedMesh and MeshMapData%u_HD_M_DistribMesh meshes must be set first) + ! Get SD loads inputs (MeshMapData%u_HD_W_Mesh and MeshMapData%u_HD_M_Mesh meshes must be set first) !.................. ! Loads (outputs) from HD meshes transfered to SD LMesh (zero them out first because they get summed in Transfer_HD_to_SD) - CALL Transfer_HD_to_SD( MeshMapData%u_SD_LMesh_2, MeshMapData%u_SD_LMesh, y_SD2%Y2Mesh, y_HD2, MeshMapData%u_HD_M_LumpedMesh, MeshMapData%u_HD_M_DistribMesh, MeshMapData, ErrStat2, ErrMsg2 ) + CALL Transfer_HD_to_SD( MeshMapData%u_SD_LMesh_2, MeshMapData%u_SD_LMesh, y_SD2%Y2Mesh, y_HD2, MeshMapData%u_HD_W_Mesh, MeshMapData%u_HD_M_Mesh, MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -2863,21 +2827,10 @@ SUBROUTINE U_FullOpt1_Residual( y_ED2, y_SD2, y_HD2, y_BD2, y_Orca2, y_ExtPtfm2, ! we're mapping loads, so we also need the sibling meshes' displacements: CALL Transfer_Point_to_Point( y_SD2%Y1Mesh, MeshMapData%u_ED_PlatformPtMesh, MeshMapData%SD_TP_2_ED_P, ErrStat2, ErrMsg2, MeshMapData%u_SD_TPMesh, PlatformMotions ) !MeshMapData%u_SD_TPMesh contains the orientations needed for moment calculations CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) - - ! WAMIT loads from HD get added to this load: - IF ( y_HD2%Mesh%Committed ) THEN - - ! we're mapping loads, so we also need the sibling meshes' displacements: - CALL Transfer_Point_to_Point( y_HD2%Mesh, MeshMapData%u_ED_PlatformPtMesh_2, MeshMapData%HD_W_P_2_ED_P, ErrStat2, ErrMsg2, MeshMapData%u_HD_Mesh, PlatformMotions ) !u_SD contains the orientations needed for moment calculations - CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) - - MeshMapData%u_ED_PlatformPtMesh%Force = MeshMapData%u_ED_PlatformPtMesh%Force + MeshMapData%u_ED_PlatformPtMesh_2%Force - MeshMapData%u_ED_PlatformPtMesh%Moment = MeshMapData%u_ED_PlatformPtMesh%Moment + MeshMapData%u_ED_PlatformPtMesh_2%Moment - - END IF + ELSE IF (p_FAST%CompSub == Module_ExtPtfm) THEN - + !.................. ! Get ExtPtfm motions input !.................. @@ -2897,6 +2850,8 @@ SUBROUTINE U_FullOpt1_Residual( y_ED2, y_SD2, y_HD2, y_BD2, y_Orca2, y_ExtPtfm2, ELSE IF ( p_FAST%CompHydro == Module_HD ) THEN + ! Rigid Substructure case + !.................. ! Get HD inputs on 3 meshes !.................. @@ -2906,31 +2861,42 @@ SUBROUTINE U_FullOpt1_Residual( y_ED2, y_SD2, y_HD2, y_BD2, y_Orca2, y_ExtPtfm2, ! CALL Transfer_PlatformMotion_to_HD( y_ED2%PlatformPtMesh, u_HD, MeshMapData, ErrStat2, ErrMsg2 ) ! so, here are the transfers, again. - + ! Motions from ED to HD for mesh mapping + ! These are the motions for the lumped point loads associated the WAMIT body: - CALL Transfer_Point_to_Point( PlatformMotions, MeshMapData%u_HD_Mesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) - + if (MeshMapData%u_HD_W_Mesh%Committed) then + CALL Transfer_Point_to_Point( PlatformMotions, MeshMapData%u_HD_W_Mesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + endif + ! These are the motions for the lumped point loads associated viscous drag on the WAMIT body and/or filled/flooded lumped forces of the WAMIT body - if (MeshMapData%u_HD_M_LumpedMesh%Committed) then - CALL Transfer_Point_to_Point( PlatformMotions, MeshMapData%u_HD_M_LumpedMesh, MeshMapData%ED_P_2_HD_M_P, ErrStat2, ErrMsg2 ) + if (MeshMapData%u_HD_M_Mesh%Committed) then + CALL Transfer_Point_to_Point( PlatformMotions, MeshMapData%u_HD_M_Mesh, MeshMapData%ED_P_2_HD_M_P, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) endif - ! These are the motions for the line2 (distributed) loads associated viscous drag on the WAMIT body and/or filled/flooded distributed forces of the WAMIT body - if (MeshMapData%u_HD_M_DistribMesh%Committed) then - CALL Transfer_Point_to_Line2( PlatformMotions, MeshMapData%u_HD_M_DistribMesh, MeshMapData%ED_P_2_HD_M_L, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) - endif + !.................. ! Get ED loads input (from HD only) !.................. - + MeshMapData%u_ED_PlatformPtMesh%Force = 0.0_ReKi + MeshMapData%u_ED_PlatformPtMesh%Moment = 0.0_ReKi + ! we're mapping loads, so we also need the sibling meshes' displacements: - CALL Transfer_Point_to_Point( y_HD2%AllHdroOrigin, MeshMapData%u_ED_PlatformPtMesh, MeshMapData%HD_W_P_2_ED_P, ErrStat2, ErrMsg2, MeshMapData%u_HD_Mesh, PlatformMotions) !u_HD and u_mapped_positions contain the displaced positions for load calculations - CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) - + if ( y_HD2%WAMITMesh%Committed) then + CALL Transfer_Point_to_Point( y_HD2%WAMITMesh, MeshMapData%u_ED_PlatformPtMesh, MeshMapData%HD_W_P_2_ED_P, ErrStat2, ErrMsg2, MeshMapData%u_HD_W_Mesh, PlatformMotions) !u_HD and u_mapped_positions contain the displaced positions for load calculations + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + end if + + if ( y_HD2%Morison%Mesh%Committed ) then + CALL Transfer_Point_to_Point( y_HD2%Morison%Mesh, MeshMapData%u_ED_PlatformPtMesh_2, MeshMapData%HD_M_P_2_ED_P, ErrStat2, ErrMsg2, MeshMapData%u_HD_M_Mesh, PlatformMotions ) !u_MAP and y_ED contain the displacements needed for moment calculations + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + + MeshMapData%u_ED_PlatformPtMesh%Force = MeshMapData%u_ED_PlatformPtMesh%Force + MeshMapData%u_ED_PlatformPtMesh_2%Force + MeshMapData%u_ED_PlatformPtMesh%Moment = MeshMapData%u_ED_PlatformPtMesh%Moment + MeshMapData%u_ED_PlatformPtMesh_2%Moment + end if + ELSE ! When using OrcaFlex, we need to zero this out @@ -2940,32 +2906,56 @@ SUBROUTINE U_FullOpt1_Residual( y_ED2, y_SD2, y_HD2, y_BD2, y_Orca2, y_ExtPtfm2, END IF !.................. - ! Get remaining portion of ED loads input on MeshMapData%u_ED_PlatformPtMesh (must do this after MeshMapData%u_SD_TPMesh and MeshMapData%u_HD_Mesh are set) + ! Get remaining portion of ED loads input on MeshMapData%u_ED_PlatformPtMesh (must do this after MeshMapData%u_SD_TPMesh and MeshMapData%u_HD_W_Mesh are set) ! at this point, MeshMapData%u_ED_PlatformPtMesh contains the portion of loads from SD and/or HD !.................. - + - ! Get the loads for ED from a mooring module and add them: + ! Get the loads for ED/SD from a mooring module and add them: IF ( p_FAST%CompMooring == Module_MAP ) THEN - CALL Transfer_Point_to_Point( y_MAP%PtFairleadLoad, MeshMapData%u_ED_PlatformPtMesh_2, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, u_MAP%PtFairDisplacement, PlatformMotions ) !u_MAP and y_ED contain the displacements needed for moment calculations - CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + if ( p_FAST%CompSub == Module_SD ) then + CALL Transfer_Point_to_Point( y_MAP%PtFairleadLoad, MeshMapData%u_SD_LMesh_2, MeshMapData%Mooring_P_2_SD_P, ErrStat2, ErrMsg2, u_MAP%PtFairDisplacement, y_SD2%Y2Mesh ) !u_MAP and y_SD contain the displacements needed for moment calculations + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) - MeshMapData%u_ED_PlatformPtMesh%Force = MeshMapData%u_ED_PlatformPtMesh%Force + MeshMapData%u_ED_PlatformPtMesh_2%Force - MeshMapData%u_ED_PlatformPtMesh%Moment = MeshMapData%u_ED_PlatformPtMesh%Moment + MeshMapData%u_ED_PlatformPtMesh_2%Moment + MeshMapData%u_SD_LMesh%Force = MeshMapData%u_SD_LMesh%Force + MeshMapData%u_SD_LMesh_2%Force + MeshMapData%u_SD_LMesh%Moment = MeshMapData%u_SD_LMesh%Moment + MeshMapData%u_SD_LMesh_2%Moment + else + CALL Transfer_Point_to_Point( y_MAP%PtFairleadLoad, MeshMapData%u_ED_PlatformPtMesh_2, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, u_MAP%PtFairDisplacement, PlatformMotions ) !u_MAP and y_ED contain the displacements needed for moment calculations + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + MeshMapData%u_ED_PlatformPtMesh%Force = MeshMapData%u_ED_PlatformPtMesh%Force + MeshMapData%u_ED_PlatformPtMesh_2%Force + MeshMapData%u_ED_PlatformPtMesh%Moment = MeshMapData%u_ED_PlatformPtMesh%Moment + MeshMapData%u_ED_PlatformPtMesh_2%Moment + end if + ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN - CALL Transfer_Point_to_Point( y_MD%PtFairleadLoad, MeshMapData%u_ED_PlatformPtMesh_2, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, u_MD%PtFairleadDisplacement, PlatformMotions ) !u_MD and y_ED contain the displacements needed for moment calculations - CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + if ( p_FAST%CompSub == Module_SD ) then + CALL Transfer_Point_to_Point( y_MD%PtFairleadLoad, MeshMapData%u_SD_LMesh_2, MeshMapData%Mooring_P_2_SD_P, ErrStat2, ErrMsg2, u_MD%PtFairleadDisplacement, y_SD2%Y2Mesh ) !u_MD and y_SD contain the displacements needed for moment calculations + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) - MeshMapData%u_ED_PlatformPtMesh%Force = MeshMapData%u_ED_PlatformPtMesh%Force + MeshMapData%u_ED_PlatformPtMesh_2%Force - MeshMapData%u_ED_PlatformPtMesh%Moment = MeshMapData%u_ED_PlatformPtMesh%Moment + MeshMapData%u_ED_PlatformPtMesh_2%Moment - + MeshMapData%u_SD_LMesh%Force = MeshMapData%u_SD_LMesh%Force + MeshMapData%u_SD_LMesh_2%Force + MeshMapData%u_SD_LMesh%Moment = MeshMapData%u_SD_LMesh%Moment + MeshMapData%u_SD_LMesh_2%Moment + else + CALL Transfer_Point_to_Point( y_MD%PtFairleadLoad, MeshMapData%u_ED_PlatformPtMesh_2, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, u_MD%PtFairleadDisplacement, PlatformMotions ) !u_MD and y_ED contain the displacements needed for moment calculations + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + + MeshMapData%u_ED_PlatformPtMesh%Force = MeshMapData%u_ED_PlatformPtMesh%Force + MeshMapData%u_ED_PlatformPtMesh_2%Force + MeshMapData%u_ED_PlatformPtMesh%Moment = MeshMapData%u_ED_PlatformPtMesh%Moment + MeshMapData%u_ED_PlatformPtMesh_2%Moment + end if + ELSEIF ( p_FAST%CompMooring == Module_FEAM ) THEN - CALL Transfer_Point_to_Point( y_FEAM%PtFairleadLoad, MeshMapData%u_ED_PlatformPtMesh_2, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, u_FEAM%PtFairleadDisplacement, PlatformMotions ) !u_FEAM and y_ED contain the displacements needed for moment calculations - CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + if ( p_FAST%CompSub == Module_SD ) then + CALL Transfer_Point_to_Point( y_FEAM%PtFairleadLoad, MeshMapData%u_SD_LMesh_2, MeshMapData%Mooring_P_2_SD_P, ErrStat2, ErrMsg2, u_FEAM%PtFairleadDisplacement, y_SD2%Y2Mesh ) !u_FEAM and y_SD contain the displacements needed for moment calculations + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) - MeshMapData%u_ED_PlatformPtMesh%Force = MeshMapData%u_ED_PlatformPtMesh%Force + MeshMapData%u_ED_PlatformPtMesh_2%Force - MeshMapData%u_ED_PlatformPtMesh%Moment = MeshMapData%u_ED_PlatformPtMesh%Moment + MeshMapData%u_ED_PlatformPtMesh_2%Moment + MeshMapData%u_SD_LMesh%Force = MeshMapData%u_SD_LMesh%Force + MeshMapData%u_SD_LMesh_2%Force + MeshMapData%u_SD_LMesh%Moment = MeshMapData%u_SD_LMesh%Moment + MeshMapData%u_SD_LMesh_2%Moment + else + CALL Transfer_Point_to_Point( y_FEAM%PtFairleadLoad, MeshMapData%u_ED_PlatformPtMesh_2, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, u_FEAM%PtFairleadDisplacement, PlatformMotions ) !u_FEAM and y_ED contain the displacements needed for moment calculations + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + + MeshMapData%u_ED_PlatformPtMesh%Force = MeshMapData%u_ED_PlatformPtMesh%Force + MeshMapData%u_ED_PlatformPtMesh_2%Force + MeshMapData%u_ED_PlatformPtMesh%Moment = MeshMapData%u_ED_PlatformPtMesh%Moment + MeshMapData%u_ED_PlatformPtMesh_2%Moment + end if ELSEIF ( p_FAST%CompMooring == Module_Orca ) THEN CALL Transfer_Point_to_Point( y_Orca2%PtfmMesh, MeshMapData%u_ED_PlatformPtMesh_2, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, MeshMapData%u_Orca_PtfmMesh, PlatformMotions ) !u_Orca_PtfmMesh and y_ED contain the displacements needed for moment calculations @@ -2980,7 +2970,7 @@ SUBROUTINE U_FullOpt1_Residual( y_ED2, y_SD2, y_HD2, y_BD2, y_Orca2, y_ExtPtfm2, !.................. CALL Create_FullOpt1_UVector(U_Resid, MeshMapData%u_ED_PlatformPtMesh, MeshMapData%u_SD_TPMesh, MeshMapData%u_SD_LMesh, & - MeshMapData%u_HD_M_LumpedMesh, MeshMapData%u_HD_M_DistribMesh, MeshMapData%u_HD_Mesh, & + MeshMapData%u_HD_M_Mesh, MeshMapData%u_HD_W_Mesh, & MeshMapData%u_ED_HubPtLoad, MeshMapData%u_BD_RootMotion, MeshMapData%u_Orca_PtfmMesh, & MeshMapData%u_ExtPtfm_PtfmMesh, p_FAST ) @@ -3039,7 +3029,7 @@ END SUBROUTINE FullOpt1_InputOutputSolve !---------------------------------------------------------------------------------------------------------------------------------- !> This routine initializes the array that maps rows/columns of the Jacobian to specific mesh fields. !! Do not change the order of this packing without changing subroutine Create_FullOpt1_UVector()! -SUBROUTINE Init_FullOpt1_Jacobian( p_FAST, MeshMapData, ED_PlatformPtMesh, SD_TPMesh, SD_LMesh, HD_M_LumpedMesh, HD_M_DistribMesh, & +SUBROUTINE Init_FullOpt1_Jacobian( p_FAST, MeshMapData, ED_PlatformPtMesh, SD_TPMesh, SD_LMesh, HD_M_Mesh, & HD_WAMIT_Mesh, ED_HubPtLoad, u_BD, Orca_PtfmMesh, ExtPtfm_PtfmMesh, ErrStat, ErrMsg) TYPE(FAST_ParameterType) , INTENT(INOUT) :: p_FAST !< FAST parameters @@ -3050,8 +3040,7 @@ SUBROUTINE Init_FullOpt1_Jacobian( p_FAST, MeshMapData, ED_PlatformPtMesh, SD_TP TYPE(MeshType) , INTENT(IN ) :: ED_HubPtLoad !< ElastoDyn's HubPtLoad mesh TYPE(MeshType) , INTENT(IN ) :: SD_TPMesh !< SubDyn's TP (transition piece) mesh TYPE(MeshType) , INTENT(IN ) :: SD_LMesh !< SubDyn's LMesh - TYPE(MeshType) , INTENT(IN ) :: HD_M_LumpedMesh !< HydroDyn's Morison Lumped Mesh - TYPE(MeshType) , INTENT(IN ) :: HD_M_DistribMesh !< HydroDyn's Morison Distributed Mesh + TYPE(MeshType) , INTENT(IN ) :: HD_M_Mesh !< HydroDyn's Morison Lumped Mesh TYPE(MeshType) , INTENT(IN ) :: HD_WAMIT_Mesh !< HydroDyn's WAMIT mesh TYPE(BD_InputType) , INTENT(IN ) :: u_BD(:) !< inputs for each instance of the BeamDyn module (for the RootMotion meshes) TYPE(MeshType) , INTENT(IN ) :: Orca_PtfmMesh !< OrcaFlex interface PtfmMesh @@ -3084,8 +3073,7 @@ SUBROUTINE Init_FullOpt1_Jacobian( p_FAST, MeshMapData, ED_PlatformPtMesh, SD_TP + SD_LMesh%NNodes *6 ! SD inputs: 6 loads per node (size of SD input from HD) END IF - p_FAST%SizeJac_Opt1(4) = HD_M_LumpedMesh%NNodes *6 & ! HD inputs: 6 accelerations per node (on each Morison mesh) - + HD_M_DistribMesh%NNodes*6 & ! HD inputs: 6 accelerations per node (on each Morison mesh) + p_FAST%SizeJac_Opt1(4) = HD_M_Mesh%NNodes *6 & ! HD inputs: 6 accelerations per node (on each Morison mesh) + HD_WAMIT_Mesh%NNodes*6 ! HD inputs: 6 accelerations per node (on the WAMIT mesh) IF ( p_FAST%CompElast == Module_BD .and. BD_Solve_Option1) THEN @@ -3236,19 +3224,19 @@ SUBROUTINE Init_FullOpt1_Jacobian( p_FAST, MeshMapData, ED_PlatformPtMesh, SD_TP ! HD inputs: !............... - !(Morison%LumpedMesh) - do i=1,HD_M_LumpedMesh%NNodes + !(Morison%Mesh) + do i=1,HD_M_Mesh%NNodes do j=1,3 - MeshMapData%Jac_u_indx(index,1) = 9 !Module/Mesh/Field: u_HD%Morison%LumpedMesh%TranslationAcc = 9 + MeshMapData%Jac_u_indx(index,1) = 9 !Module/Mesh/Field: u_HD%Morison%Mesh%TranslationAcc = 9 MeshMapData%Jac_u_indx(index,2) = j !index: j MeshMapData%Jac_u_indx(index,3) = i !Node: i index = index + 1 end do !j end do !i - do i=1,HD_M_LumpedMesh%NNodes + do i=1,HD_M_Mesh%NNodes do j=1,3 - MeshMapData%Jac_u_indx(index,1) = 10 !Module/Mesh/Field: u_HD%Morison%LumpedMesh%RotationAcc = 10 + MeshMapData%Jac_u_indx(index,1) = 10 !Module/Mesh/Field: u_HD%Morison%Mesh%RotationAcc = 10 MeshMapData%Jac_u_indx(index,2) = j !index: j MeshMapData%Jac_u_indx(index,3) = i !Node: i index = index + 1 @@ -3256,29 +3244,10 @@ SUBROUTINE Init_FullOpt1_Jacobian( p_FAST, MeshMapData, ED_PlatformPtMesh, SD_TP end do !i - !(Morison%DistribMesh) - do i=1,HD_M_DistribMesh%NNodes - do j=1,3 - MeshMapData%Jac_u_indx(index,1) = 11 !Module/Mesh/Field: u_HD%Morison%DistribMesh%TranslationAcc = 11 - MeshMapData%Jac_u_indx(index,2) = j !index: j - MeshMapData%Jac_u_indx(index,3) = i !Node: i - index = index + 1 - end do !j - end do !i - - do i=1,HD_M_DistribMesh%NNodes - do j=1,3 - MeshMapData%Jac_u_indx(index,1) = 12 !Module/Mesh/Field: u_HD%Morison%DistribMesh%RotationAcc = 12 - MeshMapData%Jac_u_indx(index,2) = j !index: j - MeshMapData%Jac_u_indx(index,3) = i !Node: i - index = index + 1 - end do !j - end do !i - !(Mesh) do i=1,HD_WAMIT_Mesh%NNodes do j=1,3 - MeshMapData%Jac_u_indx(index,1) = 13 !Module/Mesh/Field: u_HD%Mesh%TranslationAcc = 13 + MeshMapData%Jac_u_indx(index,1) = 11 !Module/Mesh/Field: u_HD%WAMITMesh%TranslationAcc = 11 MeshMapData%Jac_u_indx(index,2) = j !index: j MeshMapData%Jac_u_indx(index,3) = i !Node: i index = index + 1 @@ -3287,7 +3256,7 @@ SUBROUTINE Init_FullOpt1_Jacobian( p_FAST, MeshMapData, ED_PlatformPtMesh, SD_TP do i=1,HD_WAMIT_Mesh%NNodes do j=1,3 - MeshMapData%Jac_u_indx(index,1) = 14 !Module/Mesh/Field: u_HD%Mesh%RotationAcc = 14 + MeshMapData%Jac_u_indx(index,1) = 12 !Module/Mesh/Field: u_HD%WAMITMesh%RotationAcc = 12 MeshMapData%Jac_u_indx(index,2) = j !index: j MeshMapData%Jac_u_indx(index,3) = i !Node: i index = index + 1 @@ -3304,7 +3273,7 @@ SUBROUTINE Init_FullOpt1_Jacobian( p_FAST, MeshMapData, ED_PlatformPtMesh, SD_TP do i=1,u_BD(k)%RootMotion%NNodes do j=1,3 - MeshMapData%Jac_u_indx(index,1) = 13 + 2*k !Module/Mesh/Field: u_BD(k)%RootMotion%TranslationAcc = 15 (k=1), 17 (k=2), 19 (k=3) + MeshMapData%Jac_u_indx(index,1) = 11 + 2*k !Module/Mesh/Field: u_BD(k)%RootMotion%TranslationAcc = 13 (k=1), 15 (k=2), 17 (k=3) MeshMapData%Jac_u_indx(index,2) = j !index: j MeshMapData%Jac_u_indx(index,3) = i !Node: i index = index + 1 @@ -3313,7 +3282,7 @@ SUBROUTINE Init_FullOpt1_Jacobian( p_FAST, MeshMapData, ED_PlatformPtMesh, SD_TP do i=1,u_BD(k)%RootMotion%NNodes do j=1,3 - MeshMapData%Jac_u_indx(index,1) = 14 + 2*k !Module/Mesh/Field: u_BD(k)%RootMotion%RotationAcc = 16 (k=1), 18 (k=2), 20 (k=3) + MeshMapData%Jac_u_indx(index,1) = 12 + 2*k !Module/Mesh/Field: u_BD(k)%RootMotion%RotationAcc = 14 (k=1), 16 (k=2), 18 (k=3) MeshMapData%Jac_u_indx(index,2) = j !index: j MeshMapData%Jac_u_indx(index,3) = i !Node: i index = index + 1 @@ -3331,7 +3300,7 @@ SUBROUTINE Init_FullOpt1_Jacobian( p_FAST, MeshMapData, ED_PlatformPtMesh, SD_TP ! Orca_PtfmMesh do i=1,Orca_PtfmMesh%NNodes do j=1,3 - MeshMapData%Jac_u_indx(index,1) = 21 !Module/Mesh/Field: u_Orca%PtfmMesh%TranslationAcc = 21 + MeshMapData%Jac_u_indx(index,1) = 19 !Module/Mesh/Field: u_Orca%PtfmMesh%TranslationAcc = 19 MeshMapData%Jac_u_indx(index,2) = j !index: j MeshMapData%Jac_u_indx(index,3) = i !Node: i index = index + 1 @@ -3340,7 +3309,7 @@ SUBROUTINE Init_FullOpt1_Jacobian( p_FAST, MeshMapData, ED_PlatformPtMesh, SD_TP do i=1,Orca_PtfmMesh%NNodes do j=1,3 - MeshMapData%Jac_u_indx(index,1) = 22 !Module/Mesh/Field: u_Orca%PtfmMesh%RotationAcc = 22 + MeshMapData%Jac_u_indx(index,1) = 20 !Module/Mesh/Field: u_Orca%PtfmMesh%RotationAcc = 20 MeshMapData%Jac_u_indx(index,2) = j !index: j MeshMapData%Jac_u_indx(index,3) = i !Node: i index = index + 1 @@ -3354,7 +3323,7 @@ SUBROUTINE Init_FullOpt1_Jacobian( p_FAST, MeshMapData, ED_PlatformPtMesh, SD_TP ! ExtPtfm_PtfmMesh do i=1,ExtPtfm_PtfmMesh%NNodes do j=1,3 - MeshMapData%Jac_u_indx(index,1) = 23 !Module/Mesh/Field: u_ExtPtfm%PtfmMesh%TranslationAcc = 23 + MeshMapData%Jac_u_indx(index,1) = 21 !Module/Mesh/Field: u_ExtPtfm%PtfmMesh%TranslationAcc = 21 MeshMapData%Jac_u_indx(index,2) = j !index: j MeshMapData%Jac_u_indx(index,3) = i !Node: i index = index + 1 @@ -3363,7 +3332,7 @@ SUBROUTINE Init_FullOpt1_Jacobian( p_FAST, MeshMapData, ED_PlatformPtMesh, SD_TP do i=1,ExtPtfm_PtfmMesh%NNodes do j=1,3 - MeshMapData%Jac_u_indx(index,1) = 24 !Module/Mesh/Field: u_ExtPtfm%PtfmMesh%RotationAcc = 24 + MeshMapData%Jac_u_indx(index,1) = 22 !Module/Mesh/Field: u_ExtPtfm%PtfmMesh%RotationAcc = 22 MeshMapData%Jac_u_indx(index,2) = j !index: j MeshMapData%Jac_u_indx(index,3) = i !Node: i index = index + 1 @@ -3375,7 +3344,7 @@ END SUBROUTINE Init_FullOpt1_Jacobian !---------------------------------------------------------------------------------------------------------------------------------- !> This routine basically packs the relevant parts of the modules' input meshes for use in this InputOutput solve. !! Do not change the order of this packing without changing subroutine Init_FullOpt1_Jacobian()! -SUBROUTINE Create_FullOpt1_UVector(u, ED_PlatformPtMesh, SD_TPMesh, SD_LMesh, HD_M_LumpedMesh, HD_M_DistribMesh, HD_WAMIT_Mesh, & +SUBROUTINE Create_FullOpt1_UVector(u, ED_PlatformPtMesh, SD_TPMesh, SD_LMesh, HD_M_Mesh, HD_WAMIT_Mesh, & ED_HubPtLoad, BD_RootMotion, Orca_PtfmMesh, ExtPtfm_PtfmMesh, p_FAST ) !.................................................................................................................................. @@ -3385,8 +3354,7 @@ SUBROUTINE Create_FullOpt1_UVector(u, ED_PlatformPtMesh, SD_TPMesh, SD_LMesh, HD TYPE(MeshType) , INTENT(IN ) :: ED_PlatformPtMesh !< ElastoDyn PlatformPt mesh TYPE(MeshType) , INTENT(IN ) :: SD_TPMesh !< SubDyn TP mesh TYPE(MeshType) , INTENT(IN ) :: SD_LMesh !< SubDyn Lmesh - TYPE(MeshType) , INTENT(IN ) :: HD_M_LumpedMesh !< HydroDyn Morison Lumped mesh - TYPE(MeshType) , INTENT(IN ) :: HD_M_DistribMesh !< HydroDyn Morison distributed mesh + TYPE(MeshType) , INTENT(IN ) :: HD_M_Mesh !< HydroDyn Morison Lumped mesh TYPE(MeshType) , INTENT(IN ) :: HD_WAMIT_Mesh !< HydroDyn WAMIT mesh TYPE(MeshType) , INTENT(IN ) :: ED_HubPtLoad !< ElastoDyn HubPt mesh TYPE(MeshType) , INTENT(IN ) :: BD_RootMotion(:) !< BeamDyn RootMotion meshes @@ -3459,30 +3427,17 @@ SUBROUTINE Create_FullOpt1_UVector(u, ED_PlatformPtMesh, SD_TPMesh, SD_LMesh, HD end if !............... - ! HD inputs (Morison%LumpedMesh): + ! HD inputs (Morison%Mesh): !............... - do i=1,HD_M_LumpedMesh%NNodes + do i=1,HD_M_Mesh%NNodes indx_last = indx_first + 2 - u(indx_first:indx_last) = HD_M_LumpedMesh%TranslationAcc(:,i) + u(indx_first:indx_last) = HD_M_Mesh%TranslationAcc(:,i) indx_first = indx_last + 1 end do - do i=1,HD_M_LumpedMesh%NNodes + do i=1,HD_M_Mesh%NNodes indx_last = indx_first + 2 - u(indx_first:indx_last) = HD_M_LumpedMesh%RotationAcc(:,i) - indx_first = indx_last + 1 - end do - - ! HD inputs (Morison%DistribMesh): - do i=1,HD_M_DistribMesh%NNodes - indx_last = indx_first + 2 - u(indx_first:indx_last) = HD_M_DistribMesh%TranslationAcc(:,i) - indx_first = indx_last + 1 - end do - - do i=1,HD_M_DistribMesh%NNodes - indx_last = indx_first + 2 - u(indx_first:indx_last) = HD_M_DistribMesh%RotationAcc(:,i) + u(indx_first:indx_last) = HD_M_Mesh%RotationAcc(:,i) indx_first = indx_last + 1 end do @@ -3600,40 +3555,37 @@ SUBROUTINE Add_FullOpt1_u_delta( p_FAST, Jac_u_indx, u_delta, u_ED, u_SD, u_HD, CASE ( 8) !Module/Mesh/Field: u_SD%LMesh%Moment = 8 u_SD%LMesh%Moment(fieldIndx,node) = u_SD%LMesh%Moment(fieldIndx,node) + u_delta(n) * p_FAST%UJacSclFact - CASE ( 9) !Module/Mesh/Field: u_HD%Morison%LumpedMesh%TranslationAcc = 9 - u_HD%Morison%LumpedMesh%TranslationAcc(fieldIndx,node) = u_HD%Morison%LumpedMesh%TranslationAcc(fieldIndx,node) + u_delta(n) - CASE (10) !Module/Mesh/Field: u_HD%Morison%LumpedMesh%RotationAcc = 10 - u_HD%Morison%LumpedMesh%RotationAcc( fieldIndx,node) = u_HD%Morison%LumpedMesh%RotationAcc( fieldIndx,node) + u_delta(n) - CASE (11) !Module/Mesh/Field: u_HD%Morison%DistribMesh%TranslationAcc = 11 - u_HD%Morison%DistribMesh%TranslationAcc(fieldIndx,node) = u_HD%Morison%DistribMesh%TranslationAcc(fieldIndx,node) + u_delta(n) - CASE (12) !Module/Mesh/Field: u_HD%Morison%DistribMesh%RotationAcc = 12 - u_HD%Morison%DistribMesh%RotationAcc( fieldIndx,node) = u_HD%Morison%DistribMesh%RotationAcc( fieldIndx,node) + u_delta(n) - CASE (13) !Module/Mesh/Field: u_HD%Mesh%TranslationAcc = 13 - u_HD%Mesh%TranslationAcc( fieldIndx,node) = u_HD%Mesh%TranslationAcc( fieldIndx,node) + u_delta(n) - CASE (14) !Module/Mesh/Field: u_HD%Mesh%RotationAcc = 14 - u_HD%Mesh%RotationAcc( fieldIndx,node) = u_HD%Mesh%RotationAcc( fieldIndx,node) + u_delta(n) - - CASE (15) !Module/Mesh/Field: u_BD(1)%RootMotion%TranslationAcc = 15 (k=1) + CASE ( 9) !Module/Mesh/Field: u_HD%Morison%Mesh%TranslationAcc = 9 + u_HD%Morison%Mesh%TranslationAcc(fieldIndx,node) = u_HD%Morison%Mesh%TranslationAcc(fieldIndx,node) + u_delta(n) + CASE (10) !Module/Mesh/Field: u_HD%Morison%Mesh%RotationAcc = 10 + u_HD%Morison%Mesh%RotationAcc( fieldIndx,node) = u_HD%Morison%Mesh%RotationAcc( fieldIndx,node) + u_delta(n) + + CASE (11) !Module/Mesh/Field: u_HD%WAMITMesh%TranslationAcc = 11 + u_HD%WAMITMesh%TranslationAcc( fieldIndx,node) = u_HD%WAMITMesh%TranslationAcc( fieldIndx,node) + u_delta(n) + CASE (12) !Module/Mesh/Field: u_HD%WAMITMesh%RotationAcc = 12 + u_HD%WAMITMesh%RotationAcc( fieldIndx,node) = u_HD%WAMITMesh%RotationAcc( fieldIndx,node) + u_delta(n) + + CASE (13) !Module/Mesh/Field: u_BD(1)%RootMotion%TranslationAcc = 13 (k=1) u_BD(1)%RootMotion%TranslationAcc(fieldIndx,node) = u_BD(1)%RootMotion%TranslationAcc(fieldIndx,node) + u_delta(n) - CASE (16) !Module/Mesh/Field: u_BD(1)%RootMotion%RotationAcc = 16 (k=1) + CASE (14) !Module/Mesh/Field: u_BD(1)%RootMotion%RotationAcc = 14 (k=1) u_BD(1)%RootMotion%RotationAcc( fieldIndx,node) = u_BD(1)%RootMotion%RotationAcc( fieldIndx,node) + u_delta(n) - CASE (17) !Module/Mesh/Field: u_BD(2)%RootMotion%TranslationAcc = 17 (k=2) + CASE (15) !Module/Mesh/Field: u_BD(2)%RootMotion%TranslationAcc = 15 (k=2) u_BD(2)%RootMotion%TranslationAcc(fieldIndx,node) = u_BD(2)%RootMotion%TranslationAcc(fieldIndx,node) + u_delta(n) - CASE (18) !Module/Mesh/Field: u_BD(2)%RootMotion%RotationAcc = 18 (k=2) + CASE (16) !Module/Mesh/Field: u_BD(2)%RootMotion%RotationAcc = 16 (k=2) u_BD(2)%RootMotion%RotationAcc( fieldIndx,node) = u_BD(2)%RootMotion%RotationAcc( fieldIndx,node) + u_delta(n) - CASE (19) !Module/Mesh/Field: u_BD(3)%RootMotion%TranslationAcc = 19 (k=3) + CASE (17) !Module/Mesh/Field: u_BD(3)%RootMotion%TranslationAcc = 17 (k=3) u_BD(3)%RootMotion%TranslationAcc(fieldIndx,node) = u_BD(3)%RootMotion%TranslationAcc(fieldIndx,node) + u_delta(n) - CASE (20) !Module/Mesh/Field: u_BD(3)%RootMotion%RotationAcc = 20 (k=3) + CASE (18) !Module/Mesh/Field: u_BD(3)%RootMotion%RotationAcc = 18 (k=3) u_BD(3)%RootMotion%RotationAcc( fieldIndx,node) = u_BD(3)%RootMotion%RotationAcc( fieldIndx,node) + u_delta(n) - CASE (21) !Module/Mesh/Field: u_Orca%PtfmMesh%TranslationAcc = 21 + CASE (19) !Module/Mesh/Field: u_Orca%PtfmMesh%TranslationAcc = 19 u_Orca%PtfmMesh%TranslationAcc( fieldIndx,node) = u_Orca%PtfmMesh%TranslationAcc( fieldIndx,node) + u_delta(n) - CASE (22) !Module/Mesh/Field: u_Orca%PtfmMesh%RotationAcc = 22 + CASE (20) !Module/Mesh/Field: u_Orca%PtfmMesh%RotationAcc = 20 u_Orca%PtfmMesh%RotationAcc( fieldIndx,node) = u_Orca%PtfmMesh%RotationAcc( fieldIndx,node) + u_delta(n) - CASE (23) !Module/Mesh/Field: u_ExtPtfm%PtfmMesh%TranslationAcc = 23 + CASE (21) !Module/Mesh/Field: u_ExtPtfm%PtfmMesh%TranslationAcc = 21 u_ExtPtfm%PtfmMesh%TranslationAcc( fieldIndx,node) = u_ExtPtfm%PtfmMesh%TranslationAcc( fieldIndx,node) + u_delta(n) - CASE (24) !Module/Mesh/Field: u_ExtPtfm%PtfmMesh%RotationAcc = 24 + CASE (22) !Module/Mesh/Field: u_ExtPtfm%PtfmMesh%RotationAcc = 22 u_ExtPtfm%PtfmMesh%RotationAcc( fieldIndx,node) = u_ExtPtfm%PtfmMesh%RotationAcc( fieldIndx,node) + u_delta(n) END SELECT @@ -3695,55 +3647,50 @@ SUBROUTINE Perturb_u_FullOpt1( p_FAST, Jac_u_indx, n, u_perturb, u_ED_perturb, u perturb = GetPerturb( u_SD_perturb%LMesh%Moment(fieldIndx , node) ) u_SD_perturb%LMesh%Moment(fieldIndx,node) = u_SD_perturb%LMesh%Moment(fieldIndx,node) + perturb * p_FAST%UJacSclFact - CASE ( 9) !Module/Mesh/Field: u_HD%Morison%LumpedMesh%TranslationAcc = 9 - perturb = GetPerturb( u_HD_perturb%Morison%LumpedMesh%TranslationAcc(fieldIndx , node) ) - u_HD_perturb%Morison%LumpedMesh%TranslationAcc(fieldIndx,node) = u_HD_perturb%Morison%LumpedMesh%TranslationAcc(fieldIndx,node) + perturb - CASE ( 10) !Module/Mesh/Field: u_HD%Morison%LumpedMesh%RotationAcc = 10 - perturb = GetPerturb( u_HD_perturb%Morison%LumpedMesh%RotationAcc(fieldIndx , node) ) - u_HD_perturb%Morison%LumpedMesh%RotationAcc( fieldIndx,node) = u_HD_perturb%Morison%LumpedMesh%RotationAcc( fieldIndx,node) + perturb - CASE (11) !Module/Mesh/Field: u_HD%Morison%DistribMesh%TranslationAcc = 11 - perturb = GetPerturb( u_HD_perturb%Morison%DistribMesh%TranslationAcc(fieldIndx , node) ) - u_HD_perturb%Morison%DistribMesh%TranslationAcc(fieldIndx,node) = u_HD_perturb%Morison%DistribMesh%TranslationAcc(fieldIndx,node) + perturb - CASE (12) !Module/Mesh/Field: u_HD%Morison%DistribMesh%RotationAcc = 12 - perturb = GetPerturb( u_HD_perturb%Morison%DistribMesh%RotationAcc(fieldIndx , node) ) - u_HD_perturb%Morison%DistribMesh%RotationAcc( fieldIndx,node) = u_HD_perturb%Morison%DistribMesh%RotationAcc( fieldIndx,node) + perturb - CASE (13) !Module/Mesh/Field: u_HD%Mesh%TranslationAcc = 13 - perturb = GetPerturb( u_HD_perturb%Mesh%TranslationAcc(fieldIndx , node) ) - u_HD_perturb%Mesh%TranslationAcc(fieldIndx,node) = u_HD_perturb%Mesh%TranslationAcc(fieldIndx,node) + perturb - CASE (14) !Module/Mesh/Field: u_HD%Mesh%RotationAcc = 14 - perturb = GetPerturb( u_HD_perturb%Mesh%RotationAcc(fieldIndx , node) ) - u_HD_perturb%Mesh%RotationAcc( fieldIndx,node) = u_HD_perturb%Mesh%RotationAcc( fieldIndx,node) + perturb - - CASE (15) !Module/Mesh/Field: u_BD(1)%RootMotion%TranslationAcc = 15 (k=1) + CASE ( 9) !Module/Mesh/Field: u_HD%Morison%Mesh%TranslationAcc = 9 + perturb = GetPerturb( u_HD_perturb%Morison%Mesh%TranslationAcc(fieldIndx , node) ) + u_HD_perturb%Morison%Mesh%TranslationAcc(fieldIndx,node) = u_HD_perturb%Morison%Mesh%TranslationAcc(fieldIndx,node) + perturb + CASE ( 10) !Module/Mesh/Field: u_HD%Morison%Mesh%RotationAcc = 10 + perturb = GetPerturb( u_HD_perturb%Morison%Mesh%RotationAcc(fieldIndx , node) ) + u_HD_perturb%Morison%Mesh%RotationAcc( fieldIndx,node) = u_HD_perturb%Morison%Mesh%RotationAcc( fieldIndx,node) + perturb + + CASE (11) !Module/Mesh/Field: u_HD%WAMITMesh%TranslationAcc = 11 + perturb = GetPerturb( u_HD_perturb%WAMITMesh%TranslationAcc(fieldIndx , node) ) + u_HD_perturb%WAMITMesh%TranslationAcc(fieldIndx,node) = u_HD_perturb%WAMITMesh%TranslationAcc(fieldIndx,node) + perturb + CASE (12) !Module/Mesh/Field: u_HD%WAMITMesh%RotationAcc = 12 + perturb = GetPerturb( u_HD_perturb%WAMITMesh%RotationAcc(fieldIndx , node) ) + u_HD_perturb%WAMITMesh%RotationAcc( fieldIndx,node) = u_HD_perturb%WAMITMesh%RotationAcc( fieldIndx,node) + perturb + + CASE (13) !Module/Mesh/Field: u_BD(1)%RootMotion%TranslationAcc = 13 (k=1) perturb = GetPerturb( u_BD_perturb%RootMotion%TranslationAcc(fieldIndx , node) ) u_BD_perturb%RootMotion%TranslationAcc(fieldIndx,node) = u_BD_perturb%RootMotion%TranslationAcc(fieldIndx,node) + perturb - CASE (16) !Module/Mesh/Field: u_BD(1)%RootMotion%RotationAcc = 16 (k=1) + CASE (14) !Module/Mesh/Field: u_BD(1)%RootMotion%RotationAcc = 14 (k=1) perturb = GetPerturb( u_BD_perturb%RootMotion%RotationAcc(fieldIndx , node) ) u_BD_perturb%RootMotion%RotationAcc( fieldIndx,node) = u_BD_perturb%RootMotion%RotationAcc( fieldIndx,node) + perturb - CASE (17) !Module/Mesh/Field: u_BD(2)%RootMotion%TranslationAcc = 17 (k=2) + CASE (15) !Module/Mesh/Field: u_BD(2)%RootMotion%TranslationAcc = 15 (k=2) perturb = GetPerturb( u_BD_perturb%RootMotion%TranslationAcc(fieldIndx , node) ) u_BD_perturb%RootMotion%TranslationAcc(fieldIndx,node) = u_BD_perturb%RootMotion%TranslationAcc(fieldIndx,node) + perturb - CASE (18) !Module/Mesh/Field: u_BD(2)%RootMotion%RotationAcc = 18 (k=2) + CASE (16) !Module/Mesh/Field: u_BD(2)%RootMotion%RotationAcc = 16 (k=2) perturb = GetPerturb( u_BD_perturb%RootMotion%RotationAcc(fieldIndx , node) ) u_BD_perturb%RootMotion%RotationAcc( fieldIndx,node) = u_BD_perturb%RootMotion%RotationAcc( fieldIndx,node) + perturb - CASE (19) !Module/Mesh/Field: u_BD(3)%RootMotion%TranslationAcc = 19 (k=3) + CASE (17) !Module/Mesh/Field: u_BD(3)%RootMotion%TranslationAcc = 17 (k=3) perturb = GetPerturb( u_BD_perturb%RootMotion%TranslationAcc(fieldIndx , node) ) u_BD_perturb%RootMotion%TranslationAcc(fieldIndx,node) = u_BD_perturb%RootMotion%TranslationAcc(fieldIndx,node) + perturb - CASE (20) !Module/Mesh/Field: u_BD(3)%RootMotion%RotationAcc = 20 (k=3) + CASE (18) !Module/Mesh/Field: u_BD(3)%RootMotion%RotationAcc = 18 (k=3) perturb = GetPerturb( u_BD_perturb%RootMotion%RotationAcc(fieldIndx , node) ) u_BD_perturb%RootMotion%RotationAcc( fieldIndx,node) = u_BD_perturb%RootMotion%RotationAcc( fieldIndx,node) + perturb - CASE (21) !Module/Mesh/Field: u_Orca%PtfmMesh%TranslationAcc = 21 + CASE (19) !Module/Mesh/Field: u_Orca%PtfmMesh%TranslationAcc = 19 perturb = GetPerturb( u_Orca_perturb%PtfmMesh%TranslationAcc(fieldIndx , node) ) u_Orca_perturb%PtfmMesh%TranslationAcc(fieldIndx,node) = u_Orca_perturb%PtfmMesh%TranslationAcc(fieldIndx,node) + perturb - CASE (22) !Module/Mesh/Field: u_Orca%PtfmMesh%RotationAcc = 22 + CASE (20) !Module/Mesh/Field: u_Orca%PtfmMesh%RotationAcc = 20 perturb = GetPerturb( u_Orca_perturb%PtfmMesh%RotationAcc(fieldIndx , node) ) u_Orca_perturb%PtfmMesh%RotationAcc( fieldIndx,node) = u_Orca_perturb%PtfmMesh%RotationAcc( fieldIndx,node) + perturb - CASE (23) !Module/Mesh/Field: u_ExtPtfm%PtfmMesh%TranslationAcc = 21 + CASE (21) !Module/Mesh/Field: u_ExtPtfm%PtfmMesh%TranslationAcc = 21 perturb = GetPerturb( u_ExtPtfm_perturb%PtfmMesh%TranslationAcc(fieldIndx , node) ) u_ExtPtfm_perturb%PtfmMesh%TranslationAcc(fieldIndx,node) = u_ExtPtfm_perturb%PtfmMesh%TranslationAcc(fieldIndx,node) + perturb - CASE (24) !Module/Mesh/Field: u_ExtPtfm%PtfmMesh%RotationAcc = 22 + CASE (22) !Module/Mesh/Field: u_ExtPtfm%PtfmMesh%RotationAcc = 22 perturb = GetPerturb( u_ExtPtfm_perturb%PtfmMesh%RotationAcc(fieldIndx , node) ) u_ExtPtfm_perturb%PtfmMesh%RotationAcc( fieldIndx,node) = u_ExtPtfm_perturb%PtfmMesh%RotationAcc( fieldIndx,node) + perturb @@ -3866,18 +3813,14 @@ SUBROUTINE ResetRemapFlags(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, MAPp ! HydroDyn IF ( p_FAST%CompHydro == Module_HD ) THEN - IF (HD%Input(1)%Mesh%Committed) THEN - HD%Input(1)%Mesh%RemapFlag = .FALSE. - HD%y%Mesh%RemapFlag = .FALSE. - HD%y%AllHdroOrigin%RemapFlag = .FALSE. - END IF - IF (HD%Input(1)%Morison%LumpedMesh%Committed) THEN - HD%Input(1)%Morison%LumpedMesh%RemapFlag = .FALSE. - HD%y%Morison%LumpedMesh%RemapFlag = .FALSE. + HD%Input(1)%PRPMesh%RemapFlag = .FALSE. + IF (HD%Input(1)%WAMITMesh%Committed) THEN + HD%Input(1)%WAMITMesh%RemapFlag = .FALSE. + HD%y%WAMITMesh%RemapFlag = .FALSE. END IF - IF (HD%Input(1)%Morison%DistribMesh%Committed) THEN - HD%Input(1)%Morison%DistribMesh%RemapFlag = .FALSE. - HD%y%Morison%DistribMesh%RemapFlag = .FALSE. + IF (HD%Input(1)%Morison%Mesh%Committed) THEN + HD%Input(1)%Morison%Mesh%RemapFlag = .FALSE. + HD%y%Morison%Mesh%RemapFlag = .FALSE. END IF END IF @@ -4185,71 +4128,59 @@ SUBROUTINE InitModuleMappings(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, M IF ( p_FAST%CompHydro == Module_HD ) THEN ! HydroDyn-{ElastoDyn or SubDyn} - + + ! Regardless of the offshore configuration, ED platform motions will be mapped to the PRPMesh of HD + ! we're just going to assume PlatformLoads and PlatformMotion are committed + CALL MeshMapCreate( PlatformMotion, HD%Input(1)%PRPMesh, MeshMapData%ED_P_2_HD_PRP_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':ED_P_2_HD_PRP_P' ) !------------------------- ! HydroDyn <-> ElastoDyn !------------------------- - IF ( p_FAST%CompSub /= Module_SD ) THEN ! all of these get mapped to ElastoDyn ! (offshore floating) + IF ( p_FAST%CompSub /= Module_SD ) THEN ! all of these get mapped to ElastoDyn ! (offshore floating with rigid substructure) - ! we're just going to assume PlatformLoads and PlatformMotion are committed - - IF ( HD%y%AllHdroOrigin%Committed ) THEN ! meshes for floating + IF ( HD%y%WAMITMesh%Committed ) THEN ! meshes for floating ! HydroDyn WAMIT point mesh to/from ElastoDyn point mesh - CALL MeshMapCreate( HD%y%AllHdroOrigin, PlatformLoads, MeshMapData%HD_W_P_2_ED_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':HD_W_P_2_Ptfm' ) - CALL MeshMapCreate( PlatformMotion, HD%Input(1)%Mesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Ptfm_2_HD_W_P' ) - END IF - - ! ElastoDyn point mesh HydroDyn Morison point mesh (ED sets inputs, but gets outputs from HD%y%AllHdroOrigin in floating case) - IF ( HD%Input(1)%Morison%LumpedMesh%Committed ) THEN - CALL MeshMapCreate( PlatformMotion, HD%Input(1)%Morison%LumpedMesh, MeshMapData%ED_P_2_HD_M_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Ptfm_2_HD_M_P' ) + CALL MeshMapCreate( HD%y%WAMITMesh, PlatformLoads, MeshMapData%HD_W_P_2_ED_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':HD_W_P_2_ED_P' ) + CALL MeshMapCreate( PlatformMotion, HD%Input(1)%WAMITMesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':ED_P_2_HD_W_P' ) + END IF + + ! ElastoDyn point mesh HydroDyn Morison point mesh (ED sets inputs, but gets outputs from HD%y%WAMITMesh in floating case) + IF ( HD%Input(1)%Morison%Mesh%Committed ) THEN + CALL MeshMapCreate( HD%y%Morison%Mesh, PlatformLoads, MeshMapData%HD_M_P_2_ED_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':HD_M_P_2_ED_P' ) + CALL MeshMapCreate( PlatformMotion, HD%Input(1)%Morison%Mesh, MeshMapData%ED_P_2_HD_M_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':ED_P_2_HD_M_P' ) END IF - - ! ElastoDyn point mesh to HydroDyn Morison line mesh (ED sets inputs, but gets outputs from HD%y%AllHdroOrigin in floating case) - IF ( HD%Input(1)%Morison%DistribMesh%Committed ) THEN - CALL MeshMapCreate( PlatformMotion, HD%Input(1)%Morison%DistribMesh, MeshMapData%ED_P_2_HD_M_L, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Ptfm_2_HD_M_L' ) - END IF - - ELSE ! these get mapped to ElastoDyn AND SubDyn (in ED_SD_HD coupling) ! offshore fixed - - ! HydroDyn WAMIT mesh to ElastoDyn point mesh - IF ( HD%y%Mesh%Committed ) THEN - ! HydroDyn WAMIT point mesh to ElastoDyn point mesh ! meshes for fixed-bottom - CALL MeshMapCreate( HD%y%Mesh, PlatformLoads, MeshMapData%HD_W_P_2_ED_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':HD_W_P_2_Ptfm' ) - CALL MeshMapCreate( PlatformMotion, HD%Input(1)%Mesh, MeshMapData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Ptfm_2_HD_W_P' ) - END IF + ELSE ! these get mapped to ElastoDyn AND SubDyn (in ED_SD_HD coupling) ! offshore with substructure flexibility + + !------------------------- ! HydroDyn <-> SubDyn !------------------------- ! HydroDyn Morison point mesh to SubDyn point mesh - IF ( HD%y%Morison%LumpedMesh%Committed ) THEN + IF ( HD%y%Morison%Mesh%Committed ) THEN - CALL MeshMapCreate( HD%y%Morison%LumpedMesh, SD%Input(1)%LMesh, MeshMapData%HD_M_P_2_SD_P, ErrStat2, ErrMsg2 ) + CALL MeshMapCreate( HD%y%Morison%Mesh, SD%Input(1)%LMesh, MeshMapData%HD_M_P_2_SD_P, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':HD_M_P_2_SD_P' ) - CALL MeshMapCreate( SD%y%y2Mesh, HD%Input(1)%Morison%LumpedMesh, MeshMapData%SD_P_2_HD_M_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':SD_P_2_HD_M_P' ) - + CALL MeshMapCreate( SD%y%y2Mesh, HD%Input(1)%Morison%Mesh, MeshMapData%SD_P_2_HD_M_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':SD_P_2_HD_M_P' ) END IF - - ! HydroDyn Morison line mesh to SubDyn point mesh - IF ( HD%y%Morison%DistribMesh%Committed ) THEN - - CALL MeshMapCreate( HD%y%Morison%DistribMesh, SD%Input(1)%LMesh, MeshMapData%HD_M_L_2_SD_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':HD_M_L_2_SD_P' ) - CALL MeshMapCreate( SD%y%y2Mesh, HD%Input(1)%Morison%DistribMesh, MeshMapData%SD_P_2_HD_M_L, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':SD_P_2_HD_M_L' ) + + ! HydroDyn WAMIT point mesh to SD point mesh + IF ( HD%y%WAMITMesh%Committed ) THEN + + CALL MeshMapCreate( HD%y%WAMITMesh, SD%Input(1)%LMesh, MeshMapData%HD_W_P_2_SD_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':HD_W_P_2_SD_P' ) + CALL MeshMapCreate( SD%y%y2Mesh, HD%Input(1)%WAMITMesh, MeshMapData%SD_P_2_HD_W_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':SD_P_2_HD_W_P' ) - END IF - + END IF END IF ! HydroDyn-SubDyn @@ -4288,39 +4219,71 @@ SUBROUTINE InitModuleMappings(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, M IF ( p_FAST%CompMooring == Module_MAP ) THEN + + IF ( p_FAST%CompSub == Module_SD ) THEN +!------------------------- +! SubDyn <-> MAP +!------------------------- + ! MAP point mesh to/from SubDyn point mesh + CALL MeshMapCreate( MAPp%y%PtFairleadLoad, SD%Input(1)%LMesh, MeshMapData%Mooring_P_2_SD_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Mooring_P_2_SD_P' ) + CALL MeshMapCreate( SD%y%y2Mesh, MAPp%Input(1)%PtFairDisplacement, MeshMapData%SD_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':SD_P_2_Mooring_P' ) + ELSE !------------------------- ! ElastoDyn <-> MAP -!------------------------- +!------------------------- + ! MAP point mesh to/from ElastoDyn point mesh + CALL MeshMapCreate( MAPp%y%PtFairleadLoad, PlatformLoads, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Mooring_P_2_Ptfm' ) + CALL MeshMapCreate( PlatformMotion, MAPp%Input(1)%PtFairDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Ptfm_2_Mooring_P' ) + END IF ! p_FAST%CompSub == Module_SD - ! MAP point mesh to/from ElastoDyn point mesh - CALL MeshMapCreate( MAPp%y%PtFairleadLoad, PlatformLoads, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Mooring_P_2_Ptfm' ) - CALL MeshMapCreate( PlatformMotion, MAPp%Input(1)%PtFairDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Ptfm_2_Mooring_P' ) - ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN + IF ( p_FAST%CompSub == Module_SD ) THEN +!------------------------- +! SubDyn <-> MoorDyn +!------------------------- + ! MoorDyn point mesh to/from SubDyn point mesh + CALL MeshMapCreate( MD%y%PtFairleadLoad, SD%Input(1)%LMesh, MeshMapData%Mooring_P_2_SD_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Mooring_P_2_SD_P' ) + CALL MeshMapCreate( SD%y%y2Mesh, MD%Input(1)%PtFairleadDisplacement, MeshMapData%SD_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':SD_P_2_Mooring_P' ) + ELSE !------------------------- ! ElastoDyn <-> MoorDyn -!------------------------- +!------------------------- + ! MoorDyn point mesh to/from ElastoDyn point mesh + CALL MeshMapCreate( MD%y%PtFairleadLoad, PlatformLoads, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Mooring_P_2_Ptfm' ) + CALL MeshMapCreate( PlatformMotion, MD%Input(1)%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Ptfm_2_Mooring_P' ) + END IF ! p_FAST%CompSub == Module_SD - ! MoorDyn point mesh to/from ElastoDyn point mesh - CALL MeshMapCreate( MD%y%PtFairleadLoad, PlatformLoads, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Mooring_P_2_Ptfm' ) - CALL MeshMapCreate( PlatformMotion, MD%Input(1)%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Ptfm_2_Mooring_P' ) - ELSEIF ( p_FAST%CompMooring == Module_FEAM ) THEN + IF ( p_FAST%CompSub == Module_SD ) THEN +!------------------------- +! SubDyn <-> FEAMooring +!------------------------- + ! FEAMooring point mesh to/from SubDyn point mesh + CALL MeshMapCreate( FEAM%y%PtFairleadLoad, SD%Input(1)%LMesh, MeshMapData%Mooring_P_2_SD_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Mooring_P_2_SD_P' ) + CALL MeshMapCreate( SD%y%y2Mesh, FEAM%Input(1)%PtFairleadDisplacement, MeshMapData%SD_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':SD_P_2_Mooring_P' ) + ELSE !------------------------- ! ElastoDyn <-> FEAMooring -!------------------------- - +!------------------------- ! FEAMooring point mesh to/from ElastoDyn point mesh - CALL MeshMapCreate( FEAM%y%PtFairleadLoad, PlatformLoads, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Mooring_P_2_Ptfm' ) - CALL MeshMapCreate( PlatformMotion, FEAM%Input(1)%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Ptfm_2_Mooring_P' ) - + CALL MeshMapCreate( FEAM%y%PtFairleadLoad, PlatformLoads, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Mooring_P_2_Ptfm' ) + CALL MeshMapCreate( PlatformMotion, FEAM%Input(1)%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Ptfm_2_Mooring_P' ) + END IF ! p_FAST%CompSub == Module_SD + ELSEIF ( p_FAST%CompMooring == Module_Orca ) THEN + !------------------------- ! ElastoDyn <-> OrcaFlex !------------------------- @@ -4381,7 +4344,7 @@ SUBROUTINE InitModuleMappings(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, M !IF ( p_FAST%TurbineType == Type_Offshore_Fixed ) THEN IF ( p_FAST%CompSub /= Module_None .OR. (p_FAST%CompElast == Module_BD .and. BD_Solve_Option1) .or. p_FAST%CompMooring == Module_Orca) THEN !.OR. p_FAST%CompHydro == Module_HD ) THEN CALL Init_FullOpt1_Jacobian( p_FAST, MeshMapData, ED%Input(1)%PlatformPtMesh, SD%Input(1)%TPMesh, SD%Input(1)%LMesh, & - HD%Input(1)%Morison%LumpedMesh, HD%Input(1)%Morison%DistribMesh, HD%Input(1)%Mesh, & + HD%Input(1)%Morison%Mesh, HD%Input(1)%WAMITMesh, & ED%Input(1)%HubPtLoad, BD%Input(1,:), Orca%Input(1)%PtfmMesh, ExtPtfm%Input(1)%PtfmMesh, ErrStat2, ErrMsg2) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF ( p_FAST%CompHydro == Module_HD ) THEN @@ -4462,15 +4425,16 @@ SUBROUTINE InitModuleMappings(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, M END IF IF ( p_FAST%CompHydro == Module_HD ) THEN + + !TODO: GJH Is this needed, I created it as a place holder, 5/11/2020 + !CALL MeshCopy ( HD%Input(1)%PRPMesh, MeshMapData%u_HD_PRP_Mesh, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) + ! CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_HD_PRP_Mesh' ) - CALL MeshCopy ( HD%Input(1)%Mesh, MeshMapData%u_HD_Mesh, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_HD_Mesh' ) + CALL MeshCopy ( HD%Input(1)%WAMITMesh, MeshMapData%u_HD_W_Mesh, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_HD_W_Mesh' ) - CALL MeshCopy ( HD%Input(1)%Morison%LumpedMesh, MeshMapData%u_HD_M_LumpedMesh, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_HD_M_LumpedMesh' ) - - CALL MeshCopy ( HD%Input(1)%Morison%DistribMesh, MeshMapData%u_HD_M_DistribMesh, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_HD_M_DistribMesh' ) + CALL MeshCopy ( HD%Input(1)%Morison%Mesh, MeshMapData%u_HD_M_Mesh, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_HD_M_Mesh' ) END IF @@ -4594,6 +4558,23 @@ SUBROUTINE CalcOutputs_And_SolveForInputs( n_t_global, this_time, this_state, ca Orca%Input(1), BD%Input(1,:), MeshMapData, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF ( p_FAST%CompSub == Module_SD .and. p_FAST%CompHydro == Module_HD ) THEN + CALL SD_CalcOutput( this_time, SD%Input(1), SD%p, SD%x(this_state), SD%xd(this_state), SD%z(this_state), SD%OtherSt(this_state), SD%y, SD%m, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call Transfer_SD_to_HD( SD%y, HD%Input(1)%WAMITMesh, HD%Input(1)%Morison%Mesh, MeshMapData, ErrStat, ErrMsg ) + + IF ( p_FAST%CompMooring == Module_MAP ) THEN + CALL Transfer_Point_to_Point( SD%y%y2Mesh, MAPp%Input(1)%PtFairDisplacement, MeshMapData%SD_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN + CALL Transfer_Point_to_Point( SD%y%y2Mesh, MD%Input(1)%PtFairleadDisplacement, MeshMapData%SD_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + ELSEIF ( p_FAST%CompMooring == Module_FEAM ) THEN + CALL Transfer_Point_to_Point( SD%y%y2Mesh, FEAM%Input(1)%PtFairleadDisplacement, MeshMapData%SD_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + END IF + END IF + !> Solve option 1 (rigorous solve on loads/accelerations) CALL SolveOption1(this_time, this_state, calcJacobian, p_FAST, ED, BD, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2, WriteThisStep) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -4760,7 +4741,7 @@ SUBROUTINE SolveOption1(this_time, this_state, calcJacobian, p_FAST, ED, BD, HD, CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ELSEIF ( p_FAST%CompHydro == Module_HD ) THEN + ELSEIF ( p_FAST%CompHydro == Module_HD ) THEN ! No substructure model CALL ED_HD_InputOutputSolve( this_time, p_FAST, calcJacobian & , ED%Input(1), ED%p, ED%x(this_state), ED%xd(this_state), ED%z(this_state), ED%OtherSt(this_state), ED%y, ED%m & @@ -4774,24 +4755,40 @@ SUBROUTINE SolveOption1(this_time, this_state, calcJacobian, p_FAST, ED, BD, HD, !.................. ! Set mooring line and ice inputs (which don't have acceleration fields) !.................. + IF ( p_FAST%CompMooring == Module_MAP ) THEN - ! note: MAP_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) - CALL MAP_InputSolve( MAPp%Input(1), ED%y, MeshMapData, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! note: MAP_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) + if ( p_FAST%CompSub == Module_SD ) then + CALL Transfer_Point_to_Point( SD%y%y2Mesh, MAPp%Input(1)%PtFairDisplacement, MeshMapData%SD_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + else + CALL Transfer_Point_to_Point( ED%y%PlatformPtMesh, MAPp%Input(1)%PtFairDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + end if ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN - ! note: MD_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) - CALL MD_InputSolve( MD%Input(1), ED%y, MeshMapData, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! note: MD_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) + if ( p_FAST%CompSub == Module_SD ) then + CALL Transfer_Point_to_Point( SD%y%y2Mesh, MD%Input(1)%PtFairleadDisplacement, MeshMapData%SD_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + else + CALL Transfer_Point_to_Point( ED%y%PlatformPtMesh, MD%Input(1)%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + endif ELSEIF ( p_FAST%CompMooring == Module_FEAM ) THEN - ! note: FEAM_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) - CALL FEAM_InputSolve( FEAM%Input(1), ED%y, MeshMapData, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! note: FEAM_InputSolve must be called before setting ED loads inputs (so that motions are known for loads [moment] mapping) + if ( p_FAST%CompSub == Module_SD ) then + CALL Transfer_Point_to_Point( SD%y%y2Mesh, FEAM%Input(1)%PtFairleadDisplacement, MeshMapData%SD_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + else + CALL Transfer_Point_to_Point( ED%y%PlatformPtMesh, FEAM%Input(1)%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + end if END IF @@ -4820,13 +4817,10 @@ SUBROUTINE SolveOption1(this_time, this_state, calcJacobian, p_FAST, ED, BD, HD, 'SD_y2_IceF_Meshes_t'//TRIM(Num2LStr(0))//'.PI.bin' ) - CALL WriteMappingTransferToFile(SD%Input(1)%LMesh, SD%y%Y2Mesh, HD%Input(1)%Morison%LumpedMesh, HD%y%Morison%LumpedMesh,& + CALL WriteMappingTransferToFile(SD%Input(1)%LMesh, SD%y%Y2Mesh, HD%Input(1)%Morison%Mesh, HD%y%Morison%Mesh,& MeshMapData%SD_P_2_HD_M_P, MeshMapData%HD_M_P_2_SD_P, & 'SD_y2_HD_M_L_Meshes_t'//TRIM(Num2LStr(0))//'.PHL.bin' ) - - CALL WriteMappingTransferToFile(SD%Input(1)%LMesh, SD%y%Y2Mesh, HD%Input(1)%Morison%DistribMesh, HD%y%Morison%DistribMesh,& - MeshMapData%SD_P_2_HD_M_L, MeshMapData%HD_M_L_2_SD_P, & - 'SD_y2_HD_M_D_Meshes_t'//TRIM(Num2LStr(0))//'.PHD.bin' ) + !print * @@ -5575,9 +5569,12 @@ SUBROUTINE FAST_ExtrapInterpMods( t_global_next, p_FAST, m_FAST, ED, BD, SrvD, A ErrMsg = "" ! ElastoDyn + !write(*,*) 'ED%Input(1)%PLATFORMPTMESH%Force', ED%Input(1)%PLATFORMPTMESH%Force + !write(*,*) 'ED%Input(2)%PLATFORMPTMESH%Force', ED%Input(2)%PLATFORMPTMESH%Force + !write(*,*) 'ED%Input(3)%PLATFORMPTMESH%Force', ED%Input(3)%PLATFORMPTMESH%Force CALL ED_Input_ExtrapInterp(ED%Input, ED%InputTimes, ED%u, t_global_next, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) - + !write(*,*) 'ED%u%PLATFORMPTMESH%Force', ED%u%PLATFORMPTMESH%Force DO j = p_FAST%InterpOrder, 1, -1 CALL ED_CopyInput (ED%Input(j), ED%Input(j+1), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index 2cbe6cd786..7b59d0e63b 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -801,9 +801,6 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, if (allocated(Init%OutData_HD%LinNames_y)) call move_alloc(Init%OutData_HD%LinNames_y,y_FAST%Lin%Modules(MODULE_HD)%Instance(1)%Names_y ) if (allocated(Init%OutData_HD%LinNames_u)) call move_alloc(Init%OutData_HD%LinNames_u,y_FAST%Lin%Modules(MODULE_HD)%Instance(1)%Names_u ) if (allocated(Init%OutData_HD%LinNames_x)) call move_alloc(Init%OutData_HD%LinNames_x, y_FAST%Lin%Modules(MODULE_HD)%Instance(1)%Names_x ) -! LIN-TODO: Determine if we need to create this data even though we don't have rotating frames in HD - !if (allocated(Init%OutData_HD%RotFrame_y)) call move_alloc(Init%OutData_HD%RotFrame_y,y_FAST%Lin%Modules(MODULE_HD)%Instance(1)%RotFrame_y ) - !if (allocated(Init%OutData_HD%RotFrame_u)) call move_alloc(Init%OutData_HD%RotFrame_u,y_FAST%Lin%Modules(MODULE_HD)%Instance(1)%RotFrame_u ) if (allocated(Init%OutData_HD%DerivOrder_x)) call move_alloc(Init%OutData_HD%DerivOrder_x,y_FAST%Lin%Modules(MODULE_HD)%Instance(1)%DerivOrder_x) if (allocated(Init%OutData_HD%IsLoad_u )) call move_alloc(Init%OutData_HD%IsLoad_u ,y_FAST%Lin%Modules(MODULE_HD)%Instance(1)%IsLoad_u ) @@ -841,12 +838,13 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_SD%WtrDpth = 0.0_ReKi END IF + Init%InData_SD%Linearize = p_FAST%Linearize Init%InData_SD%g = Init%OutData_ED%Gravity - !Init%InData_SD%UseInputFile = .TRUE. + !Ini%tInData_SD%UseInputFile = .TRUE. Init%InData_SD%SDInputFile = p_FAST%SubFile Init%InData_SD%RootName = p_FAST%OutFileRoot - Init%InData_SD%TP_RefPoint = ED%y%PlatformPtMesh%Position(:,1) ! bjj: not sure what this is supposed to be - Init%InData_SD%SubRotateZ = 0.0 ! bjj: not sure what this is supposed to be + Init%InData_SD%TP_RefPoint = ED%y%PlatformPtMesh%Position(:,1) ! "Interface point" where loads will be transferred to + Init%InData_SD%SubRotateZ = 0.0 ! Used by driver to rotate structure around z CALL SD_Init( Init%InData_SD, SD%Input(1), SD%p, SD%x(STATE_CURR), SD%xd(STATE_CURR), SD%z(STATE_CURR), & @@ -856,6 +854,21 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, p_FAST%ModuleInitialized(Module_SD) = .TRUE. CALL SetModuleSubstepTime(Module_SD, p_FAST, y_FAST, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + allocate( y_FAST%Lin%Modules(MODULE_SD)%Instance(1), stat=ErrStat2) + if (ErrStat2 /= 0 ) then + call SetErrStat(ErrID_Fatal, "Error allocating Lin%Modules(SD).", ErrStat, ErrMsg, RoutineName ) + else + if (allocated(Init%OutData_SD%LinNames_y)) call move_alloc(Init%OutData_SD%LinNames_y,y_FAST%Lin%Modules(MODULE_SD)%Instance(1)%Names_y) + if (allocated(Init%OutData_SD%LinNames_x)) call move_alloc(Init%OutData_SD%LinNames_x,y_FAST%Lin%Modules(MODULE_SD)%Instance(1)%Names_x) + if (allocated(Init%OutData_SD%LinNames_u)) call move_alloc(Init%OutData_SD%LinNames_u,y_FAST%Lin%Modules(MODULE_SD)%Instance(1)%Names_u) + if (allocated(Init%OutData_SD%RotFrame_y)) call move_alloc(Init%OutData_SD%RotFrame_y,y_FAST%Lin%Modules(MODULE_SD)%Instance(1)%RotFrame_y) + if (allocated(Init%OutData_SD%RotFrame_x)) call move_alloc(Init%OutData_SD%RotFrame_x,y_FAST%Lin%Modules(MODULE_SD)%Instance(1)%RotFrame_x) + if (allocated(Init%OutData_SD%RotFrame_u)) call move_alloc(Init%OutData_SD%RotFrame_u,y_FAST%Lin%Modules(MODULE_SD)%Instance(1)%RotFrame_u) + if (allocated(Init%OutData_SD%IsLoad_u )) call move_alloc(Init%OutData_SD%IsLoad_u ,y_FAST%Lin%Modules(MODULE_SD)%Instance(1)%IsLoad_u ) + if (allocated(Init%OutData_SD%WriteOutputHdr)) y_FAST%Lin%Modules(MODULE_SD)%Instance(1)%NumOutputs = size(Init%OutData_SD%WriteOutputHdr) + if (allocated(Init%OutData_SD%DerivOrder_x)) call move_alloc(Init%OutData_SD%DerivOrder_x,y_FAST%Lin%Modules(MODULE_SD)%Instance(1)%DerivOrder_x) + end if IF (ErrStat >= AbortErrLev) THEN CALL Cleanup() @@ -889,6 +902,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, if (allocated(Init%OutData_ExtPtfm%RotFrame_u)) call move_alloc(Init%OutData_ExtPtfm%RotFrame_u,y_FAST%Lin%Modules(MODULE_ExtPtfm)%Instance(1)%RotFrame_u) if (allocated(Init%OutData_ExtPtfm%IsLoad_u )) call move_alloc(Init%OutData_ExtPtfm%IsLoad_u ,y_FAST%Lin%Modules(MODULE_ExtPtfm)%Instance(1)%IsLoad_u ) if (allocated(Init%OutData_ExtPtfm%WriteOutputHdr)) y_FAST%Lin%Modules(MODULE_ExtPtfm)%Instance(1)%NumOutputs = size(Init%OutData_ExtPtfm%WriteOutputHdr) + if (allocated(Init%OutData_ExtPtfm%DerivOrder_x)) call move_alloc(Init%OutData_ExtPtfm%DerivOrder_x,y_FAST%Lin%Modules(MODULE_ExtPtfm)%Instance(1)%DerivOrder_x) end if IF (ErrStat >= AbortErrLev) THEN @@ -961,9 +975,6 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, else if (allocated(Init%OutData_MAP%LinInitOut%LinNames_y)) call move_alloc(Init%OutData_MAP%LinInitOut%LinNames_y,y_FAST%Lin%Modules(Module_MAP)%Instance(1)%Names_y ) if (allocated(Init%OutData_MAP%LinInitOut%LinNames_u)) call move_alloc(Init%OutData_MAP%LinInitOut%LinNames_u,y_FAST%Lin%Modules(Module_MAP)%Instance(1)%Names_u ) -! LIN-TODO: Determine if we need to create this data even though we don't have rotating frames in MAP - !if (allocated(Init%OutData_MAP%LinInitOut%RotFrame_y)) call move_alloc(Init%OutData_MAP%LinInitOut%RotFrame_y,y_FAST%Lin%Modules(Module_MAP)%Instance(1)%RotFrame_y ) - !if (allocated(Init%OutData_MAP%LinInitOut%RotFrame_u)) call move_alloc(Init%OutData_MAP%LinInitOut%RotFrame_u,y_FAST%Lin%Modules(Module_MAP)%Instance(1)%RotFrame_u ) if (allocated(Init%OutData_MAP%LinInitOut%IsLoad_u )) call move_alloc(Init%OutData_MAP%LinInitOut%IsLoad_u ,y_FAST%Lin%Modules(Module_MAP)%Instance(1)%IsLoad_u ) if (allocated(Init%OutData_MAP%WriteOutputHdr)) y_FAST%Lin%Modules(Module_MAP)%Instance(1)%NumOutputs = size(Init%OutData_MAP%WriteOutputHdr) @@ -1195,7 +1206,13 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, ! Initialize for linearization: ! ------------------------------------------------------------------------- if ( p_FAST%Linearize ) then - call Init_Lin(p_FAST, y_FAST, m_FAST, AD, ED, Init%OutData_ED%NumBl, ErrStat2, ErrMsg2) + ! NOTE: In the following call, we use Init%OutData_AD%BladeProps(1)%NumBlNds as the number of aero nodes on EACH blade, which + ! is consistent with the current AD implementation, but if AD changes this, then it must be handled here, too! + if (p_FAST%CompAero == MODULE_AD) then + call Init_Lin(p_FAST, y_FAST, m_FAST, AD, ED, Init%OutData_ED%NumBl, Init%OutData_AD%BladeProps(1)%NumBlNds, ErrStat2, ErrMsg2) + else + call Init_Lin(p_FAST, y_FAST, m_FAST, AD, ED, Init%OutData_ED%NumBl, -1, ErrStat2, ErrMsg2) + endif call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat >= AbortErrLev) then @@ -1599,6 +1616,8 @@ SUBROUTINE ValidateInputData(p, m_FAST, ErrStat, ErrMsg) CALL SetErrStat( ErrID_Fatal, 'HydroDyn must be used when MAP is used. Set CompHydro > 0 or CompMooring = 0 in the FAST input file.', ErrStat, ErrMsg, RoutineName ) ELSEIF (p%CompMooring == Module_FEAM) THEN CALL SetErrStat( ErrID_Fatal, 'HydroDyn must be used when FEAMooring is used. Set CompHydro > 0 or CompMooring = 0 in the FAST input file.', ErrStat, ErrMsg, RoutineName ) + ELSEIF (p%CompMooring == Module_MD) THEN + CALL SetErrStat( ErrID_Fatal, 'HydroDyn must be used when MoorDyn is used. Set CompHydro > 0 or CompMooring = 0 in the FAST input file.', ErrStat, ErrMsg, RoutineName ) END IF ELSE IF (p%CompMooring == Module_Orca) CALL SetErrStat( ErrID_Fatal, 'HydroDyn cannot be used if OrcaFlex is used. Set CompHydro = 0 or CompMooring < 4 in the FAST input file.', ErrStat, ErrMsg, RoutineName ) @@ -1682,7 +1701,7 @@ SUBROUTINE ValidateInputData(p, m_FAST, ErrStat, ErrMsg) if (p%CompInflow == MODULE_OpFM) call SetErrStat(ErrID_Fatal,'Linearization is not implemented for the OpenFOAM coupling.',ErrStat, ErrMsg, RoutineName) if (p%CompAero == MODULE_AD14) call SetErrStat(ErrID_Fatal,'Linearization is not implemented for the AeroDyn v14 module.',ErrStat, ErrMsg, RoutineName) !if (p%CompSub == MODULE_SD) call SetErrStat(ErrID_Fatal,'Linearization is not implemented for the SubDyn module.',ErrStat, ErrMsg, RoutineName) - if (p%CompSub /= MODULE_None) call SetErrStat(ErrID_Fatal,'Linearization is not implemented for the any of the substructure modules.',ErrStat, ErrMsg, RoutineName) + if (p%CompSub /= MODULE_None .and. p%CompSub /= MODULE_SD ) call SetErrStat(ErrID_Fatal,'Linearization is not implemented for the ExtPtfm_MCKF substructure module.',ErrStat, ErrMsg, RoutineName) if (p%CompMooring /= MODULE_None .and. p%CompMooring /= MODULE_MAP) call SetErrStat(ErrID_Fatal,'Linearization is not implemented for the FEAMooring or MoorDyn mooring modules.',ErrStat, ErrMsg, RoutineName) if (p%CompIce /= MODULE_None) call SetErrStat(ErrID_Fatal,'Linearization is not implemented for any of the ice loading modules.',ErrStat, ErrMsg, RoutineName) @@ -3167,9 +3186,9 @@ SUBROUTINE SetVTKParameters(p_FAST, InitOutData_ED, InitOutData_AD, InitInData_H ! morison surfaces !....................... - IF ( HD%Input(1)%Morison%DistribMesh%Committed ) THEN - - call move_alloc(InitOutData_HD%Morison%Morison_Rad, p_FAST%VTK_Surface%MorisonRad) + IF ( HD%Input(1)%Morison%Mesh%Committed ) THEN + !TODO: FIX for visualization GJH 4/23/20 + ! call move_alloc(InitOutData_HD%Morison%Morison_Rad, p_FAST%VTK_Surface%MorisonRad) END IF @@ -5149,22 +5168,23 @@ SUBROUTINE WrVTK_AllMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, OpFM, H END IF ! HydroDyn - IF ( p_FAST%CompHydro == Module_HD .and. allocated(HD%Input)) THEN + IF ( p_FAST%CompHydro == Module_HD .and. allocated(HD%Input)) THEN + !TODO: Fix for Visualizaton GJH 4/23/20 !call MeshWrVTK(p_FAST%TurbinePos, HD%Input(1)%Mesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_Mesh_motion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2 ) - !call MeshWrVTK(p_FAST%TurbinePos, HD%Input(1)%Morison%LumpedMesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_MorisonLumped_motion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2 ) - !call MeshWrVTK(p_FAST%TurbinePos, HD%Input(1)%Morison%DistribMesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_MorisonDistrib_motion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2 ) - - if (p_FAST%CompSub == Module_NONE) then - call MeshWrVTK(p_FAST%TurbinePos, HD%y%AllHdroOrigin, trim(p_FAST%VTK_OutFileRoot)//'.HD_AllHdroOrigin', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%Input(1)%Mesh ) - outputFields = .false. - else - call MeshWrVTK(p_FAST%TurbinePos, HD%y%Mesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_Mesh', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%Input(1)%Mesh ) - outputFields = p_FAST%VTK_fields - end if - call MeshWrVTK(p_FAST%TurbinePos, HD%y%Morison%LumpedMesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_MorisonLumped', y_FAST%VTK_count, outputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%Input(1)%Morison%LumpedMesh ) - call MeshWrVTK(p_FAST%TurbinePos, HD%y%Morison%DistribMesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_MorisonDistrib', y_FAST%VTK_count, outputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%Input(1)%Morison%DistribMesh ) - - + call MeshWrVTK(p_FAST%TurbinePos, HD%Input(1)%Morison%Mesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_Morison_Motion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) + + if (HD%y%WamitMesh%Committed) then +! if (p_FAST%CompSub == Module_NONE) then +!TODO call MeshWrVTK(p_FAST%TurbinePos, HD%y%WamitMesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_Mesh', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%Input(1)%WAMITMesh ) +! outputFields = .false. +! else + call MeshWrVTK(p_FAST%TurbinePos, HD%y%WamitMesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_Mesh', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%Input(1)%WAMITMesh ) +! outputFields = p_FAST%VTK_fields +! end if + endif + if (HD%y%Morison%Mesh%Committed) then + call MeshWrVTK(p_FAST%TurbinePos, HD%y%Morison%Mesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_Morison', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%Input(1)%Morison%Mesh ) + endif END IF ! SubDyn @@ -5307,14 +5327,14 @@ SUBROUTINE WrVTK_BasicMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, OpFM, IF ( p_FAST%CompHydro == Module_HD ) THEN if (p_FAST%CompSub == Module_NONE) then - call MeshWrVTK(p_FAST%TurbinePos, HD%y%AllHdroOrigin, trim(p_FAST%VTK_OutFileRoot)//'.HD_AllHdroOrigin', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%Input(1)%Mesh ) + call MeshWrVTK(p_FAST%TurbinePos, HD%y%WAMITMesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_AllHdroOrigin', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%Input(1)%WAMITMesh ) outputFields = .false. else OutputFields = p_FAST%VTK_fields end if - - call MeshWrVTK(p_FAST%TurbinePos, HD%Input(1)%Morison%DistribMesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_MorisonDistrib', & - y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, Sib=HD%y%Morison%DistribMesh ) + !TODO: Fix for Visualization GJH 4/23/20 + call MeshWrVTK(p_FAST%TurbinePos, HD%Input(1)%Morison%Mesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_Morison', & + y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, Sib=HD%y%Morison%Mesh ) END IF @@ -5422,19 +5442,20 @@ SUBROUTINE WrVTK_Surfaces(t_global, p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW ! IF ( p_FAST%CompSub == Module_SD ) THEN ! call MeshWrVTK(p_FAST%TurbinePos, SD%Input(1)%TPMesh, trim(p_FAST%VTK_OutFileRoot)//'.SD_TPMesh_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) ! call MeshWrVTK(p_FAST%TurbinePos, SD%y%y2Mesh, trim(p_FAST%VTK_OutFileRoot)//'.SD_y2Mesh_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) -! END IF - - IF ( HD%Input(1)%Morison%DistribMesh%Committed ) THEN - !if ( p_FAST%CompSub == Module_NONE ) then ! floating - ! OutputFields = .false. - !else - ! OutputFields = p_FAST%VTK_fields - !end if - - call MeshWrVTK_Ln2Surface (p_FAST%TurbinePos, HD%Input(1)%Morison%DistribMesh, trim(p_FAST%VTK_OutFileRoot)//'.MorisonSurface', & - y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, p_FAST%VTK_Surface%NumSectors, & - p_FAST%VTK_Surface%MorisonRad, Sib=HD%y%Morison%DistribMesh ) - END IF +! END IF +!TODO: Fix below section for new Morison GJH 4/23/20 + ! + !IF ( HD%Input(1)%Morison%Mesh%Committed ) THEN + ! !if ( p_FAST%CompSub == Module_NONE ) then ! floating + ! ! OutputFields = .false. + ! !else + ! ! OutputFields = p_FAST%VTK_fields + ! !end if + ! + ! call MeshWrVTK_Ln2Surface (p_FAST%TurbinePos, HD%Input(1)%Morison%Mesh, trim(p_FAST%VTK_OutFileRoot)//'.MorisonSurface', & + ! y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, p_FAST%VTK_Surface%NumSectors, & + ! p_FAST%VTK_Surface%MorisonRad, Sib=HD%y%Morison%Mesh ) + !END IF ! Mooring Lines? @@ -5648,9 +5669,8 @@ SUBROUTINE WriteInputMeshesToFile(u_ED, u_AD, u_SD, u_HD, u_MAP, u_BD, FileName, CALL MeshWrBin( unOut, u_ED%PlatformPtMesh, ErrStat, ErrMsg ) CALL MeshWrBin( unOut, u_SD%TPMesh, ErrStat, ErrMsg ) CALL MeshWrBin( unOut, u_SD%LMesh, ErrStat, ErrMsg ) - CALL MeshWrBin( unOut, u_HD%Morison%distribMesh, ErrStat, ErrMsg ) - CALL MeshWrBin( unOut, u_HD%Morison%lumpedMesh, ErrStat, ErrMsg ) - CALL MeshWrBin( unOut, u_HD%Mesh, ErrStat, ErrMsg ) + CALL MeshWrBin( unOut, u_HD%Morison%Mesh, ErrStat, ErrMsg ) + CALL MeshWrBin( unOut, u_HD%WAMITMesh, ErrStat, ErrMsg ) CALL MeshWrBin( unOut, u_MAP%PtFairDisplacement, ErrStat, ErrMsg ) ! Add how many BD blade meshes there are: NumBl = SIZE(u_BD,1) ! Note that NumBl is B4Ki @@ -5731,9 +5751,8 @@ SUBROUTINE WriteMotionMeshesToFile(time, y_ED, u_SD, y_SD, u_HD, u_MAP, y_BD, u_ CALL MeshWrBin( unOut, y_ED%PlatformPtMesh, ErrStat, ErrMsg ) CALL MeshWrBin( unOut, u_SD%TPMesh, ErrStat, ErrMsg ) CALL MeshWrBin( unOut, y_SD%y2Mesh, ErrStat, ErrMsg ) - CALL MeshWrBin( unOut, u_HD%Morison%distribMesh, ErrStat, ErrMsg ) - CALL MeshWrBin( unOut, u_HD%Morison%lumpedMesh, ErrStat, ErrMsg ) - CALL MeshWrBin( unOut, u_HD%Mesh, ErrStat, ErrMsg ) + CALL MeshWrBin( unOut, u_HD%Morison%Mesh, ErrStat, ErrMsg ) + CALL MeshWrBin( unOut, u_HD%WAMITMesh, ErrStat, ErrMsg ) CALL MeshWrBin( unOut, u_MAP%PtFairDisplacement, ErrStat, ErrMsg ) DO K_local = 1,SIZE(y_BD,1) CALL MeshWrBin( unOut, u_BD(K_local)%RootMotion, ErrStat, ErrMsg ) diff --git a/modules/openfast-library/src/FAST_Types.f90 b/modules/openfast-library/src/FAST_Types.f90 index 5fae280752..60c5d07915 100644 --- a/modules/openfast-library/src/FAST_Types.f90 +++ b/modules/openfast-library/src/FAST_Types.f90 @@ -506,6 +506,8 @@ MODULE FAST_Types TYPE(SD_OutputType) :: y !< System outputs [-] TYPE(SD_MiscVarType) :: m !< Misc/optimization variables [-] TYPE(SD_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< Array of inputs associated with InputTimes [-] + TYPE(SD_OutputType) , DIMENSION(:), ALLOCATABLE :: Output !< Array of outputs associated with CalcSteady Azimuths [-] + TYPE(SD_OutputType) :: y_interp !< interpolated system outputs for CalcSteady [-] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Array of times associated with Input Array [-] END TYPE SubDyn_Data ! ======================= @@ -616,20 +618,21 @@ MODULE FAST_Types TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: ED_P_2_BD_P !< Map ElastoDyn BladeRootMotion meshes to BeamDyn RootMotion point meshes [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: BD_P_2_ED_P !< Map BeamDyn ReactionForce loads point meshes to ElastoDyn HubPtLoad point mesh [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: ED_P_2_BD_P_Hub !< ElastoDyn hub to BeamDyn for hub orientation necessary for pitch actuator [-] + TYPE(MeshMapType) :: ED_P_2_HD_PRP_P !< Map ElastoDyn PlatformPtMesh to HydroDyn platform reference Point [-] TYPE(MeshMapType) :: ED_P_2_HD_W_P !< Map ElastoDyn PlatformPtMesh to HydroDyn WAMIT Point [-] - TYPE(MeshMapType) :: HD_W_P_2_ED_P !< Map HydroDyn WAMIT Point (from either y%Mesh or y%AllHydroOrigin) to ElastoDyn PlatformPtMesh [-] + TYPE(MeshMapType) :: HD_W_P_2_ED_P !< Map HydroDyn WAMIT Point from y%WAMITMesh to ElastoDyn PlatformPtMesh [-] TYPE(MeshMapType) :: ED_P_2_HD_M_P !< Map ElastoDyn PlatformPtMesh to HydroDyn Morison Point [-] TYPE(MeshMapType) :: HD_M_P_2_ED_P !< Map HydroDyn Morison Point to ElastoDyn PlatformPtMesh [-] - TYPE(MeshMapType) :: ED_P_2_HD_M_L !< Map ElastoDyn PlatformPtMesh to HydroDyn Morison Line2 [-] - TYPE(MeshMapType) :: HD_M_L_2_ED_P !< Map HydroDyn Morison Line2 to ElastoDyn PlatformPtMesh [-] TYPE(MeshMapType) :: ED_P_2_Mooring_P !< Map ElastoDyn PlatformPtMesh to MAP/FEAM/MoorDyn/OrcaFlex point mesh [-] TYPE(MeshMapType) :: Mooring_P_2_ED_P !< Map FEAM/MAP/MoorDyn/OrcaFlex point mesh to ElastoDyn PlatformPtMesh [-] + TYPE(MeshMapType) :: SD_P_2_Mooring_P !< Map SD Motions (y2Mesh) to MAP/FEAM/MoorDyn/OrcaFlex point mesh [-] + TYPE(MeshMapType) :: Mooring_P_2_SD_P !< Map FEAM/MAP/MoorDyn/OrcaFlex point mesh to SD point loads (LMesh) mesh [-] TYPE(MeshMapType) :: ED_P_2_SD_TP !< Map ElastoDyn PlatformPtMesh to SubDyn transition-piece point mesh [-] TYPE(MeshMapType) :: SD_TP_2_ED_P !< Map SubDyn transition-piece point mesh to ElastoDyn PlatformPtMesh [-] TYPE(MeshMapType) :: SD_P_2_HD_M_P !< Map SubDyn y2Mesh Point to HydroDyn Morison Point [-] TYPE(MeshMapType) :: HD_M_P_2_SD_P !< Map HydroDyn Morison Point to SubDyn y2Mesh Point [-] - TYPE(MeshMapType) :: SD_P_2_HD_M_L !< Map SubDyn y2Mesh Point to HydroDyn Morison Line2 [-] - TYPE(MeshMapType) :: HD_M_L_2_SD_P !< Map HydroDyn Morison Line2 to SubDyn y2Mesh Point [-] + TYPE(MeshMapType) :: SD_P_2_HD_W_P !< Map SubDyn y2Mesh Point to HydroDyn WAMIT Point [-] + TYPE(MeshMapType) :: HD_W_P_2_SD_P !< Map HydroDyn WAMIT Point to SubDyn y2Mesh Point [-] TYPE(MeshMapType) :: ED_P_2_SrvD_P_N !< Map ElastoDyn Nacelle point mesh to ServoDyn/TMD point mesh [-] TYPE(MeshMapType) :: SrvD_P_2_ED_P_N !< Map ServoDyn nacelle point mesh to ElastoDyn point mesh on the nacelle [-] TYPE(MeshMapType) :: ED_L_2_SrvD_P_T !< Map ElastoDyn tower line2 mesh to ServoDyn/TTMD point mesh [-] @@ -641,9 +644,9 @@ MODULE FAST_Types TYPE(MeshMapType) :: AD_L_2_ED_P_T !< Map AeroDyn14 Twr_InputMarkers or AeroDyn TowerLoad line2 mesh to ElastoDyn TowerPtLoads point mesh [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: ED_P_2_AD_P_R !< Map ElastoDyn BladeRootMotion point meshes to AeroDyn BladeRootMotion point meshes [-] TYPE(MeshMapType) :: ED_P_2_AD_P_H !< Map ElastoDyn HubPtMotion point mesh to AeroDyn HubMotion point mesh [-] - TYPE(MeshMapType) :: IceF_P_2_SD_P !< Map IceFloe point mesh to SubDyn y2Mesh point mesh [-] + TYPE(MeshMapType) :: IceF_P_2_SD_P !< Map IceFloe point mesh to SubDyn LMesh point mesh [-] TYPE(MeshMapType) :: SD_P_2_IceF_P !< Map SubDyn y2Mesh point mesh to IceFloe point mesh [-] - TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: IceD_P_2_SD_P !< Map IceDyn point mesh to SubDyn y2Mesh point mesh [-] + TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: IceD_P_2_SD_P !< Map IceDyn point mesh to SubDyn LMesh point mesh [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: SD_P_2_IceD_P !< Map SubDyn y2Mesh point mesh to IceDyn point mesh [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Jacobian_Opt1 !< Stored Jacobian in ED_HD_InputOutputSolve or FullOpt1_InputOutputSolve [-] INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: Jacobian_pivot !< Pivot array used for LU decomposition of Jacobian_Opt1 [-] @@ -653,9 +656,8 @@ MODULE FAST_Types TYPE(MeshType) :: u_SD_TPMesh !< copy of SD input mesh [-] TYPE(MeshType) :: u_SD_LMesh !< copy of SD input mesh [-] TYPE(MeshType) :: u_SD_LMesh_2 !< copy of SD input mesh (used only for temporary storage) [-] - TYPE(MeshType) :: u_HD_M_LumpedMesh !< copy of HD input mesh [-] - TYPE(MeshType) :: u_HD_M_DistribMesh !< copy of HD input mesh [-] - TYPE(MeshType) :: u_HD_Mesh !< copy of HD input mesh [-] + TYPE(MeshType) :: u_HD_M_Mesh !< copy of HD morison input mesh [-] + TYPE(MeshType) :: u_HD_W_Mesh !< copy of HD wamit input mesh [-] TYPE(MeshType) :: u_ED_HubPtLoad !< copy of ED input mesh [-] TYPE(MeshType) :: u_ED_HubPtLoad_2 !< copy of ED input mesh [-] TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: u_BD_RootMotion !< copy of BD input meshes [-] @@ -26538,6 +26540,25 @@ SUBROUTINE FAST_CopySubDyn_Data( SrcSubDyn_DataData, DstSubDyn_DataData, CtrlCod IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF +IF (ALLOCATED(SrcSubDyn_DataData%Output)) THEN + i1_l = LBOUND(SrcSubDyn_DataData%Output,1) + i1_u = UBOUND(SrcSubDyn_DataData%Output,1) + IF (.NOT. ALLOCATED(DstSubDyn_DataData%Output)) THEN + ALLOCATE(DstSubDyn_DataData%Output(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstSubDyn_DataData%Output.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcSubDyn_DataData%Output,1), UBOUND(SrcSubDyn_DataData%Output,1) + CALL SD_CopyOutput( SrcSubDyn_DataData%Output(i1), DstSubDyn_DataData%Output(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + CALL SD_CopyOutput( SrcSubDyn_DataData%y_interp, DstSubDyn_DataData%y_interp, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN IF (ALLOCATED(SrcSubDyn_DataData%InputTimes)) THEN i1_l = LBOUND(SrcSubDyn_DataData%InputTimes,1) i1_u = UBOUND(SrcSubDyn_DataData%InputTimes,1) @@ -26583,6 +26604,13 @@ SUBROUTINE FAST_DestroySubDyn_Data( SubDyn_DataData, ErrStat, ErrMsg ) ENDDO DEALLOCATE(SubDyn_DataData%Input) ENDIF +IF (ALLOCATED(SubDyn_DataData%Output)) THEN +DO i1 = LBOUND(SubDyn_DataData%Output,1), UBOUND(SubDyn_DataData%Output,1) + CALL SD_DestroyOutput( SubDyn_DataData%Output(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(SubDyn_DataData%Output) +ENDIF + CALL SD_DestroyOutput( SubDyn_DataData%y_interp, ErrStat, ErrMsg ) IF (ALLOCATED(SubDyn_DataData%InputTimes)) THEN DEALLOCATE(SubDyn_DataData%InputTimes) ENDIF @@ -26791,6 +26819,46 @@ SUBROUTINE FAST_PackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! Output allocated yes/no + IF ( ALLOCATED(InData%Output) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Output upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Output,1), UBOUND(InData%Output,1) + Int_BufSz = Int_BufSz + 3 ! Output: size of buffers for each call to pack subtype + CALL SD_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%Output(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Output + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Output + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Output + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Output + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 3 ! y_interp: size of buffers for each call to pack subtype + CALL SD_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_interp, ErrStat2, ErrMsg2, .TRUE. ) ! y_interp + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! y_interp + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! y_interp + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! y_interp + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no IF ( ALLOCATED(InData%InputTimes) ) THEN Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension @@ -27096,6 +27164,75 @@ SUBROUTINE FAST_PackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er ENDIF END DO END IF + IF ( .NOT. ALLOCATED(InData%Output) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Output,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Output,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Output,1), UBOUND(InData%Output,1) + CALL SD_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%Output(i1), ErrStat2, ErrMsg2, OnlySize ) ! Output + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO + END IF + CALL SD_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_interp, ErrStat2, ErrMsg2, OnlySize ) ! y_interp + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF IF ( .NOT. ALLOCATED(InData%InputTimes) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -27532,6 +27669,102 @@ SUBROUTINE FAST_UnPackSubDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Output not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Output)) DEALLOCATE(OutData%Output) + ALLOCATE(OutData%Output(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Output.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Output,1), UBOUND(OutData%Output,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL SD_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%Output(i1), ErrStat2, ErrMsg2 ) ! Output + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL SD_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y_interp, ErrStat2, ErrMsg2 ) ! y_interp + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -35605,6 +35838,9 @@ SUBROUTINE FAST_CopyModuleMapType( SrcModuleMapTypeData, DstModuleMapTypeData, C IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%ED_P_2_HD_PRP_P, DstModuleMapTypeData%ED_P_2_HD_PRP_P, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%ED_P_2_HD_W_P, DstModuleMapTypeData%ED_P_2_HD_W_P, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -35617,16 +35853,16 @@ SUBROUTINE FAST_CopyModuleMapType( SrcModuleMapTypeData, DstModuleMapTypeData, C CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%HD_M_P_2_ED_P, DstModuleMapTypeData%HD_M_P_2_ED_P, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%ED_P_2_HD_M_L, DstModuleMapTypeData%ED_P_2_HD_M_L, CtrlCode, ErrStat2, ErrMsg2 ) + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%ED_P_2_Mooring_P, DstModuleMapTypeData%ED_P_2_Mooring_P, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%HD_M_L_2_ED_P, DstModuleMapTypeData%HD_M_L_2_ED_P, CtrlCode, ErrStat2, ErrMsg2 ) + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%Mooring_P_2_ED_P, DstModuleMapTypeData%Mooring_P_2_ED_P, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%ED_P_2_Mooring_P, DstModuleMapTypeData%ED_P_2_Mooring_P, CtrlCode, ErrStat2, ErrMsg2 ) + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%SD_P_2_Mooring_P, DstModuleMapTypeData%SD_P_2_Mooring_P, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%Mooring_P_2_ED_P, DstModuleMapTypeData%Mooring_P_2_ED_P, CtrlCode, ErrStat2, ErrMsg2 ) + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%Mooring_P_2_SD_P, DstModuleMapTypeData%Mooring_P_2_SD_P, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%ED_P_2_SD_TP, DstModuleMapTypeData%ED_P_2_SD_TP, CtrlCode, ErrStat2, ErrMsg2 ) @@ -35641,10 +35877,10 @@ SUBROUTINE FAST_CopyModuleMapType( SrcModuleMapTypeData, DstModuleMapTypeData, C CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%HD_M_P_2_SD_P, DstModuleMapTypeData%HD_M_P_2_SD_P, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%SD_P_2_HD_M_L, DstModuleMapTypeData%SD_P_2_HD_M_L, CtrlCode, ErrStat2, ErrMsg2 ) + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%SD_P_2_HD_W_P, DstModuleMapTypeData%SD_P_2_HD_W_P, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%HD_M_L_2_SD_P, DstModuleMapTypeData%HD_M_L_2_SD_P, CtrlCode, ErrStat2, ErrMsg2 ) + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%HD_W_P_2_SD_P, DstModuleMapTypeData%HD_W_P_2_SD_P, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%ED_P_2_SrvD_P_N, DstModuleMapTypeData%ED_P_2_SrvD_P_N, CtrlCode, ErrStat2, ErrMsg2 ) @@ -35825,13 +36061,10 @@ SUBROUTINE FAST_CopyModuleMapType( SrcModuleMapTypeData, DstModuleMapTypeData, C CALL MeshCopy( SrcModuleMapTypeData%u_SD_LMesh_2, DstModuleMapTypeData%u_SD_LMesh_2, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL MeshCopy( SrcModuleMapTypeData%u_HD_M_LumpedMesh, DstModuleMapTypeData%u_HD_M_LumpedMesh, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL MeshCopy( SrcModuleMapTypeData%u_HD_M_DistribMesh, DstModuleMapTypeData%u_HD_M_DistribMesh, CtrlCode, ErrStat2, ErrMsg2 ) + CALL MeshCopy( SrcModuleMapTypeData%u_HD_M_Mesh, DstModuleMapTypeData%u_HD_M_Mesh, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL MeshCopy( SrcModuleMapTypeData%u_HD_Mesh, DstModuleMapTypeData%u_HD_Mesh, CtrlCode, ErrStat2, ErrMsg2 ) + CALL MeshCopy( SrcModuleMapTypeData%u_HD_W_Mesh, DstModuleMapTypeData%u_HD_W_Mesh, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN CALL MeshCopy( SrcModuleMapTypeData%u_ED_HubPtLoad, DstModuleMapTypeData%u_ED_HubPtLoad, CtrlCode, ErrStat2, ErrMsg2 ) @@ -35907,20 +36140,21 @@ SUBROUTINE FAST_DestroyModuleMapType( ModuleMapTypeData, ErrStat, ErrMsg ) ENDDO DEALLOCATE(ModuleMapTypeData%ED_P_2_BD_P_Hub) ENDIF + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_HD_PRP_P, ErrStat, ErrMsg ) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_HD_W_P, ErrStat, ErrMsg ) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%HD_W_P_2_ED_P, ErrStat, ErrMsg ) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_HD_M_P, ErrStat, ErrMsg ) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%HD_M_P_2_ED_P, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_HD_M_L, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%HD_M_L_2_ED_P, ErrStat, ErrMsg ) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%Mooring_P_2_ED_P, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SD_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%Mooring_P_2_SD_P, ErrStat, ErrMsg ) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_SD_TP, ErrStat, ErrMsg ) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SD_TP_2_ED_P, ErrStat, ErrMsg ) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SD_P_2_HD_M_P, ErrStat, ErrMsg ) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%HD_M_P_2_SD_P, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SD_P_2_HD_M_L, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%HD_M_L_2_SD_P, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SD_P_2_HD_W_P, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%HD_W_P_2_SD_P, ErrStat, ErrMsg ) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_SrvD_P_N, ErrStat, ErrMsg ) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SrvD_P_2_ED_P_N, ErrStat, ErrMsg ) CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_L_2_SrvD_P_T, ErrStat, ErrMsg ) @@ -35980,9 +36214,8 @@ SUBROUTINE FAST_DestroyModuleMapType( ModuleMapTypeData, ErrStat, ErrMsg ) CALL MeshDestroy( ModuleMapTypeData%u_SD_TPMesh, ErrStat, ErrMsg ) CALL MeshDestroy( ModuleMapTypeData%u_SD_LMesh, ErrStat, ErrMsg ) CALL MeshDestroy( ModuleMapTypeData%u_SD_LMesh_2, ErrStat, ErrMsg ) - CALL MeshDestroy( ModuleMapTypeData%u_HD_M_LumpedMesh, ErrStat, ErrMsg ) - CALL MeshDestroy( ModuleMapTypeData%u_HD_M_DistribMesh, ErrStat, ErrMsg ) - CALL MeshDestroy( ModuleMapTypeData%u_HD_Mesh, ErrStat, ErrMsg ) + CALL MeshDestroy( ModuleMapTypeData%u_HD_M_Mesh, ErrStat, ErrMsg ) + CALL MeshDestroy( ModuleMapTypeData%u_HD_W_Mesh, ErrStat, ErrMsg ) CALL MeshDestroy( ModuleMapTypeData%u_ED_HubPtLoad, ErrStat, ErrMsg ) CALL MeshDestroy( ModuleMapTypeData%u_ED_HubPtLoad_2, ErrStat, ErrMsg ) IF (ALLOCATED(ModuleMapTypeData%u_BD_RootMotion)) THEN @@ -36106,6 +36339,23 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF END DO END IF + Int_BufSz = Int_BufSz + 3 ! ED_P_2_HD_PRP_P: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_HD_PRP_P, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_HD_PRP_P + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_HD_PRP_P + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_HD_PRP_P + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_HD_PRP_P + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF Int_BufSz = Int_BufSz + 3 ! ED_P_2_HD_W_P: size of buffers for each call to pack subtype CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_HD_W_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -36174,71 +36424,71 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! ED_P_2_HD_M_L: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_HD_M_L, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_HD_M_L + Int_BufSz = Int_BufSz + 3 ! ED_P_2_Mooring_P: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_Mooring_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_HD_M_L + IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_Mooring_P Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_HD_M_L + IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_Mooring_P Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_HD_M_L + IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_Mooring_P Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! HD_M_L_2_ED_P: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%HD_M_L_2_ED_P, ErrStat2, ErrMsg2, .TRUE. ) ! HD_M_L_2_ED_P + Int_BufSz = Int_BufSz + 3 ! Mooring_P_2_ED_P: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, .TRUE. ) ! Mooring_P_2_ED_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! HD_M_L_2_ED_P + IF(ALLOCATED(Re_Buf)) THEN ! Mooring_P_2_ED_P Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! HD_M_L_2_ED_P + IF(ALLOCATED(Db_Buf)) THEN ! Mooring_P_2_ED_P Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! HD_M_L_2_ED_P + IF(ALLOCATED(Int_Buf)) THEN ! Mooring_P_2_ED_P Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! ED_P_2_Mooring_P: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_Mooring_P + Int_BufSz = Int_BufSz + 3 ! SD_P_2_Mooring_P: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%SD_P_2_Mooring_P, ErrStat2, ErrMsg2, .TRUE. ) ! SD_P_2_Mooring_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_Mooring_P + IF(ALLOCATED(Re_Buf)) THEN ! SD_P_2_Mooring_P Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_Mooring_P + IF(ALLOCATED(Db_Buf)) THEN ! SD_P_2_Mooring_P Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_Mooring_P + IF(ALLOCATED(Int_Buf)) THEN ! SD_P_2_Mooring_P Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! Mooring_P_2_ED_P: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, .TRUE. ) ! Mooring_P_2_ED_P + Int_BufSz = Int_BufSz + 3 ! Mooring_P_2_SD_P: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%Mooring_P_2_SD_P, ErrStat2, ErrMsg2, .TRUE. ) ! Mooring_P_2_SD_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! Mooring_P_2_ED_P + IF(ALLOCATED(Re_Buf)) THEN ! Mooring_P_2_SD_P Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! Mooring_P_2_ED_P + IF(ALLOCATED(Db_Buf)) THEN ! Mooring_P_2_SD_P Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! Mooring_P_2_ED_P + IF(ALLOCATED(Int_Buf)) THEN ! Mooring_P_2_SD_P Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -36310,37 +36560,37 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! SD_P_2_HD_M_L: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%SD_P_2_HD_M_L, ErrStat2, ErrMsg2, .TRUE. ) ! SD_P_2_HD_M_L + Int_BufSz = Int_BufSz + 3 ! SD_P_2_HD_W_P: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%SD_P_2_HD_W_P, ErrStat2, ErrMsg2, .TRUE. ) ! SD_P_2_HD_W_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! SD_P_2_HD_M_L + IF(ALLOCATED(Re_Buf)) THEN ! SD_P_2_HD_W_P Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! SD_P_2_HD_M_L + IF(ALLOCATED(Db_Buf)) THEN ! SD_P_2_HD_W_P Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! SD_P_2_HD_M_L + IF(ALLOCATED(Int_Buf)) THEN ! SD_P_2_HD_W_P Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! HD_M_L_2_SD_P: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%HD_M_L_2_SD_P, ErrStat2, ErrMsg2, .TRUE. ) ! HD_M_L_2_SD_P + Int_BufSz = Int_BufSz + 3 ! HD_W_P_2_SD_P: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%HD_W_P_2_SD_P, ErrStat2, ErrMsg2, .TRUE. ) ! HD_W_P_2_SD_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! HD_M_L_2_SD_P + IF(ALLOCATED(Re_Buf)) THEN ! HD_W_P_2_SD_P Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! HD_M_L_2_SD_P + IF(ALLOCATED(Db_Buf)) THEN ! HD_W_P_2_SD_P Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! HD_M_L_2_SD_P + IF(ALLOCATED(Int_Buf)) THEN ! HD_W_P_2_SD_P Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -36735,54 +36985,37 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! u_HD_M_LumpedMesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%u_HD_M_LumpedMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! u_HD_M_LumpedMesh + Int_BufSz = Int_BufSz + 3 ! u_HD_M_Mesh: size of buffers for each call to pack subtype + CALL MeshPack( InData%u_HD_M_Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! u_HD_M_Mesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! u_HD_M_LumpedMesh + IF(ALLOCATED(Re_Buf)) THEN ! u_HD_M_Mesh Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! u_HD_M_LumpedMesh + IF(ALLOCATED(Db_Buf)) THEN ! u_HD_M_Mesh Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! u_HD_M_LumpedMesh + IF(ALLOCATED(Int_Buf)) THEN ! u_HD_M_Mesh Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! u_HD_M_DistribMesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%u_HD_M_DistribMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! u_HD_M_DistribMesh + Int_BufSz = Int_BufSz + 3 ! u_HD_W_Mesh: size of buffers for each call to pack subtype + CALL MeshPack( InData%u_HD_W_Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! u_HD_W_Mesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! u_HD_M_DistribMesh + IF(ALLOCATED(Re_Buf)) THEN ! u_HD_W_Mesh Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! u_HD_M_DistribMesh + IF(ALLOCATED(Db_Buf)) THEN ! u_HD_W_Mesh Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! u_HD_M_DistribMesh - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! u_HD_Mesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%u_HD_Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! u_HD_Mesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! u_HD_Mesh - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! u_HD_Mesh - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! u_HD_Mesh + IF(ALLOCATED(Int_Buf)) THEN ! u_HD_W_Mesh Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -37050,6 +37283,34 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ENDIF END DO END IF + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_HD_PRP_P, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_HD_PRP_P + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_HD_W_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -37162,7 +37423,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_HD_M_L, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_HD_M_L + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_Mooring_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -37190,7 +37451,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%HD_M_L_2_ED_P, ErrStat2, ErrMsg2, OnlySize ) ! HD_M_L_2_ED_P + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, OnlySize ) ! Mooring_P_2_ED_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -37218,7 +37479,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_Mooring_P + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%SD_P_2_Mooring_P, ErrStat2, ErrMsg2, OnlySize ) ! SD_P_2_Mooring_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -37246,7 +37507,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, OnlySize ) ! Mooring_P_2_ED_P + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%Mooring_P_2_SD_P, ErrStat2, ErrMsg2, OnlySize ) ! Mooring_P_2_SD_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -37386,7 +37647,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%SD_P_2_HD_M_L, ErrStat2, ErrMsg2, OnlySize ) ! SD_P_2_HD_M_L + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%SD_P_2_HD_W_P, ErrStat2, ErrMsg2, OnlySize ) ! SD_P_2_HD_W_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -37414,7 +37675,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%HD_M_L_2_SD_P, ErrStat2, ErrMsg2, OnlySize ) ! HD_M_L_2_SD_P + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%HD_W_P_2_SD_P, ErrStat2, ErrMsg2, OnlySize ) ! HD_W_P_2_SD_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -38135,7 +38396,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL MeshPack( InData%u_HD_M_LumpedMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! u_HD_M_LumpedMesh + CALL MeshPack( InData%u_HD_M_Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! u_HD_M_Mesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -38163,35 +38424,7 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL MeshPack( InData%u_HD_M_DistribMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! u_HD_M_DistribMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL MeshPack( InData%u_HD_Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! u_HD_Mesh + CALL MeshPack( InData%u_HD_W_Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! u_HD_W_Mesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -38611,6 +38844,46 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_HD_PRP_P, ErrStat2, ErrMsg2 ) ! ED_P_2_HD_PRP_P + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -38804,7 +39077,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_HD_M_L, ErrStat2, ErrMsg2 ) ! ED_P_2_HD_M_L + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) ! ED_P_2_Mooring_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -38844,7 +39117,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%HD_M_L_2_ED_P, ErrStat2, ErrMsg2 ) ! HD_M_L_2_ED_P + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2 ) ! Mooring_P_2_ED_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -38884,7 +39157,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) ! ED_P_2_Mooring_P + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%SD_P_2_Mooring_P, ErrStat2, ErrMsg2 ) ! SD_P_2_Mooring_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -38924,7 +39197,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2 ) ! Mooring_P_2_ED_P + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%Mooring_P_2_SD_P, ErrStat2, ErrMsg2 ) ! Mooring_P_2_SD_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -39124,7 +39397,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%SD_P_2_HD_M_L, ErrStat2, ErrMsg2 ) ! SD_P_2_HD_M_L + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%SD_P_2_HD_W_P, ErrStat2, ErrMsg2 ) ! SD_P_2_HD_W_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -39164,7 +39437,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%HD_M_L_2_SD_P, ErrStat2, ErrMsg2 ) ! HD_M_L_2_SD_P + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%HD_W_P_2_SD_P, ErrStat2, ErrMsg2 ) ! HD_W_P_2_SD_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40164,47 +40437,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL MeshUnpack( OutData%u_HD_M_LumpedMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! u_HD_M_LumpedMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL MeshUnpack( OutData%u_HD_M_DistribMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! u_HD_M_DistribMesh + CALL MeshUnpack( OutData%u_HD_M_Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! u_HD_M_Mesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -40244,7 +40477,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL MeshUnpack( OutData%u_HD_Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! u_HD_Mesh + CALL MeshUnpack( OutData%u_HD_W_Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! u_HD_W_Mesh CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN diff --git a/modules/subdyn/CMakeLists.txt b/modules/subdyn/CMakeLists.txt index fa0fdbc858..8d56cc80f8 100644 --- a/modules/subdyn/CMakeLists.txt +++ b/modules/subdyn/CMakeLists.txt @@ -20,9 +20,13 @@ endif() set(SUBDYN_SOURCES src/SubDyn.f90 + src/FEM.f90 src/SD_FEM.f90 src/SubDyn_Output.f90 - src/qsort_c_module.f90 + src/SubDyn_Output_Params.f90 + src/SubDyn_Tests.f90 + src/IntegerList.f90 + src/Yaml.f90 src/SubDyn_Types.f90 ) diff --git a/modules/subdyn/src/FEM.f90 b/modules/subdyn/src/FEM.f90 new file mode 100644 index 0000000000..2d5972e4d7 --- /dev/null +++ b/modules/subdyn/src/FEM.f90 @@ -0,0 +1,1410 @@ +!.................................................................................................................................. +! LICENSING +! Copyright (C) 2013-2016 National Renewable Energy Laboratory +! +! This file is part of SubDyn. +! +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at +! +! http://www.apache.org/licenses/LICENSE-2.0 +! +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. +!********************************************************************************************************************************** +!> Standalone tools for beam-based finite element method (FEM) +!! No dependency with SubDyn types and representation +MODULE FEM + USE NWTC_Library + IMPLICIT NONE + + INTEGER, PARAMETER :: FEKi = R8Ki ! Define the kind to be used for FEM + INTEGER, PARAMETER :: LaKi = R8Ki ! Define the kind to be used for LaPack + +CONTAINS +!------------------------------------------------------------------------------------------------------ +!> Return eigenvalues, Omega, and eigenvectors + +SUBROUTINE EigenSolve(K, M, N, bCheckSingularity, EigVect, Omega, ErrStat, ErrMsg ) + USE NWTC_LAPACK, only: LAPACK_ggev + INTEGER , INTENT(IN ) :: N !< Number of degrees of freedom, size of M and K + REAL(LaKi), INTENT(INOUT) :: K(N, N) !< Stiffness matrix + REAL(LaKi), INTENT(INOUT) :: M(N, N) !< Mass matrix + LOGICAL, INTENT(IN ) :: bCheckSingularity ! If True, the solver will fail if rigid modes are present + REAL(LaKi), INTENT(INOUT) :: EigVect(N, N) !< Returned Eigenvectors + REAL(LaKi), INTENT(INOUT) :: Omega(N) !< Returned Eigenvalues + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + ! LOCALS + REAL(LaKi), ALLOCATABLE :: WORK (:), VL(:,:), AlphaR(:), AlphaI(:), BETA(:) ! eigensolver variables + INTEGER :: i + INTEGER :: LWORK !variables for the eigensolver + INTEGER, ALLOCATABLE :: KEY(:) + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + REAL(LaKi) :: normA + REAL(LaKi) :: Omega2(N) !< Squared eigenvalues + REAL(LaKi), parameter :: MAX_EIGENVALUE = HUGE(1.0_ReKi) ! To avoid overflow when switching to ReKi + + ErrStat = ErrID_None + ErrMsg = '' + + ! allocate working arrays and return arrays for the eigensolver + LWORK=8*N + 16 !this is what the eigensolver wants >> bjj: +16 because of MKL ?ggev documenation ( "lwork >= max(1, 8n+16) for real flavors"), though LAPACK documenation says 8n is fine + !bjj: there seems to be a memory problem in *GGEV, so I'm making the WORK array larger to see if I can figure it out + CALL AllocAry( Work, LWORK, 'Work', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'EigenSolve') + CALL AllocAry( AlphaR, N, 'AlphaR', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'EigenSolve') + CALL AllocAry( AlphaI, N, 'AlphaI', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'EigenSolve') + CALL AllocAry( Beta, N, 'Beta', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'EigenSolve') + CALL AllocAry( VL, N, N, 'VL', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'EigenSolve') + CALL AllocAry( KEY, N, 'KEY', ErrStat2, ErrMsg2 ); if(Failed()) return + + ! --- Eigenvalue analysis + ! note: SGGEV seems to have memory issues in certain cases. The eigenvalues seem to be okay, but the eigenvectors vary wildly with different compiling options. + ! DGGEV seems to work better, so I'm making these variables LaKi (which is set to R8Ki for now) - bjj 4/25/2014 + ! bjj: This comes from the LAPACK documentation: + ! Note: the quotients AlphaR(j)/BETA(j) and AlphaI(j)/BETA(j) may easily over- or underflow, and BETA(j) may even be zero. + ! Thus, the user should avoid naively computing the ratio Alpha/beta. However, AlphaR and AlphaI will be always less + ! than and usually comparable with norm(A) in magnitude, and BETA always less than and usually comparable with norm(B). + ! Omega2=AlphaR/BETA !Note this may not be correct if AlphaI<>0 and/or BETA=0 TO INCLUDE ERROR CHECK, also they need to be sorted + CALL LAPACK_ggev('N','V',N ,K, M, AlphaR, AlphaI, Beta, VL, EigVect, WORK, LWORK, ErrStat2, ErrMsg2) + if(Failed()) return + + ! --- Determinign and sorting eigen frequencies + Omega2(:) =0.0_LaKi + DO I=1,N !Initialize the key and calculate Omega + KEY(I)=I + Omega2(I) = AlphaR(I)/Beta(I) + if ( EqualRealNos(real(Beta(I),ReKi),0.0_ReKi) ) then + ! --- Beta =0 + if (bCheckSingularity) call WrScr('[WARN] Large eigenvalue found, system may be ill-conditioned') + Omega2(I) = MAX_EIGENVALUE + elseif ( EqualRealNos(real(AlphaI(I),ReKi),0.0_ReKi) ) THEN + ! --- Real Eigenvalues + IF ( AlphaR(I)<0.0_LaKi ) THEN + if ( (AlphaR(I)/Beta(I))<1e-6_LaKi ) then + ! Tolerating very small negative eigenvalues + if (bCheckSingularity) call WrScr('[INFO] Negative eigenvalue found with small norm (system may contain rigid body mode)') + Omega2(I)=0.0_LaKi + else + if (bCheckSingularity) call WrScr('[WARN] Negative eigenvalue found, system may be ill-conditioned.') + Omega2(I)=AlphaR(I)/Beta(I) + endif + else + Omega2(I) = AlphaR(I)/Beta(I) + endif + else + ! --- Complex Eigenvalues + normA = sqrt(AlphaR(I)**2 + AlphaI(I)**2) + if ( (normA/Beta(I))<1e-6_LaKi ) then + ! Tolerating very small eigenvalues with imaginary part + if (bCheckSingularity) call WrScr('[WARN] Complex eigenvalue found with small norm, approximating as 0') + Omega2(I) = 0.0_LaKi + elseif ( abs(AlphaR(I))>1e3_LaKi*abs(AlphaI(I)) ) then + ! Tolerating very small imaginary part compared to real part... (not pretty) + if (bCheckSingularity) call WrScr('[WARN] Complex eigenvalue found with small Im compare to Re') + Omega2(I) = AlphaR(I)/Beta(I) + else + if (bCheckSingularity) call WrScr('[WARN] Complex eigenvalue found with large imaginary value)') + Omega2(I) = MAX_EIGENVALUE + endif + !call Fatal('Complex eigenvalue found, system may be ill-conditioned'); return + endif + ! Capping to avoid overflow + if (Omega2(I)> MAX_EIGENVALUE) then + Omega2(I) = MAX_EIGENVALUE + endif + enddo + + ! Sorting. LASRT has issues for double precision 64 bit on windows + !CALL ScaLAPACK_LASRT('I',N,Omega2,KEY,ErrStat2,ErrMsg2); if(Failed()) return + CALL sort_in_place(Omega2,KEY) + + ! --- Sorting eigen vectors + ! KEEP ME: scaling of the eigenvectors using generalized mass =identity criterion + ! ALLOCATE(normcoeff(N,N), STAT = ErrStat ) + ! result1 = matmul(M,EigVect) + ! result2 = matmul(transpose(EigVect),result1) + ! normcoeff=sqrt(result2) !This should be a diagonal matrix which contains the normalization factors + ! normcoeff=sqrt(matmul(transpose(EigVect),matmul(M,EigVect))) !This should be a diagonal matrix which contains the normalization factors + VL=EigVect !temporary storage for sorting EigVect + DO I=1,N + !EigVect(:,I)=VL(:,KEY(I))/normcoeff(KEY(I),KEY(I)) !reordered and normalized + EigVect(:,I)=VL(:,KEY(I)) !just reordered as Huimin had a normalization outside of this one + ENDDO + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + ! --- Return Omega (capped by huge(ReKi)) and check for singularity + Omega(:) = 0.0_LaKi + do I=1,N + if (EqualRealNos(real(Omega2(I),ReKi), 0.0_ReKi)) then ! NOTE: may be necessary for some corner numerics + Omega(i)=0.0_LaKi + if (bCheckSingularity) then + call Fatal('Zero eigenvalue found, system may contain rigid body mode'); return + endif + elseif (Omega2(I)>0) then + Omega(i)=sqrt(Omega2(I)) + else + ! Negative eigenfrequency + print*,'>>> Wrong eigenfrequency, Omega^2=',Omega2(I) ! <<< This should never happen + Omega(i)= 0.0_LaKi + call Fatal('Negative eigenvalue found, system may be ill-conditioned'); return + endif + enddo + + CALL CleanupEigen() + RETURN + +CONTAINS + LOGICAL FUNCTION Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'EigenSolve') + Failed = ErrStat >= AbortErrLev + if (Failed) call CleanUpEigen() + END FUNCTION Failed + + SUBROUTINE Fatal(ErrMsg_in) + character(len=*), intent(in) :: ErrMsg_in + CALL SetErrStat(ErrID_Fatal, ErrMsg_in, ErrStat, ErrMsg, 'EigenSolve'); + CALL CleanUpEigen() + END SUBROUTINE Fatal + + SUBROUTINE CleanupEigen() + IF (ALLOCATED(Work) ) DEALLOCATE(Work) + IF (ALLOCATED(AlphaR)) DEALLOCATE(AlphaR) + IF (ALLOCATED(AlphaI)) DEALLOCATE(AlphaI) + IF (ALLOCATED(Beta) ) DEALLOCATE(Beta) + IF (ALLOCATED(VL) ) DEALLOCATE(VL) + IF (ALLOCATED(KEY) ) DEALLOCATE(KEY) + END SUBROUTINE CleanupEigen + +END SUBROUTINE EigenSolve + +pure subroutine sort_in_place(a,key) + real(LaKi), intent(inout), dimension(:) :: a + integer(IntKi), intent(inout), dimension(:) :: key + integer(IntKi) :: tempI + real(LaKi) :: temp + integer(IntKi) :: i, j + do i = 2, size(a) + j = i - 1 + temp = a(i) + tempI = key(i) + do while (j>=1 .and. a(j)>temp) + a(j+1) = a(j) + key(j+1) = key(j) + j = j - 1 + if (j<1) then + exit + endif + end do + a(j+1) = temp + key(j+1) = tempI + end do +end subroutine sort_in_place + +!> Compute the determinant of a real matrix using an LU factorization +FUNCTION Determinant(A, ErrStat, ErrMsg) result(det) + use NWTC_LAPACK, only: LAPACK_GETRF + REAL(FEKi), INTENT(IN ) :: A(:, :) !< Input matrix, no side effect + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + real(FEKi) :: det !< May easily overflow + integer(IntKi) :: i + integer :: n + integer, allocatable :: ipiv(:) + real(FEKi), allocatable :: PLU(:,:) + real(FEKi) :: ScaleVal + + n = size(A(1,:)) + allocate(PLU(n,n)) + allocate(ipiv(n)) + ScaleVal= 1.0_FEKi + PLU = A/ScaleVal + ! general matrix factorization: Factor matrix into A=PLU. + call LAPACK_GETRF( n, n, PLU, ipiv, ErrStat, ErrMsg ) !call dgetrf(n, n, PLU, n, ipiv, info) + if (ErrStat==ErrID_Fatal) then + print*,'Error in getrf' + det = 0 + deallocate(PLU) + deallocate(ipiv) + return + endif + ! PLU now contains the LU of the factorization A = PLU + ! As L has unit diagonal entries, the determinant can be computed + ! from the product of U's diagonal entries. Additional sign changes + ! stemming from the permutations P have to be taken into account as well. + det = 1.0_FEKi + do i = 1,n + if(ipiv(i) /= i) then ! additional sign change + det = -det*PLU(i,i) + else + det = det*PLU(i,i) + endif + end do + deallocate(PLU) + deallocate(ipiv) + IF ( EqualRealNos(real(det, ReKi), 0.0_ReKi) ) THEN + print*,'Det is zero' + return + else + det = det*(ScaleVal**n) + endif +END FUNCTION Determinant +!------------------------------------------------------------------------------------------------------ +!> Create a chessboard-like matrix with `valBlack` on the "black" cases, starting with black at (1,1) +!! As a generalization, "black" values may be spaced every `nSpace` squares +!! For instance, blackVal=9, whiteVal=0, nSpace=2 +!! [9 0 0 9 0 0 9] +!! [0 9 0 0 9 0 0] +!! [0 0 9 0 0 9 0] +!! Diagonal values may be overriden by `diagVal` +!! Matrix M does not need to be square +subroutine ChessBoard(M, blackVal, whiteVal, nSpace, diagVal) + real(ReKi), dimension(:,:), intent( out) :: M !< Output matrix + real(ReKi), intent(in ) :: blackVal !< value for black squares + real(ReKi), intent(in ) :: whiteVal !< value for white squre + integer(IntKi), optional, intent(in ) :: nSpace !< spacing between black values, default 1 + real(ReKi), optional, intent(in ) :: diagVal !< Value to override diagonal + integer(IntKi) :: i, j, jFake, n + ! Default value for spacing is 1 if not provided + if (present(nSpace)) then; n=nSpace+1; else; n=2; endif + ! Default values are white values + M(:,:) = whiteVal + ! Setting black values everyother n values + do i=1,size(M,2) + do jFake=1,size(M,2),n ! everyother n values + j = mod(jFake+i-2, size(M,2)) +1 + !print*,'i,j',i,jFake,j + M(i,j) = blackVal + enddo + enddo + ! Forcing diagonal values + if (present(diagVal)) then + do i=1,size(M,1) + do j=1,size(M,2) ! Matrix not necessarily square + if (i==j) M(i,i) = diagVal + enddo + enddo + endif +end subroutine ChessBoard +!------------------------------------------------------------------------------------------------------ +!> Partition matrices and vectors into Boundary (R) and internal (L) nodes +!! M = [ MRR, MRL ] +!! [ sym, MLL ] +!! MRR = M(IDR, IDR), KRR = M(IDR, IDR), FR = F(IDR) +!! MLL = M(IDL, IDL), KRR = K(IDL, IDL), FL = F(IDL) +!! MRL = M(IDR, IDL), KRR = K(IDR, IDL) +!! NOTE: generic code +SUBROUTINE BreakSysMtrx(MM, KK, IDR, IDL, nR, nL, MRR, MLL, MRL, KRR, KLL, KRL, FG, FGR, FGL, CC, CRR, CLL, CRL) + REAL(FEKi), INTENT(IN ) :: MM(:,:) !< Mass Matrix + REAL(FEKi), INTENT(IN ) :: KK(:,:) !< Stiffness matrix + INTEGER(IntKi), INTENT(IN ) :: nR + INTEGER(IntKi), INTENT(IN ) :: nL + INTEGER(IntKi), INTENT(IN ) :: IDR(nR) !< Indices of leader DOFs + INTEGER(IntKi), INTENT(IN ) :: IDL(nL) !< Indices of interior DOFs + REAL(FEKi), INTENT( OUT) :: MRR(nR, nR) + REAL(FEKi), INTENT( OUT) :: MLL(nL, nL) + REAL(FEKi), INTENT( OUT) :: MRL(nR, nL) + REAL(FEKi), INTENT( OUT) :: KRR(nR, nR) + REAL(FEKi), INTENT( OUT) :: KLL(nL, nL) + REAL(FEKi), INTENT( OUT) :: KRL(nR, nL) + REAL(FEKi), OPTIONAL, INTENT(IN ) :: FG(:) !< Force vector + REAL(FEKi), OPTIONAL, INTENT( OUT) :: FGR(nR) + REAL(FEKi), OPTIONAL, INTENT( OUT) :: FGL(nL) + REAL(FEKi), OPTIONAL, INTENT(IN ) :: CC(:,:) !< Stiffness matrix + REAL(FEKi), OPTIONAL, INTENT( OUT) :: CRR(nR, nR) + REAL(FEKi), OPTIONAL, INTENT( OUT) :: CLL(nL, nL) + REAL(FEKi), OPTIONAL, INTENT( OUT) :: CRL(nR, nL) + INTEGER(IntKi) :: I, J, II, JJ + + ! RR: Leader/Boundary DOFs + DO I = 1, nR + II = IDR(I) + DO J = 1, nR + JJ = IDR(J) + MRR(I, J) = MM(II, JJ) + KRR(I, J) = KK(II, JJ) + ENDDO + ENDDO + ! LL: Interior/follower DOFs + DO I = 1, nL + II = IDL(I) + DO J = 1, nL + JJ = IDL(J) + MLL(I, J) = MM(II, JJ) + KLL(I, J) = KK(II, JJ) + ENDDO + ENDDO + ! RL: cross terms + DO I = 1, nR + II = IDR(I) + DO J = 1, nL + JJ = IDL(J) + MRL(I, J) = MM(II, JJ) + KRL(I, J) = KK(II, JJ) + ENDDO + ENDDO + ! Forces + if (present(FG)) then + if (present(FGR)) then + do I = 1, nR + II = IDR(I) + FGR(I) = FG(II) + enddo + endif + if (present(FGL)) then + do I = 1, nL + II = IDL(I) + FGL(I) = FG(II) + enddo + endif + endif + if (present(CC)) then + ! RR: Leader/Boundary DOFs + DO I = 1, nR + II = IDR(I) + DO J = 1, nR + JJ = IDR(J) + CRR(I, J) = CC(II, JJ) + ENDDO + ENDDO + ! LL: Interior/follower DOFs + DO I = 1, nL + II = IDL(I) + DO J = 1, nL + JJ = IDL(J) + CLL(I, J) = CC(II, JJ) + ENDDO + ENDDO + ! RL: cross terms + DO I = 1, nR + II = IDR(I) + DO J = 1, nL + JJ = IDL(J) + CRL(I, J) = CC(II, JJ) + ENDDO + ENDDO + endif +END SUBROUTINE BreakSysMtrx + +!------------------------------------------------------------------------------------------------------ +!> Performs Craig-Bampton reduction of M and K matrices and optional Force vector +!! TODO: (Damping optional) +!! Convention is: +!! "R": leader DOF -> "B": reduced leader DOF +!! "L": interior DOF -> "M": reduced interior DOF (CB-modes) +!! NOTE: +!! - M_MM = Identity and K_MM = Omega*2 hence these matrices are not returned +!! - Possibility to get more CB modes using the input nM_Out>nM +!! +!! NOTE: generic code +SUBROUTINE CraigBamptonReduction(MM, KK, IDR, nR, IDL, nL, nM, nM_Out, MBB, MBM, KBB, PhiL, PhiR, OmegaL, ErrStat, ErrMsg, FG, FGR, FGL, FGB, FGM, CC, CBB, CBM, CMM) + use NWTC_LAPACK, only: LAPACK_GEMV + REAL(FEKi), INTENT(IN ) :: MM(:, :) !< Mass matrix + REAL(FEKi), INTENT(IN ) :: KK(:, :) !< Stiffness matrix + INTEGER(IntKi), INTENT(IN ) :: nR + INTEGER(IntKi), INTENT(IN ) :: IDR(nR) !< Indices of leader DOFs + INTEGER(IntKi), INTENT(IN ) :: nL + INTEGER(IntKi), INTENT(IN ) :: IDL(nL) !< Indices of interior DOFs + INTEGER(IntKi), INTENT(IN ) :: nM !< Number of CB modes + INTEGER(IntKi), INTENT(IN ) :: nM_Out !< Number of modes returned for PhiL & OmegaL + REAL(FEKi), INTENT( OUT) :: MBB( nR, nR) !< Reduced Guyan Mass Matrix + REAL(FEKi), INTENT( OUT) :: KBB( nR, nR) !< Reduced Guyan Stiffness matrix + REAL(FEKi), INTENT( OUT) :: MBM( nR, nM) !< Cross term + REAL(FEKi), INTENT( OUT) :: PhiR(nL, nR) !< Guyan Modes + REAL(FEKi), INTENT( OUT) :: PhiL(nL, nM_out) !< Craig-Bampton modes + REAL(FEKi), INTENT( OUT) :: OmegaL(nM_out) !< Eigenvalues + REAL(FEKi), OPTIONAL, INTENT(IN ) :: FG(:) !< Force vector (typically a constant force, like gravity) + REAL(FEKi), OPTIONAL, INTENT( OUT) :: FGR(nR) !< Force vector partitioned for R DOFs (TODO remove me) + REAL(FEKi), OPTIONAL, INTENT( OUT) :: FGL(nL) !< Force vector partitioned for L DOFs (TODO somehow for Static improvment..) + REAL(FEKi), OPTIONAL, INTENT( OUT) :: FGB(nR) !< Force vector in Guyan modes = FR+PhiR^t FL + REAL(FEKi), OPTIONAL, INTENT( OUT) :: FGM(nM) !< Force vector in CB modes = PhiM^t FL + REAL(FEKi), OPTIONAL, INTENT(IN ) :: CC(:, :) !< Damping matrix + REAL(FEKi), OPTIONAL, INTENT( OUT) :: CBB(nR, nR) !< Guyan Damping matrix + REAL(FEKi), OPTIONAL, INTENT( OUT) :: CBM(nR, nM) !< Coupling Damping matrix + REAL(FEKi), OPTIONAL, INTENT( OUT) :: CMM(nM, nM) !< Craig-Bampton Damping matrix + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'CraigBamptonReduction_FromPartition' + ! Partitioned variables + real(FEKi), allocatable :: MRR(:, :) + real(FEKi), allocatable :: MLL(:, :) + real(FEKi), allocatable :: MRL(:, :) + real(FEKi), allocatable :: KRR(:, :) + real(FEKi), allocatable :: KLL(:, :) + real(FEKi), allocatable :: KRL(:, :) + real(FEKi), allocatable :: CRR(:, :) + real(FEKi), allocatable :: CRL(:, :) + real(FEKi), allocatable :: CLL(:, :) + ! --- Break system + CALL AllocAry(MRR, nR, nR, 'matrix MRR', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry(MLL, nL, nL, 'matrix MLL', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry(MRL, nR, nL, 'matrix MRL', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry(KRR, nR, nR, 'matrix KRR', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry(KLL, nL, nL, 'matrix KLL', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry(KRL, nR, nL, 'matrix KRL', ErrStat2, ErrMsg2 ); if(Failed()) return + if (present(CC)) then + CALL AllocAry(CRR, nR, nR, 'matrix CRR', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry(CLL, nL, nL, 'matrix CLL', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry(CRL, nR, nL, 'matrix CRL', ErrStat2, ErrMsg2 ); if(Failed()) return + endif + call BreakSysMtrx(MM, KK, IDR, IDL, nR, nL, MRR, MLL, MRL, KRR, KLL, KRL, FG=FG, FGR=FGR, FGL=FGL, CC=CC, CRR=CRR, CLL=CLL, CRL=CRL) + ! --- CB reduction + call CraigBamptonReduction_FromPartition( MRR, MLL, MRL, KRR, KLL, KRL, nR, nL, nM, nM_Out,& !< Inputs + MBB, MBM, KBB, PhiL, PhiR, OmegaL, ErrStat2, ErrMsg2, & !< Outputs + CRR=CRR, CLL=CLL, CRL=CRL,& !< Optional inputs + CBB=CBB, CBM=CBM, CMM=CMM) !< Optional Outputs + if(Failed()) return + + ! --- Reduction of force if provided + if (present(FG).and.present(FGR).and.present(FGL)) then + if (present(FGB)) then + !FGB = FGR + matmul( transpose(PhiR), FGL) + if (nL>0) then + CALL LAPACK_GEMV('t', nL , nR, 1.0_FeKi, PhiR, nL, FGL, 1, 0.0_FeKi, FGB, 1 ) + FGB = FGR + FGB + else + FGB = FGR + endif + endif + if (present(FGM)) then + !FGM = matmul( FGL, PhiL(:,1:nM) ) != matmul( transpose(PhiM), FGL ) because FGL is 1-D + if (nM>0) then + CALL LAPACK_GEMV('t', nL , nM, 1.0_FeKi, PhiL(:,1:nM), nL, FGL, 1, 0.0_FeKi, FGM, 1 ) + endif + endif + endif + call CleanUp() + +contains + logical function Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'CraigBamptonReduction') + Failed = ErrStat >= AbortErrLev + if (Failed) call CleanUp() + end function Failed + subroutine CleanUp() + IF(ALLOCATED(MRR) ) DEALLOCATE(MRR) + IF(ALLOCATED(MLL) ) DEALLOCATE(MLL) + IF(ALLOCATED(MRL) ) DEALLOCATE(MRL) + IF(ALLOCATED(KRR) ) DEALLOCATE(KRR) + IF(ALLOCATED(KLL) ) DEALLOCATE(KLL) + IF(ALLOCATED(KRL) ) DEALLOCATE(KRL) + IF(ALLOCATED(CRR) ) DEALLOCATE(CRR) + IF(ALLOCATED(CLL) ) DEALLOCATE(CLL) + IF(ALLOCATED(CRL) ) DEALLOCATE(CRL) + end subroutine +END SUBROUTINE CraigBamptonReduction + +!------------------------------------------------------------------------------------------------------ +!> Performs Craig-Bampton reduction based on partitioned matrices M and K +!! Convention is: +!! "R": leader DOF -> "B": reduced leader DOF +!! "L": interior DOF -> "M": reduced interior DOF (CB-modes) +!! NOTE: +!! - M_MM = Identity and K_MM = Omega*2 hence these matrices are not returned +!! - Possibility to get more CB modes using the input nM_Out>nM (e.g. for static improvement) +!! +!! NOTE: generic code +SUBROUTINE CraigBamptonReduction_FromPartition( MRR, MLL, MRL, KRR, KLL, KRL, nR, nL, nM, nM_Out,& + MBB, MBM, KBB, PhiL, PhiR, OmegaL, ErrStat, ErrMsg,& + CRR, CLL, CRL, CBB, CBM, CMM) + USE NWTC_LAPACK, only: LAPACK_getrs, LAPACK_getrf, LAPACK_gemm + INTEGER(IntKi), INTENT( in) :: nR + INTEGER(IntKi), INTENT( in) :: nL + INTEGER(IntKi), INTENT( in) :: nM_Out + INTEGER(IntKi), INTENT( in) :: nM + REAL(FEKi), INTENT( IN) :: MRR( nR, nR) !< Partitioned mass and stiffness matrices + REAL(FEKi), INTENT( IN) :: MLL( nL, nL) + REAL(FEKi), INTENT( IN) :: MRL( nR, nL) + REAL(FEKi), INTENT( IN) :: KRR( nR, nR) + REAL(FEKi), INTENT(INOUT) :: KLL( nL, nL) ! on exit, it has been factored (otherwise not changed) + REAL(FEKi), INTENT( IN) :: KRL( nR, nL) + REAL(FEKi), INTENT( OUT) :: MBB( nR, nR) + REAL(FEKi), INTENT( OUT) :: MBM( nR, nM) + REAL(FEKi), INTENT( OUT) :: KBB( nR, nR) + REAL(FEKi), INTENT( OUT) :: PhiR(nL, nR) !< Guyan Modes + REAL(FEKi), INTENT( OUT) :: PhiL(nL, nM_Out) !< Craig-Bampton modes + REAL(FEKi), INTENT( OUT) :: OmegaL(nM_Out) !< Eigenvalues + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + REAL(FEKi), OPTIONAL, INTENT( IN) :: CRR( nR, nR) !< Partitioned damping matrices + REAL(FEKi), OPTIONAL, INTENT( IN) :: CLL( nL, nL) + REAL(FEKi), OPTIONAL, INTENT( IN) :: CRL( nR, nL) + REAL(FEKi), OPTIONAL, INTENT( OUT) :: CBB( nR, nR) !< Guyan damping matrix + REAL(FEKi), OPTIONAL, INTENT( OUT) :: CBM( nR, nM) !< Coupling damping matrix + REAL(FEKi), OPTIONAL, INTENT( OUT) :: CMM( nM, nM) !< CB damping matrix + ! LOCAL VARIABLES + REAL(FEKi) , allocatable :: Mu(:, :) ! matrix for normalization Mu(p%nDOFL, p%nDOFL) [bjj: made allocatable to try to avoid stack issues] + REAL(FEKi) , allocatable :: Temp(:, :) ! temp matrix for intermediate steps [bjj: made allocatable to try to avoid stack issues] + REAL(FEKi) , allocatable :: PhiR_T_MLL(:,:) ! PhiR_T_MLL(nR,nL) = transpose of PhiR * MLL (temporary storage) + INTEGER :: I !counter + INTEGER :: ipiv(nL) ! length min(m,n) (See LAPACK documentation) + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'CraigBamptonReduction_FromPartition' + ErrStat = ErrID_None + ErrMsg = '' + + if (nM_out>nL) then + ErrMsg2='Cannot request more modes than internal degrees of Freedom'; ErrStat2=ErrID_Fatal; + if(Failed()) return; + endif + if (nM_out 0 ) then + ! bCheckSingularity = True + CALL EigenSolveWrap(KLL, MLL, nL, nM_out, .True., PhiL(:,1:nM_out), OmegaL(1:nM_out), ErrStat2, ErrMsg2); if(Failed()) return + ! --- Normalize PhiL + ! MU = MATMUL ( MATMUL( TRANSPOSE(PhiL), MLL ), PhiL ) + CALL AllocAry( Temp , nM_out, nL , 'Temp' , ErrStat2 , ErrMsg2); if(Failed()) return + CALL AllocAry( MU , nM_out, nM_out , 'Mu' , ErrStat2 , ErrMsg2); if(Failed()) return + CALL LAPACK_gemm( 'T', 'N', 1.0_FeKi, PhiL, MLL, 0.0_FeKi, Temp , ErrStat2, ErrMsg2); if(Failed()) return + CALL LAPACK_gemm( 'N', 'N', 1.0_FeKi, Temp, PhiL, 0.0_FeKi, MU , ErrStat2, ErrMsg2); if(Failed()) return + DEALLOCATE(Temp) + ! PhiL = MATMUL( PhiL, MU ) ! this is the normalization (MU is diagonal) + DO I = 1, nM_out + PhiL(:,I) = PhiL(:,I) / SQRT( MU(I, I) ) + ENDDO + DEALLOCATE(MU) + if (present(CRR)) then + ! CB damping CMM = PhiL^T CLL PhiL + CALL AllocAry( Temp , nM, nL , 'Temp' , ErrStat2 , ErrMsg2); if(Failed()) return + CALL LAPACK_gemm( 'T', 'N', 1.0_FeKi, PhiL(1:nL, 1:nM), CLL, 0.0_FeKi, Temp , ErrStat2, ErrMsg2); if(Failed()) return + CALL LAPACK_gemm( 'N', 'N', 1.0_FeKi, Temp, PhiL(1:nL, 1:nM), 0.0_FeKi, CMM , ErrStat2, ErrMsg2); if(Failed()) return + DEALLOCATE(Temp) + endif + else + PhiL = 0.0_FEKi + OmegaL = 0.0_FEKi + if (present(CRR)) CMM = 0.0_FEKi + end if + + if (nL>0) then + ! --- Compute Guyan Modes (PhiR) + ! factor KLL to compute PhiR: KLL*PhiR=-TRANSPOSE(KRL) + ! ** note this must be done after EigenSolveWrap() because it modifies KLL ** + CALL LAPACK_getrf( nL, nL, KLL, ipiv, ErrStat2, ErrMsg2); if(Failed()) return + + PhiR = -1.0_FEKi * TRANSPOSE(KRL) !set "b" in Ax=b (solve KLL * PhiR = - TRANSPOSE( KRL ) for PhiR) + CALL LAPACK_getrs( TRANS='N', N=nL, A=KLL, IPIV=ipiv, B=PhiR, ErrStat=ErrStat2, ErrMsg=ErrMsg2); if(Failed()) return + + ! --- Set MBB, MBM, and KBB from Eq. 4: + CALL AllocAry( PhiR_T_MLL, nR, nL, 'PhiR_T_MLL', ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry( Temp , nR, nR, 'Temp' , ErrStat2 , ErrMsg2); if(Failed()) return + + ! PhiR_T_MLL = TRANSPOSE(PhiR) * MLL + CALL LAPACK_gemm( 'T', 'N', 1.0_FeKi, PhiR, MLL, 0.0_FeKi, PhiR_T_MLL , ErrStat2, ErrMsg2); if(Failed()) return + ! MBB1 = MATMUL(MRL, PhiR) + CALL LAPACK_gemm( 'N', 'N', 1.0_FeKi, MRL, PhiR, 0.0_FeKi, MBB , ErrStat2, ErrMsg2); if(Failed()) return + ! MBB2 = MATMUL( PhiR_T_MLL, PhiR ) + CALL LAPACK_gemm( 'N', 'N', 1.0_FeKi, PhiR_T_MLL, PhiR, 0.0_FeKi, Temp , ErrStat2, ErrMsg2); if(Failed()) return + MBB = MRR + MBB + TRANSPOSE( MBB ) + Temp + DEALLOCATE(Temp) + + IF ( nM == 0) THEN + MBM = 0.0_FEKi + ELSE + CALL AllocAry( Temp , nR, nM, 'Temp' , ErrStat2 , ErrMsg2); if(Failed()) return + !MBM = MATMUL( PhiR_T_MLL, PhiL(:,1:nM)) ! last half of operation + CALL LAPACK_gemm( 'N', 'N', 1.0_FeKi, PhiR_T_MLL, PhiL(:,1:nM), 0.0_FeKi, MBM , ErrStat2, ErrMsg2); if(Failed()) return + ! Temp = MATMUL( MRL, PhiL(:,1:nM) ) + CALL LAPACK_gemm( 'N', 'N', 1.0_FeKi, MRL, PhiL(:,1:nM), 0.0_FeKi, Temp , ErrStat2, ErrMsg2); if(Failed()) return + MBM = Temp + MBM !This had PhiM + DEALLOCATE(Temp) + ENDIF + + !KBB = MATMUL(KRL, PhiR) + CALL LAPACK_gemm( 'N', 'N', 1.0_FeKi, KRL, PhiR, 0.0_FeKi, KBB , ErrStat2, ErrMsg2); if(Failed()) return + KBB = KBB + KRR + + if (present(CRR)) then + ! Guyan damping CBB = CRR + (CRL*PhiR) + (CRL*PhiR)^T + PhiR^T*CLL*PhiR + ! PhiR_T_CLL = TRANSPOSE(PhiR) * CLL + CALL AllocAry( Temp , nR, nR, 'Temp' , ErrStat2 , ErrMsg2); if(Failed()) return + CALL LAPACK_gemm( 'T', 'N', 1.0_FeKi, PhiR, MLL, 0.0_FeKi, PhiR_T_MLL , ErrStat2, ErrMsg2); if(Failed()) return + ! CBB = MATMUL(CRL, PhiR) + CALL LAPACK_gemm( 'N', 'N', 1.0_FeKi, CRL, PhiR, 0.0_FeKi, CBB , ErrStat2, ErrMsg2); if(Failed()) return + ! CBB2 = MATMUL( PhiR_T_CLL, PhiR ) + CALL LAPACK_gemm( 'N', 'N', 1.0_FeKi, PhiR_T_MLL, PhiR, 0.0_FeKi, Temp , ErrStat2, ErrMsg2); if(Failed()) return + CBB = CRR + CBB + TRANSPOSE( CBB ) + Temp + DEALLOCATE(Temp) + ! Cross coupling CMB = PhiM^T*CLR + PhiM^T CLL PhiR + ! CBM = CRL*PhiM + PhiR^T CLL^T PhiM (NOTE: assuming CLL symmetric) + IF ( nM == 0) THEN + CBM = 0.0_FEKi + CMM = 0.0_FEKi + ELSE + CBM = MATMUL( PhiR_T_MLL, PhiL(:,1:nM)) ! last half of operation + CBM = MATMUL( CRL, PhiL(:,1:nM) ) + CBM !This had PhiM + ENDIF + endif + else + PhiR(1:nL,1:nR) = 0.0_FEKi ! Empty + MBM (1:nR,1:nM) = 0.0_FEKi ! Empty + MBB = MRR + KBB = KRR + if (present(CRR)) then + CBB=CRR + CBM=0.0_FEKi + endif + endif + + call CleanUp() +CONTAINS + + logical function Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'CraigBamptonReduction_FromPartition') + Failed = ErrStat >= AbortErrLev + if (Failed) call CleanUp() + end function Failed + + subroutine CleanUp() + if (allocated(Mu )) DEALLOCATE(Mu ) + if (allocated(Temp )) DEALLOCATE(Temp ) + if (allocated(PhiR_T_MLL)) DEALLOCATE(PhiR_T_MLL) + end subroutine +END SUBROUTINE CraigBamptonReduction_FromPartition + +!------------------------------------------------------------------------------------------------------ +!> Wrapper function for eigen value analyses, for two cases: +!! Case1: K and M are taken "as is", this is used for the "LL" part of the matrix +!! Case2: K and M contain some constraints lines, and they need to be removed from the Mass/Stiffness matrix. Used for full system +SUBROUTINE EigenSolveWrap(K, M, nDOF, NOmega, bCheckSingularity, EigVect, Omega, ErrStat, ErrMsg, bDOF ) + INTEGER, INTENT(IN ) :: nDOF ! Total degrees of freedom of the incoming system + REAL(FEKi), INTENT(IN ) :: K(nDOF, nDOF) ! stiffness matrix + REAL(FEKi), INTENT(IN ) :: M(nDOF, nDOF) ! mass matrix + INTEGER, INTENT(IN ) :: NOmega ! No. of requested eigenvalues + LOGICAL, INTENT(IN ) :: bCheckSingularity ! If True, the solver will fail if rigid modes are present + REAL(FEKi), INTENT( OUT) :: EigVect(nDOF, NOmega) ! Returned Eigenvectors + REAL(FEKi), INTENT( OUT) :: Omega(NOmega) ! Returned Eigenvalues + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + LOGICAL, OPTIONAL, INTENT(IN ) :: bDOF(nDOF) ! Optinal Mask for DOF to keep (True), or reduce (False) + + ! LOCALS + REAL(LaKi), ALLOCATABLE :: K_LaKi(:,:), M_LaKi(:,:) + REAL(LaKi), ALLOCATABLE :: EigVect_LaKi(:,:), Omega_LaKi(:) + INTEGER(IntKi) :: N + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + ErrStat = ErrID_None + ErrMsg = '' + EigVect=0.0_FeKi + Omega=0.0_FeKi + + ! --- Unfortunate conversion to FEKi... TODO TODO consider storing M and K in FEKi + if (present(bDOF)) then + ! Remove unwanted DOFs + call RemoveDOF(M, bDOF, M_LaKi, ErrStat2, ErrMsg2); if(Failed()) return + call RemoveDOF(K, bDOF, K_LaKi, ErrStat2, ErrMsg2); if(Failed()) return + else + N=size(K,1) + CALL AllocAry(K_LaKi , N, N, 'K_FEKi', ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(M_LaKi , N, N, 'M_FEKi', ErrStat2, ErrMsg2); if(Failed()) return + K_LaKi = real( K, LaKi ) + M_LaKi = real( M, LaKi ) + endif + N=size(K_LaKi,1) + + ! Note: NOmega must be <= N, which is the length of Omega2, Phi! + if ( NOmega > nDOF ) then + CALL SetErrStat(ErrID_Fatal,"NOmega must be less than or equal to N",ErrStat,ErrMsg,'EigenSolveWrap') + CALL CleanupEigen() + return + end if + + ! --- Eigenvalue analysis + CALL AllocAry(EigVect_LAKi, N, N, 'EigVect', ErrStat2, ErrMsg2); if(Failed()) return; + CALL AllocAry(Omega_LaKi, N , 'Omega', ErrStat2, ErrMsg2); if(Failed()) return; ! <<< NOTE: Needed due to dimension of Omega + CALL EigenSolve(K_LaKi, M_LaKi, N, bCheckSingularity, EigVect_LaKi, Omega_LaKi, ErrStat2, ErrMsg2 ); if (Failed()) return; + + Omega(:) = huge(1.0_ReKi) + Omega(1:nOmega) = real(Omega_LaKi(1:nOmega), FEKi) !<<< nOmega= AbortErrLev + if (Failed) call CleanUpEigen() + END FUNCTION Failed + + SUBROUTINE CleanupEigen() + IF (ALLOCATED(Omega_LaKi) ) DEALLOCATE(Omega_LaKi) + IF (ALLOCATED(EigVect_LaKi)) DEALLOCATE(EigVect_LaKi) + IF (ALLOCATED(K_LaKi) ) DEALLOCATE(K_LaKi) + IF (ALLOCATED(M_LaKi) ) DEALLOCATE(M_LaKi) + END SUBROUTINE CleanupEigen + +END SUBROUTINE EigenSolveWrap +!------------------------------------------------------------------------------------------------------ +!> Remove degrees of freedom from a matrix (lines and rows) +SUBROUTINE RemoveDOF(A, bDOF, Ared, ErrStat, ErrMsg ) + REAL(FEKi), INTENT(IN ) :: A(:, :) ! full matrix + logical, INTENT(IN ) :: bDOF(:) ! Array of logical specifying whether a DOF is to be kept(True), or removed (False) + REAL(LaKi),ALLOCATABLE, INTENT( OUT) :: Ared(:,:) ! reduced matrix + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + !locals + INTEGER :: I, J ! counters into full matrix + INTEGER :: Ir, Jr ! counters into reduced matrix + INTEGER :: nr ! number of reduced DOF + ErrStat = ErrID_None + ErrMsg = '' + + nr= count(bDOF) + CALL AllocAry(Ared, nr, nr, 'Ared', ErrStat, ErrMsg ); if (ErrStat >= AbortErrLev) return + + ! Remove rows and columns from A when bDOF is + Jr=0 + do J = 1, size(A,1) + if (bDOF(J)) then + Jr=Jr+1 + Ir=0 + do I = 1, size(A,1) + if (bDOF(I)) then + Ir=Ir+1 + Ared(Ir, Jr) = REAL( A(I, J), FEKi ) + end if + end do + endif + end do +END SUBROUTINE RemoveDOF + +!> Expand a matrix to includes rows where bDOF is False (inverse behavior as RemoveDOF) +SUBROUTINE InsertDOFrows(Ared, bDOF, DefaultVal, A, ErrStat, ErrMsg ) + REAL(LaKi), INTENT(IN ) :: Ared(:, :) ! Reduced matrix + logical, INTENT(IN ) :: bDOF(:) ! Array of logical specifying whether a DOF is to be kept(True), or removed (False) + REAL(FEKi), INTENT(IN ) :: DefaultVal ! Default value to fill the + REAL(FEKi) , INTENT(INOUT) :: A(:,:) ! Full matrix + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + !locals + INTEGER :: I ! counter into full matrix + INTEGER :: Ir ! counter into reduced matrix + INTEGER :: n ! number of DOF (fullsystem) + ErrStat = ErrID_None + ErrMsg = '' + n= size(bDOF) + IF ( size(Ared,1) > n) THEN + ErrStat = ErrID_Fatal + ErrMsg = 'InsertDOFrows: Number of reduced rows needs to be lower than full system rows' + RETURN + END IF + IF ( size(Ared,2) /= size(A,2) ) THEN + ErrStat = ErrID_Fatal + ErrMsg = 'InsertDOFrows: Inconsistent number of columns between A and Ared' + RETURN + END IF + !CALL AllocAry(A, n, size(Ared,2), 'A', ErrStat, ErrMsg ); if (ErrStat >= AbortErrLev) return + + ! Use rows from Ared when bDOF is true, use default value otherwise + ir=0 ! initialize + do i=1,n + if (bDOF(i)) then + ir =ir +1 + A(i,:)=Ared(ir,:) + else + A(i,:)=DefaultVal + endif + enddo +END SUBROUTINE InsertDOFrows +!------------------------------------------------------------------------------------------------------ +!> Returns index of val in Array (val is an integer!) +! NOTE: in the future use intrinsinc function findloc +FUNCTION FINDLOCI_ReKi(Array, Val) result(i) + real(ReKi) , dimension(:), intent(in) :: Array !< Array to search in + integer(IntKi), intent(in) :: val !< Val + integer(IntKi) :: i !< Index of joint in joint table + i = 1 + do while ( i <= size(Array) ) + if ( Val == NINT(Array(i)) ) THEN + return ! Exit when found + else + i = i + 1 + endif + enddo + i=-1 +END FUNCTION +!> Returns index of val in Array (val is an integer!) +! NOTE: in the future use intrinsinc function findloc +FUNCTION FINDLOCI_IntKi(Array, Val) result(i) + integer(IntKi), dimension(:), intent(in) :: Array !< Array to search in + integer(IntKi), intent(in) :: val !< Val + integer(IntKi) :: i !< Index of joint in joint table + i = 1 + do while ( i <= size(Array) ) + if ( Val == Array(i) ) THEN + return ! Exit when found + else + i = i + 1 + endif + enddo + i=-1 +END FUNCTION +!------------------------------------------------------------------------------------------------------ +SUBROUTINE RigidTransformationLine(dx,dy,dz,iLine,Line) + real(ReKi), INTENT(IN) :: dx,dy,dz + integer(IntKi) , INTENT(IN) :: iLine + Real(ReKi), dimension(6), INTENT(OUT) :: Line + SELECT CASE (iLine) + CASE (1); Line = (/1.0_ReKi, 0.0_ReKi, 0.0_ReKi, 0.0_ReKi, dz, -dy/) + CASE (2); Line = (/0.0_ReKi, 1.0_ReKi, 0.0_ReKi, -dz, 0.0_ReKi, dx/) + CASE (3); Line = (/0.0_ReKi, 0.0_ReKi, 1.0_ReKi, dy, -dx, 0.0_ReKi/) + CASE (4); Line = (/0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 1.0_ReKi, 0.0_ReKi, 0.0_ReKi/) + CASE (5); Line = (/0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 1.0_ReKi, 0.0_ReKi/) + CASE (6); Line = (/0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 1.0_ReKi/) + CASE DEFAULT + Line=-99999999_ReKi + print*,'Error in RigidTransformationLine' + STOP +! ErrStat = ErrID_Fatal +! ErrMsg = 'Error calculating transformation matrix TI ' +! return + END SELECT +END SUBROUTINE +!------------------------------------------------------------------------------------------------------ +!> Rigid transformation matrix between DOFs of node j and k where node j is the leader node. +SUBROUTINE GetRigidTransformation(Pj, Pk, TRigid, ErrStat, ErrMsg) + REAL(ReKi), INTENT(IN ) :: Pj(3) ! (x,y,z) positions of leader node + REAL(ReKi), INTENT(IN ) :: Pk(3) ! (x,y,z) positions of follower node + REAL(ReKi), INTENT( OUT) :: TRigid(6,6) ! Transformation matrix such that xk = T.xj + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! Local + !REAL(ReKi) :: L ! length of element + !REAL(ReKi) :: DirCos(3, 3) ! direction cosine matrix + !REAL(ReKi) :: R0(3,3) + integer(IntKi) :: I + ErrStat = ErrID_None + ErrMsg = "" + + ! --- Formulation using Delta of Global coordinates + Trigid=0; do I = 1,6; Trigid(I,I) = 1; enddo + Trigid ( 1, 5 ) = (Pk(3) - Pj(3)) + Trigid ( 1, 6 ) = -(Pk(2) - Pj(2)) + Trigid ( 2, 4 ) = -(Pk(3) - Pj(3)) + Trigid ( 2, 6 ) = (Pk(1) - Pj(1)) + Trigid ( 3, 4 ) = (Pk(2) - Pj(2)) + Trigid ( 3, 5 ) = -(Pk(1) - Pj(1)) + + ! --- Formulation bty transforming the "local" matrix into a global one + !call GetDirCos(Pj, Pk, R0, L, ErrStat, ErrMsg) + !TRigid = 0 ; do I = 1,6; TRigid(I,I) = 1; enddo + !TRigid (1, 5) = L + !TRigid (2, 4) = -L + !TRigid(1:3,4:6) = matmul( R0 , matmul(TRigid(1:3,4:6), transpose(R0)) ) + + ! --- Formulation using L and Rotation matrix + !TRigid = 0; do I = 1,6; TRigid(I,I) = 1; enddo + !TRigid ( 1, 5 ) = L*R0(3,3) + !TRigid ( 1, 6 ) = -L*R0(2,3) + !TRigid ( 2, 4 ) = -L*R0(3,3) + !TRigid ( 2, 6 ) = L*R0(1,3) + !TRigid ( 3, 4 ) = L*R0(2,3) + !TRigid ( 3, 5 ) = -L*R0(1,3) +END SUBROUTINE GetRigidTransformation +!------------------------------------------------------------------------------------------------------ +!> Computes directional cosine matrix DirCos +!! Transforms from element to global coordinates: xg = DC.xe, Kg = DC.Ke.DC^t +!! Assumes that the element main direction is along ze. +!! +!! bjj: note that this is the transpose of what is normally considered the Direction Cosine Matrix +!! in the FAST framework. +SUBROUTINE GetDirCos(P1, P2, DirCos, L_out, ErrStat, ErrMsg) + REAL(ReKi) , INTENT(IN ) :: P1(3), P2(3) ! (x,y,z) global positions of two nodes making up an element + REAL(FEKi) , INTENT( OUT) :: DirCos(3, 3) ! calculated direction cosine matrix + REAL(ReKi) , INTENT( OUT) :: L_out ! length of element + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + REAL(FEKi) :: Dx, Dy, Dz, Dxy,L! distances between nodes + ErrMsg = "" + ErrStat = ErrID_None + + Dx=P2(1)-P1(1) + Dy=P2(2)-P1(2) + Dz=P2(3)-P1(3) + Dxy = sqrt( Dx**2 + Dy**2 ) + L = sqrt( Dx**2 + Dy**2 + Dz**2) + + IF ( EqualRealNos(L, 0.0_FEKi) ) THEN + ErrMsg = ' Same starting and ending location in the element.' + ErrStat = ErrID_Fatal + RETURN + ENDIF + + IF ( EqualRealNos(Dxy, 0.0_FEKi) ) THEN + DirCos=0.0_FEKi ! whole matrix set to 0 + IF ( Dz < 0) THEN !x is kept along global x + DirCos(1, 1) = 1.0_FEKi + DirCos(2, 2) = -1.0_FEKi + DirCos(3, 3) = -1.0_FEKi + ELSE + DirCos(1, 1) = 1.0_ReKi + DirCos(2, 2) = 1.0_ReKi + DirCos(3, 3) = 1.0_ReKi + ENDIF + ELSE + DirCos(1, 1) = Dy/Dxy + DirCos(1, 2) = +Dx*Dz/(L*Dxy) + DirCos(1, 3) = Dx/L + + DirCos(2, 1) = -Dx/Dxy + DirCos(2, 2) = +Dz*Dy/(L*Dxy) + DirCos(2, 3) = Dy/L + + DirCos(3, 1) = 0.0_FEKi + DirCos(3, 2) = -Dxy/L + DirCos(3, 3) = +Dz/L + ENDIF + L_out= real(L, ReKi) + +END SUBROUTINE GetDirCos +!------------------------------------------------------------------------------------------------------ +!> Returns two vectors orthonormal to the input vector +SUBROUTINE GetOrthVectors(e1, e2, e3, ErrStat, ErrMsg) + real(ReKi) , intent(in ) :: e1(3) !< + real(ReKi) , intent( out) :: e2(3) !< + real(ReKi) , intent( out) :: e3(3) !< + integer(IntKi), intent( out) :: ErrStat ! error status of the operation + character(*), intent( out) :: ErrMsg ! error message if errstat /= errid_none + real(ReKi) :: min_norm + real(ReKi) :: e2_norm + real(ReKi) :: e1b(3) + ErrMsg = "" + ErrStat = ErrID_None + + min_norm = min( abs(e1(1)), abs(e1(2)), abs(e1(3)) ) + ! Finding a good candidate for orthogonality + if (min_norm == abs(e1(1))) then; e2 = (/ 0._ReKi, -e1(3), e1(2) /) + else if (min_norm == abs(e1(2))) then; e2 = (/ e1(3) , 0._ReKi, -e1(1) /) + else if (min_norm == abs(e1(3))) then; e2 = (/-e1(2) , e1(1), 0._ReKi /) + endif + ! Normalizing + e2_norm=sqrt(e2(1)**2 + e2(2)**2 + e2(3)**2) + if (abs(e2_norm)<1e-8) then + ErrStat=ErrID_Fatal + ErrMsg='Failed to determine orthogonal vector' + e2=-99999._ReKi + e3=-99999._ReKi + return + endif + e2 = e2/e2_norm + e1b= e1/sqrt(e1(1)**2 + e1(2)**2 + e1(3)**2) + ! Third + e3 = cross_product(e1b,e2) +END SUBROUTINE GetOrthVectors +!------------------------------------------------------------------------------------------------------ +!> Element stiffness matrix for classical beam elements +!! shear is true -- non-tapered Timoshenko beam +!! shear is false -- non-tapered Euler-Bernoulli beam +SUBROUTINE ElemK_Beam(A, L, Ixx, Iyy, Jzz, Shear, kappa, E, G, DirCos, K) + REAL(ReKi), INTENT( IN) :: A, L, Ixx, Iyy, Jzz, E, G, kappa + REAL(FEKi), INTENT( IN) :: DirCos(3,3) !< From element to global: xg = DC.xe, Kg = DC.Ke.DC^t + LOGICAL , INTENT( IN) :: Shear + REAL(FEKi), INTENT(OUT) :: K(12, 12) + ! Local variables + REAL(FEKi) :: Ax, Ay, Kx, Ky + REAL(FEKi) :: DC(12, 12) + + Ax = kappa*A + Ay = kappa*A + + K(1:12,1:12) = 0.0_FEKi + + IF (Shear) THEN + Kx = 12.0_FEKi*E*Iyy / (G*Ax*L*L) + Ky = 12.0_FEKi*E*Ixx / (G*Ay*L*L) + ELSE + Kx = 0.0_FEKi + Ky = 0.0_FEKi + ENDIF + + K( 9, 9) = E*A/L + K( 7, 7) = 12.0_FEKi*E*Iyy/( L*L*L*(1.0_FEKi + Kx) ) + K( 8, 8) = 12.0_FEKi*E*Ixx/( L*L*L*(1.0_FEKi + Ky) ) + K(12, 12) = G*Jzz/L + K(10, 10) = (4.0_FEKi + Ky)*E*Ixx / ( L*(1.0_FEKi+Ky) ) + K(11, 11) = (4.0_FEKi + Kx)*E*Iyy / ( L*(1.0_FEKi+Kx) ) + K( 2, 4) = -6._FEKi*E*Ixx / ( L*L*(1.0_FEKi+Ky) ) + K( 1, 5) = 6._FEKi*E*Iyy / ( L*L*(1.0_FEKi+Kx) ) + K( 4, 10) = (2.0_FEKi-Ky)*E*Ixx / ( L*(1.0_FEKi+Ky) ) + K( 5, 11) = (2.0_FEKi-Kx)*E*Iyy / ( L*(1.0_FEKi+Kx) ) + + K( 3, 3) = K(9,9) + K( 1, 1) = K(7,7) + K( 2, 2) = K(8,8) + K( 6, 6) = K(12,12) + K( 4, 4) = K(10,10) + K(5,5) = K(11,11) + K(4,2) = K(2,4) + K(5,1) = K(1,5) + K(10,4) = K(4,10) + K(11,5) = K(5,11) + K(12,6)= -K(6,6) + K(10,2)= K(4,2) + K(11,1)= K(5,1) + K(9,3) = -K(3,3) + K(7,1) = -K(1,1) + K(8,2) = -K(2,2) + K(6, 12) = -K(6,6) + K(2, 10) = K(4,2) + K(1, 11) = K(5,1) + K(3, 9) = -K(3,3) + K(1, 7) = -K(1,1) + K(2, 8) = -K(2,2) + K(11,7) = -K(5,1) + K(10,8) = -K(4,2) + K(7,11) = -K(5,1) + K(8,10) = -K(4,2) + K(7,5) = -K(5,1) + K(5,7) = -K(5,1) + K(8,4) = -K(4,2) + K(4,8) = -K(4,2) + + DC = 0.0_FEKi + DC( 1: 3, 1: 3) = DirCos + DC( 4: 6, 4: 6) = DirCos + DC( 7: 9, 7: 9) = DirCos + DC(10:12, 10:12) = DirCos + + K = MATMUL( MATMUL(DC, K), TRANSPOSE(DC) ) ! TODO: change me if DirCos convention is transposed + +END SUBROUTINE ElemK_Beam +!------------------------------------------------------------------------------------------------------ +!> Element stiffness matrix for pretension cable +!! Element coordinate system: z along the cable! +SUBROUTINE ElemK_Cable(A, L, E, T0, DirCos, K) + REAL(ReKi), INTENT( IN) :: A, L, E + REAL(ReKi), INTENT( IN) :: T0 ! Pretension [N] + REAL(FEKi), INTENT( IN) :: DirCos(3,3) !< From element to global: xg = DC.xe, Kg = DC.Ke.DC^t + REAL(FEKi), INTENT(OUT) :: K(12, 12) + ! Local variables + REAL(FEKi) :: L0, Eps0, EAL0, EE + REAL(FEKi) :: DC(12, 12) + + Eps0 = T0/(E*A) + L0 = L/(1+Eps0) ! "rest length" for which pretension would be 0 + EAL0 = E*A/L0 + EE = EAL0* Eps0/(1+Eps0) + + K(1:12,1:12)=0.0_FEKi + + ! Note: only translational DOF involved (1-3, 7-9) + K(1,1)= EE + K(2,2)= EE + K(3,3)= EAL0 + + K(1,7)= -EE + K(2,8)= -EE + K(3,9)= -EAL0 + + K(7,1)= -EE + K(8,2)= -EE + K(9,3)= -EAL0 + + K(7,7)= EE + K(8,8)= EE + K(9,9)= EAL0 + + + DC = 0.0_FEKi + DC( 1: 3, 1: 3) = DirCos + DC( 4: 6, 4: 6) = DirCos + DC( 7: 9, 7: 9) = DirCos + DC(10:12, 10:12) = DirCos + + K = MATMUL( MATMUL(DC, K), TRANSPOSE(DC) ) ! TODO: change me if DirCos convention is transposed +END SUBROUTINE ElemK_Cable +!------------------------------------------------------------------------------------------------------ +!> Element mass matrix for classical beam elements +SUBROUTINE ElemM_Beam(A, L, Ixx, Iyy, Jzz, rho, DirCos, M) + REAL(ReKi), INTENT( IN) :: A, L, Ixx, Iyy, Jzz, rho + REAL(FEKi), INTENT( IN) :: DirCos(3,3) !< From element to global: xg = DC.xe, Kg = DC.Ke.DC^t + REAL(FEKi), INTENT(OUT) :: M(12, 12) + + REAL(FEKi) :: t, rx, ry, po + REAL(FEKi) :: DC(12, 12) + + t = rho*A*L; + rx = rho*Ixx; + ry = rho*Iyy; + po = rho*Jzz*L; + + M(1:12,1:12) = 0.0_FEKi + + M( 9, 9) = t/3.0_FEKi + M( 7, 7) = 13.0_FEKi*t/35.0_FEKi + 6.0_FEKi*ry/(5.0_FEKi*L) + M( 8, 8) = 13.0_FEKi*t/35.0_FEKi + 6.0_FEKi*rx/(5.0_FEKi*L) + M(12, 12) = po/3.0_FEKi + M(10, 10) = t*L*L/105.0_FEKi + 2.0_FEKi*L*rx/15.0_FEKi + M(11, 11) = t*L*L/105.0_FEKi + 2.0_FEKi*L*ry/15.0_FEKi + M( 2, 4) = -11.0_FEKi*t*L/210.0_FEKi - rx/10.0_FEKi + M( 1, 5) = 11.0_FEKi*t*L/210.0_FEKi + ry/10.0_FEKi + M( 3, 9) = t/6.0_FEKi + M( 5, 7) = 13._FEKi*t*L/420._FEKi - ry/10._FEKi + M( 4, 8) = -13._FEKi*t*L/420._FEKi + rx/10._FEKi + M( 6, 12) = po/6._FEKi + M( 2, 10) = 13._FEKi*t*L/420._FEKi - rx/10._FEKi + M( 1, 11) = -13._FEKi*t*L/420._FEKi + ry/10._FEKi + M( 8, 10) = 11._FEKi*t*L/210._FEKi + rx/10._FEKi + M( 7, 11) = -11._FEKi*t*L/210._FEKi - ry/10._FEKi + M( 1, 7) = 9._FEKi*t/70._FEKi - 6._FEKi*ry/(5._FEKi*L) + M( 2, 8) = 9._FEKi*t/70._FEKi - 6._FEKi*rx/(5._FEKi*L) + M( 4, 10) = -L*L*t/140._FEKi - rx*L/30._FEKi + M( 5, 11) = -L*L*t/140._FEKi - ry*L/30._FEKi + + M( 3, 3) = M( 9, 9) + M( 1, 1) = M( 7, 7) + M( 2, 2) = M( 8, 8) + M( 6, 6) = M(12, 12) + M( 4, 4) = M(10, 10) + M( 5, 5) = M(11, 11) + M( 4, 2) = M( 2, 4) + M( 5, 1) = M( 1, 5) + M( 9, 3) = M( 3, 9) + M( 7, 5) = M( 5, 7) + M( 8, 4) = M( 4, 8) + M(12, 6) = M( 6, 12) + M(10, 2) = M( 2, 10) + M(11, 1) = M( 1, 11) + M(10, 8) = M( 8, 10) + M(11, 7) = M( 7, 11) + M( 7, 1) = M( 1, 7) + M( 8, 2) = M( 2, 8) + M(10, 4) = M( 4, 10) + M(11, 5) = M( 5, 11) + + DC = 0.0_FEKi + DC( 1: 3, 1: 3) = DirCos + DC( 4: 6, 4: 6) = DirCos + DC( 7: 9, 7: 9) = DirCos + DC(10:12, 10:12) = DirCos + + M = MATMUL( MATMUL(DC, M), TRANSPOSE(DC) ) ! TODO change me if direction cosine is transposed + +END SUBROUTINE ElemM_Beam +!------------------------------------------------------------------------------------------------------ +!> Element stiffness matrix for pretension cable +SUBROUTINE ElemM_Cable(A, L, rho, DirCos, M) + REAL(ReKi), INTENT( IN) :: A,rho + REAL(FEKi), INTENT( IN) :: L + REAL(FEKi), INTENT( IN) :: DirCos(3,3) !< From element to global: xg = DC.xe, Kg = DC.Ke.DC^t + REAL(FEKi), INTENT(OUT) :: M(12, 12) + ! Local variables + REAL(FEKi) :: DC(12, 12) + REAL(FEKi) :: t + + t = rho*A*L; + + M(1:12,1:12) = 0.0_FEKi + + M( 1, 1) = 13._FEKi/35._FEKi * t + M( 2, 2) = 13._FEKi/35._FEKi * t + M( 3, 3) = t/3.0_FEKi + + M( 7, 7) = 13._FEKi/35._FEKi * t + M( 8, 8) = 13._FEKi/35._FEKi * t + M( 9, 9) = t/3.0_FEKi + + M( 1, 7) = 9._FEKi/70._FEKi * t + M( 2, 8) = 9._FEKi/70._FEKi * t + M( 3, 9) = t/6.0_FEKi + + M( 7, 1) = 9._FEKi/70._FEKi * t + M( 8, 2) = 9._FEKi/70._FEKi * t + M( 9, 3) = t/6.0_FEKi + + DC = 0.0_FEKi + DC( 1: 3, 1: 3) = DirCos + DC( 4: 6, 4: 6) = DirCos + DC( 7: 9, 7: 9) = DirCos + DC(10:12, 10:12) = DirCos + + M = MATMUL( MATMUL(DC, M), TRANSPOSE(DC) ) ! TODO: change me if DirCos convention is transposed +END SUBROUTINE ElemM_Cable +!------------------------------------------------------------------------------------------------------ +!> calculates the lumped forces and moments due to gravity on a given element: +!! the element has two nodes, with the loads for both elements stored in array F. Indexing of F is: +!! Fx_n1=1,Fy_n1=2,Fz_n1=3,Mx_n1= 4,My_n1= 5,Mz_n1= 6, +!! Fx_n2=7,Fy_n2=8,Fz_n2=9,Mx_n2=10,My_n2=11,Mz_n2=12 +SUBROUTINE ElemG(A, L, rho, DirCos, F, g) + REAL(ReKi), INTENT( IN ) :: A !< area + REAL(ReKi), INTENT( IN ) :: L !< element length + REAL(ReKi), INTENT( IN ) :: rho !< density + REAL(FEKi), INTENT( IN) :: DirCos(3,3) !< From element to global: xg = DC.xe, Kg = DC.Ke.DC^t + REAL(ReKi), INTENT( IN ) :: g !< gravity + REAL(FEKi), INTENT( OUT) :: F(12) !< returned loads. positions 1-6 are the loads for node 1 ; 7-12 are loads for node 2. + REAL(FEKi) :: TempCoeff + REAL(FEKi) :: w ! weight per unit length + + F = 0.0_FEKi ! initialize whole array to zero, then set the non-zero portions + w = rho*A*g ! weight per unit length + + ! lumped forces on both nodes (z component only): + F(3) = -0.5_FEKi*L*w + F(9) = F(3) + + ! lumped moments on node 1 (x and y components only): + ! bjj: note that RRD wants factor of 1/12 because of boundary conditions. Our MeshMapping routines use factor of 1/6 (assuming generic/different boundary + ! conditions), so we may have some inconsistent behavior. JMJ suggests using line2 elements for SubDyn's input/output meshes to improve the situation. + TempCoeff = L*L*w/12.0_FEKi ! let's not calculate this twice + F(4) = -TempCoeff * DirCos(2,3) ! = -L*w*Dy/12._FEKi !bjj: DirCos(2,3) = Dy/L + F(5) = TempCoeff * DirCos(1,3) ! = L*w*Dx/12._FEKi !bjj: DirCos(1,3) = Dx/L + + ! lumped moments on node 2: (note the opposite sign of node 1 moment) + F(10) = -F(4) + F(11) = -F(5) + !F(12) is 0 for g along z alone + +END SUBROUTINE ElemG +!------------------------------------------------------------------------------------------------------ +!> +SUBROUTINE ElemF_Cable(T0, DirCos, F) + REAL(ReKi), INTENT( IN ) :: T0 !< Pretension load [N] + REAL(FEKi), INTENT( IN) :: DirCos(3,3) !< From element to global: xg = DC.xe, Kg = DC.Ke.DC^t + REAL(FEKi), INTENT( OUT) :: F(12) !< returned loads. 1-6 for node 1; 7-12 for node 2. + ! Local variables + REAL(FEKi) :: DC(12, 12) + + F(1:12) = 0.0_FEKi ! init + F(3) = +T0 + F(9) = -T0 + + DC = 0.0_FEKi + DC( 1: 3, 1: 3) = DirCos + DC( 4: 6, 4: 6) = DirCos + DC( 7: 9, 7: 9) = DirCos + DC(10:12, 10:12) = DirCos + + F = MATMUL(DC, F)! TODO: change me if DirCos convention is transposed + +END SUBROUTINE ElemF_Cable +!------------------------------------------------------------------------------------------------------ +!> Calculates the lumped gravity forces at the nodes given the element geometry +!! It assumes a linear variation of the dimensions from node 1 to node 2, thus the area may be quadratically varying if crat<>1 +!! bjj: note this routine is a work in progress, intended for future version of SubDyn. Compare with ElemG. +SUBROUTINE LumpForces(Area1,Area2,crat,L,rho, g, DirCos, F) + REAL(ReKi), INTENT( IN ) :: Area1,Area2,crat !< X-sectional areas at node 1 and node 2, t2/t1 thickness ratio + REAL(ReKi), INTENT( IN ) :: g !< gravity + REAL(ReKi), INTENT( IN ) :: L !< Length of element + REAL(ReKi), INTENT( IN ) :: rho !< density + REAL(ReKi), INTENT( IN) :: DirCos(3,3) !< From element to global: xg = DC.xe, Kg = DC.Ke.DC^t + REAL(ReKi), INTENT( OUT) :: F(12) !< Lumped forces + !LOCALS + REAL(ReKi) :: TempCoeff,a0,a1,a2 !coefficients of the gravity quadratically distributed force + + !Calculate quadratic polynomial coefficients + a0 = a1 + print*,'Error: the function lumpforces is not ready to use' + STOP + + !Calculate quadratic polynomial coefficients + a0 = -99999 ! TODO: this is wrong + a2 = ( (Area1+A2) - (Area1*crat+Area2/crat) )/L**2. ! *x**2 + a1 = (Area2-Area1)/L -a2*L ! *x + + !Now calculate the Lumped Forces + F = 0 + F(3) = -(a0*L/2. +a1*L**2/6. +a2*L**3/12. )*rho*g !Forces along z (must be negative on earth) + F(9) = -(a0*L/2. +a1*L**2/3. +a2*L**3/4. )*rho*g !Forces along z (must be negative on earth) + + !Now calculate the Lumped Moments + !HERE TO BE COMPLETED FOR THE BELOW + TempCoeff = 1.0/12.0*g*L*L*rho*Area2 !RRD : I am changing this to >0 sign 6/10/13 + + !F(4) = TempCoeff*( DirCos(1, 3)*DirCos(2, 1) - DirCos(1, 1)*DirCos(2, 3) ) !These do not work if convnetion on z2>z1, x2>x1, y2>y1 are not followed as I have discovered 7/23 + !F(5) = TempCoeff*( DirCos(1, 3)*DirCos(2, 2) - DirCos(1, 2)*DirCos(2, 3) ) + + !RRD attempt at new dircos which keeps x in the X-Y plane + F(4) = -TempCoeff * SQRT(1-DirCos(3,3)**2) * DirCos(1,1) !bjj: compare with ElemG() and verify this lumping is consistent + F(5) = -TempCoeff * SQRT(1-DirCos(3,3)**2) * DirCos(2,1) !bjj: compare with ElemG() and verify this lumping is consistent + !RRD ends + F(10) = -F(4) + F(11) = -F(5) + !F(12) is 0 for g along z alone +END SUBROUTINE LumpForces + +!------------------------------------------------------------------------------------------------------ +!> +!! Method 1: pinv_A = A \ eye(m) (matlab) +!! call _GELSS to solve A.X=B +!! pinv(A) = B(1:n,1:m) +!! Method 2: [U,S,V] = svd(A); pinv_A = ( V / S ) * U'; (matlab) +! perform lapack GESVD and then pinv(A) = V*(inv(S))*U' +SUBROUTINE PseudoInverse(A, Ainv, ErrStat, ErrMsg) + use NWTC_LAPACK, only: LAPACK_GESVD, LAPACK_GEMM + real(FEKi), dimension(:,:), intent(in) :: A + real(FEKi), dimension(:,:), allocatable :: Ainv + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! < Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! < Error message if ErrStat / = ErrID_None + ! + real(FEKi), dimension(:), allocatable :: S + real(FEKi), dimension(:,:), allocatable :: U + real(FEKi), dimension(:,:), allocatable :: Vt + real(FEKi), dimension(:), allocatable :: WORK + real(FEKi), dimension(:,:), allocatable :: Acopy + integer :: j ! Loop indices + integer :: M !< The number of rows of the input matrix A + integer :: N !< The number of columns of the input matrix A + integer :: K !< + integer :: L !< + integer :: LWORK !< + M = size(A,1) + N = size(A,2) + K = min(M,N) + L = max(M,N) + LWORK = MAX(1,3*K +L,5*K) + allocate(S(K)); S = 0; + !! LWORK >= MAX(1,3*MIN(M,N) + MAX(M,N),5*MIN(M,N)) for the other paths + allocate(Work(LWORK)); Work=0 + allocate(U (M,K) ); U=0; + allocate(Vt(K,N) ); Vt=0; + allocate(Ainv(N,M)); Ainv=0; + allocate(Acopy(M,N)); Acopy=A; + + ! --- Compute the SVD of A + ! [U,S,V] = svd(A) + !call DGESVD ('S', 'S', M, N, A, M, S, U, M , Vt , K, WORK, LWORK, INFO) + call LAPACK_GESVD('S', 'S', M, N, Acopy, S, U, Vt, WORK, LWORK, ErrStat, ErrMsg) + + !--- Compute PINV = V**T * SIGMA * U**T in two steps + ! SIGMA = S^(-1)=1/S(j), S is diagonal + do j = 1, K + U(:,j) = U(:,j)/S(j) + end do + ! Compute Ainv = 1.0*V^t * U^t + 0.0*Ainv V*(inv(S))*U' + !call DGEMM( 'T', 'T', N, M, K, 1.0, V, K, U, M, 0.0, Ainv, N) + print*,'8' + call LAPACK_GEMM( 'T', 'T', 1.0_FEKi, Vt, U, 0.0_FEKi, Ainv, ErrStat, ErrMsg) + ! --- Compute rank + !tol=maxval(shape(A))*epsilon(maxval(S)) + !rank=0 + !do i=1,K + ! if(S(i) .gt. tol)then + ! rank=rank+1 + ! end if + !end do + !print*,'Rank',rank + ! Ainv=transpose(matmul(matmul(U(:,1:r),S_inv(1:r,1:r)),Vt(1:r,:))) + END SUBROUTINE PseudoInverse + +END MODULE FEM diff --git a/modules/subdyn/src/IntegerList.f90 b/modules/subdyn/src/IntegerList.f90 new file mode 100644 index 0000000000..a5f74112ce --- /dev/null +++ b/modules/subdyn/src/IntegerList.f90 @@ -0,0 +1,458 @@ +!> Module providing suport for an integer list stored as an array and not a chained list +!! Used since registry does not support pointer with recursive types. +module IntegerList + use SubDyn_Types, only: IList + use NWTC_Library, only: IntKi, ReKi, AllocAry, ErrID_None, ErrID_Fatal, num2lstr + + implicit none + + public :: IList + + public :: init_list + public :: destroy_list + public :: len + public :: append + public :: pop + public :: get + public :: find + public :: sort + public :: reverse + interface pop + module procedure pop_last + module procedure pop_item + end interface + interface init_list + module procedure init_list_n_def + module procedure init_list_vect + end interface + interface find + module procedure find_list + module procedure find_intarray + end interface + interface unique + module procedure unique_list + module procedure unique_intarray + module procedure unique_intarray_in_place + end interface +contains + + !> Concatenate lists: I3=[I1,I2] + subroutine concatenate_lists(I1,I2,I3, ErrStat, ErrMsg) + integer(intki), intent(in) :: i1(:), i2(:) + integer(intki), intent(out) :: i3(:) + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat / = ErrID_None + ErrStat=ErrID_None + ErrMsg='' + I3(1:size(I1)) = I1 + I3(size(I1)+1:size(I1)+size(I2)) = I2 + endsubroutine + subroutine concatenate_3lists(I1,I2,I3,I4, ErrStat, ErrMsg) + integer(intki), intent(in) :: i1(:), i2(:), i3(:) + integer(intki), intent(out) :: i4(:) + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat / = ErrID_None + ErrStat=ErrID_None + ErrMsg='' + I4( 1:size(I1) ) = I1 + I4(size(I1) +1:size(I1)+size(I2) ) = I2 + I4(size(I1)+size(I2)+1:size(I1)+size(I2)+size(I3)) = I3 + endsubroutine + + !> Set difference: I3=I1-I2 (assumes I1 is biggger than I2), elements of I1 not in I2 + subroutine lists_difference(I1, I2, I3, ErrStat, ErrMsg) + integer(IntKi), intent(in) :: I1(:), I2(:) + integer(IntKi), intent(out) :: I3(:) + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + integer(IntKi) :: I + logical, dimension(:), allocatable :: bUnique + ErrStat = ErrID_None + ErrMsg = "" + allocate(bUnique(1:size(I1))) + ! Then, remove DOFs on the boundaries: + DO i = 1, size(I1) !Boundary DOFs (Interface + Constraints) + if (find(I2,I1(i))>0) then + bUnique(I) = .false. + else + bUnique(I) = .true. + endif + ENDDO + if (count(bUnique) /= size(I3)) then + ErrStat=ErrID_Fatal; ErrMsg='Storage for list difference is of wrong size'; return + endif + I3 = pack(I1, bUnique) + deallocate(bUnique) + endsubroutine + + !> Initialize an integer list + subroutine init_list_n_def(L,n,default_val,ErrStat,ErrMsg) + type(IList), intent(inout) :: L !< List + integer(IntKi), intent(in) :: n !< number of initial values + integer(IntKi), intent(in) :: default_val !< default values + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + ErrStat = ErrID_None + ErrMsg = "" + call AllocAry(L%List, n, 'L%List', ErrStat, ErrMsg) + if (ErrStat/=ErrID_None) return + L%List(1:n) = default_val + end subroutine init_list_n_def + + subroutine init_list_vect(L,vect,ErrStat,ErrMsg) + type(IList), intent(inout) :: L !< List + integer(IntKi), dimension(:), intent(in) :: vect !< number of initial values + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + ErrStat = ErrID_None + ErrMsg = "" + call AllocAry(L%List, size(vect), 'L%List', ErrStat, ErrMsg) + if (ErrStat/=ErrID_None) return + L%List = vect + end subroutine init_list_vect + + !> Deallocate list + subroutine destroy_list(L,ErrStat,ErrMsg) + type(IList), intent(inout) :: L !< List + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + ErrStat = ErrID_None + ErrMsg = "" + if (allocated(L%List)) deallocate(L%List) + end subroutine destroy_list + + !> Returns list length + integer function len(L) + type(IList), intent(in) :: L + if (allocated(L%List)) then + len=size(L%List) + else + len=0 + endif + end function len + + !> Append element to list + subroutine append(L,e, ErrStat, ErrMsg) + type(IList), intent(inout) :: L + integer(IntKi), intent(in) :: e + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat / = ErrID_None + ErrStat = ErrID_None + ErrMsg = "" + if (allocated(L%List)) then + call resize_array(L%List,len(L)+1,e) + else + call init_list(L, 1, e, ErrStat, ErrMsg) + endif + end subroutine append + + !> Get element i from list + integer function get(L,i, ErrStat, ErrMsg) + type(IList), intent(inout) :: L + integer(IntKi), intent(in) :: i + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat / = ErrID_None + if ((i<=0).or.(i>len(L))) then + ErrStat=ErrID_Fatal + ErrMsg="Index out of bound "//trim(num2lstr(i))//", list length is "//trim(num2lstr(len(L))) + get=-9999 + else + ErrStat = ErrID_None + ErrMsg = "" + get = L%List(i) ! No error handling, throws "index array out of bound", like a regular array + endif + end function get + + !> Pop last element of the list and reduce list size by 1 + integer function pop_last(L,ErrStat,ErrMsg) + type(IList), intent(inout) :: L + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat / = ErrID_None + integer(IntKi) :: n + ErrStat = ErrID_None + ErrMsg = "" + n=len(L) + pop_last = get(L, n, ErrStat, ErrMsg) ! index array out of bound will be thrown + call resize_array(L%List,n-1,0) + end function pop_last + + !> Pop element i from the list and reduce the size of the list by 1 + integer function pop_item(L,i,ErrStat,ErrMsg) + type(IList), intent(inout) :: L + integer(IntKi), intent(in) :: i + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat / = ErrID_None + integer(IntKi) :: n + ErrStat = ErrID_None + ErrMsg = "" + n=len(L) + pop_item = get(L, i, ErrStat, ErrMsg) ! index array out of bound will be thrown + L%List(i:n-1)=L%List(i+1:n) + call resize_array(L%List,n-1,0) + end function pop_item + + !> Sort list + subroutine sort(L, ErrStat, ErrMsg) + type(IList), intent(inout) :: L + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat / = ErrID_None + ErrStat = ErrID_None + ErrMsg = "" + if (allocated(L%List)) then + call sort_in_place(L%List) + else + ErrStat=ErrID_Fatal + ErrMsg="Cannot sort a list not allocated" + endif + end subroutine sort + + !> Reverse list + subroutine reverse(L, ErrStat, ErrMsg) + type(IList), intent(inout) :: L + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat / = ErrID_None + integer(IntKi) :: i + integer(IntKi) :: n + ErrStat = ErrID_None + ErrMsg = "" + n=len(L) + do i =1,int(n/2) + call swap(i, n-i+1) + enddo + contains + subroutine swap(i,j) + integer(IntKi), intent(in) :: i,j + integer(IntKi) :: tmp + tmp=L%List(i) + L%List(i) = L%List(j) + L%List(j) = tmp + end subroutine + end subroutine reverse + + + !> Returns index of element e in L, returns 0 if not found + !! NOTE: list but be sorted to call this function + integer(IntKi) function find_list(L, e, ErrStat, ErrMsg) + type(IList), intent(inout) :: L + integer(IntKi), intent(in ) :: e + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat / = ErrID_None + ErrStat = ErrID_None + ErrMsg = "" + if (len(L)>0) then + find_list = binary_search(L%List, e) ! Binary search returns index for inequality List(i)<=e + if (find_list>0) then + if (L%List(find_list)/=e) then + find_list=-1 + endif + endif + else + find_list=-1 + endif + end function find_list + + !> Unique, in place + subroutine unique_list(L, ErrStat, ErrMsg) + type(IList), intent(inout) :: L + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat / = ErrID_None + ErrStat = ErrID_None + ErrMsg = "" + if (len(L)>0) then + call unique_intarray_in_place(L%List) + endif + end subroutine + + !> Print + subroutine print_list(L, varname, u_opt) + type(IList), intent(in) :: L + character(len=*),intent(in) :: varname + integer(IntKi), intent(in),optional :: u_opt + ! + character(len=*),parameter :: IFMT='I7.0' !< + integer(IntKi) :: u + integer(IntKi) :: n + character(len=20) :: fmt + ! Optional args + if (present(u_opt)) then + u=u_opt + else + u=6 + endif + n=len(L) + if (n>0) then + write(fmt,*) n + write(u,"(A,A,"// adjustl(fmt)//IFMT//",A)") varname,"=[",L%List,"];" + else + write(u,'(A,A)') varname,'=[];' + endif + end subroutine print_list + + ! -------------------------------------------------------------------------------- + ! --- Generic helper functions (should be part of NWTC library) + ! -------------------------------------------------------------------------------- + !> Sort integer array in place + pure subroutine sort_in_place(a) + integer(IntKi), intent(inout), dimension(:) :: a + integer(IntKi) :: temp + integer(IntKi) :: i, j + do i = 2, size(a) + j = i - 1 + temp = a(i) + do while (j>=1 .and. a(j)>temp) + a(j+1) = a(j) + j = j - 1 + if (j<1) then + exit + endif + end do + a(j+1) = temp + end do + end subroutine sort_in_place + + !> Performs binary search and return the largest index such that x(i) <= x0 + !! allows equlity + Integer(IntKi) function binary_search(x, x0) result(i_inf) + ! Arguments declarations + integer(IntKi), dimension(:),intent(in) :: x !< x *sorted* vector + integer(IntKi), intent(in) :: x0 !< + ! Variable declarations + integer(IntKi) :: i_sup !< + integer(IntKi) :: mid !< + i_inf=1 + i_sup=size(x) + ! Safety test + if (x0=x(i_sup)) then + i_inf=i_sup + return + end if + ! We loop until we narrow down to one index + do while (i_inf+1 Returns index of val in Array (val is an integer!) + ! NOTE: in the future use intrinsinc function findloc + function find_intarray(Array, Val) result(i) + integer(IntKi), dimension(:), intent(in) :: Array !< Array to search in + integer(IntKi), intent(in) :: val !< Val + integer(IntKi) :: i !< Index of joint in joint table + i = 1 + do while ( i <= size(Array) ) + if ( Val == Array(i) ) THEN + return ! Exit when found + else + i = i + 1 + endif + enddo + i=-1 + end function + + !> return in res the unique values of v + subroutine unique_intarray(v,res) + ! Arguments + integer(IntKi),dimension(:),intent(in) :: v + integer(IntKi),dimension(:),allocatable::res + ! + integer(IntKi),dimension(:),pointer::tmp + integer :: k !< number of unique elements + integer :: i, j + if (allocated(res)) deallocate(res) + allocate(tmp(1:size(v))) + k = 1 + tmp(1) = v(1) + outer: do i=2,size(v) + do j=1,k + if (tmp(j) == v(i)) then + ! Found a match so start looking again + cycle outer + end if + end do + ! No match found so add it to the output + k = k + 1 + tmp(k) = v(i) + end do outer + allocate(res(1:k)) + res(1:k)=tmp(1:k) + deallocate(tmp) + end subroutine + + subroutine unique_intarray_in_place(v) + integer(IntKi),dimension(:),allocatable :: v + integer(IntKi),dimension(:),allocatable::res + integer :: k !< number of unique elements + integer :: i, j + allocate(res(1:size(v))) + k = 1 + res(1) = v(1) + outer: do i=2,size(v) + do j=1,k + if (res(j) == v(i)) then + ! Found a match so start looking again + cycle outer + end if + end do + ! No match found so add it to the output + k = k + 1 + res(k) = v(i) + end do outer + deallocate(v) + allocate(v(1:k)) + v(1:k)=res(1:k) + deallocate(res) + end subroutine + + !> Resize integer array of dimension 1 + subroutine resize_array(array,nNewSize,default_val) + integer(IntKi),dimension(:),allocatable,intent(inout) :: array + integer(IntKi) , intent(in) :: nNewSize + integer(IntKi), intent(in) :: default_val + ! Local variables + integer(IntKi),dimension(:),allocatable :: tmp !< backup of input + integer(IntKi) :: nDimTmp + integer(IntKi) :: AllocateStatus + ! To save memory, if nNewSize is below second dim, we take the min + nDimTmp= min(size(array,1),nNewSize) + ! Making of copy of the input + allocate(tmp(1:nDimTmp), STAT = AllocateStatus) + if (AllocateStatus /= 0) STOP "*** Not enough memory ***" + tmp(1:nDimTmp)=array(1:nDimTmp) + ! Reallocating the array + deallocate(array) + allocate(array(1:nNewSize), STAT = AllocateStatus) + if (AllocateStatus /= 0) STOP "*** Not enough memory ***" + ! We copy the original data into it + array(1:nDimTmp)=tmp(1:nDimTmp) + if(nDimTmp+1<=nNewSize) array(nDimTmp+1:nNewSize)=default_val + end subroutine + + !> Append two integer arrays of dimension 1 + subroutine append_arrays(array1,n1,array2,n2) + integer(IntKi), dimension(:), allocatable :: array1 + integer(IntKi), dimension(:) :: array2 + integer(IntKi), intent(inout) :: n1 !< SIDE EFFECTS + integer(IntKi), intent(in) :: n2 + ! Local variables + integer :: nNew + nNew=n1+n2 + ! --- Making enough space if needed + if(nNew>size(array1,1)) then + call resize_array(array1,nNew,0) + endif + ! --- Appending + array1((n1+1):(n1+n2))=array2(1:n2) + ! updating n1 + n1=n1+n2; + end subroutine + +end module IntegerList diff --git a/modules/subdyn/src/SD_FEM.f90 b/modules/subdyn/src/SD_FEM.f90 index dd59ec1477..c705e6aea8 100644 --- a/modules/subdyn/src/SD_FEM.f90 +++ b/modules/subdyn/src/SD_FEM.f90 @@ -19,58 +19,99 @@ MODULE SD_FEM USE NWTC_Library USE SubDyn_Types + USE FEM IMPLICIT NONE - INTEGER, PARAMETER :: LAKi = R8Ki ! Define the kind to be used for LAPACK routines for getting eigenvalues/vectors. Apparently there is a problem with SGGEV's eigenvectors - INTEGER(IntKi), PARAMETER :: MaxMemjnt = 10 ! Maximum number of members at one joint + INTEGER(IntKi), PARAMETER :: MaxMemJnt = 10 ! Maximum number of members at one joint INTEGER(IntKi), PARAMETER :: MaxOutChs = 2000 ! Max number of Output Channels to be read in - INTEGER(IntKi), PARAMETER :: TPdofL = 6 ! 6 degrees of freedom (length of u subarray [UTP]) + 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: - INTEGER(IntKi), PARAMETER :: JointsCol = 4 ! Number of columns in Joints (JointID, JointXss, JointYss, JointZss) - INTEGER(IntKi), PARAMETER :: ReactCol = 7 ! Number of columns in reaction dof array (JointID,RctTDxss,RctTDYss,RctTDZss,RctRDXss,RctRDYss,RctRDZss) + INTEGER(IntKi), PARAMETER :: JointsCol = 9 ! Number of columns in Joints (JointID, JointXss, JointYss, JointZss, JointType, JointDirX JointDirY JointDirZ JointStiff) INTEGER(IntKi), PARAMETER :: InterfCol = 7 ! Number of columns in interf matrix (JointID,ItfTDxss,ItfTDYss,ItfTDZss,ItfRDXss,ItfRDYss,ItfRDZss) + INTEGER(IntKi), PARAMETER :: ReactCol = 7 ! Number of columns in reaction matrix (JointID,ItfTDxss,ItfTDYss,ItfTDZss,ItfRDXss,ItfRDYss,ItfRDZss) INTEGER(IntKi), PARAMETER :: MaxNodesPerElem = 2 ! Maximum number of nodes per element (currently 2) - INTEGER(IntKi), PARAMETER :: MembersCol = MaxNodesPerElem + 3 ! Number of columns in Members (MemberID,MJointID1,MJointID2,MPropSetID1,MPropSetID2,COSMID) - INTEGER(IntKi), PARAMETER :: PropSetsCol = 6 ! Number of columns in PropSets (PropSetID,YoungE,ShearG,MatDens,XsecD,XsecT) !bjj: this really doesn't need to store k, does it? or is this supposed to be an ID, in which case we shouldn't be storing k (except new property sets), we should be storing IDs - INTEGER(IntKi), PARAMETER :: XPropSetsCol = 10 ! Number of columns in XPropSets (PropSetID,YoungE,ShearG,MatDens,XsecA,XsecAsx,XsecAsy,XsecJxx,XsecJyy,XsecJ0) + INTEGER(IntKi), PARAMETER :: MembersCol = MaxNodesPerElem + 3+1 ! Number of columns in Members (MemberID,MJointID1,MJointID2,MPropSetID1,MPropSetID2,COSMID) + INTEGER(IntKi), PARAMETER :: PropSetsBCol = 6 ! Number of columns in PropSets (PropSetID,YoungE,ShearG,MatDens,XsecD,XsecT) !bjj: this really doesn't need to store k, does it? or is this supposed to be an ID, in which case we shouldn't be storing k (except new property sets), we should be storing IDs + INTEGER(IntKi), PARAMETER :: PropSetsXCol = 10 ! Number of columns in XPropSets (PropSetID,YoungE,ShearG,MatDens,XsecA,XsecAsx,XsecAsy,XsecJxx,XsecJyy,XsecJ0) + INTEGER(IntKi), PARAMETER :: PropSetsCCol = 5 ! Number of columns in CablePropSet (PropSetID, EA, MatDens, T0) + INTEGER(IntKi), PARAMETER :: PropSetsRCol = 2 ! Number of columns in RigidPropSet (PropSetID, MatDens) INTEGER(IntKi), PARAMETER :: COSMsCol = 10 ! Number of columns in (cosine matrices) COSMs (COSMID,COSM11,COSM12,COSM13,COSM21,COSM22,COSM23,COSM31,COSM32,COSM33) - INTEGER(IntKi), PARAMETER :: CMassCol = 5 ! Number of columns in Concentrated Mass (CMJointID,JMass,JMXX,JMYY,JMZZ) + INTEGER(IntKi), PARAMETER :: CMassCol = 11 ! Number of columns in Concentrated Mass (CMJointID,JMass,JMXX,JMYY,JMZZ, Optional:JMXY,JMXZ,JMYZ,CGX,CGY,CGZ) ! Indices in Members table + INTEGER(IntKi), PARAMETER :: iMType= 6 ! Index in Members table where the type is stored INTEGER(IntKi), PARAMETER :: iMProp= 4 ! Index in Members table where the PropSet1 and 2 are stored - INTEGER(IntKi), PARAMETER :: SDMaxInpCols = MAX(JointsCol,ReactCol,InterfCol,MembersCol,PropSetsCol,XPropSetsCol,COSMsCol,CMassCol) + ! Indices in Joints table + INTEGER(IntKi), PARAMETER :: iJointType= 5 ! Index in Joints where the joint type is stored + INTEGER(IntKi), PARAMETER :: iJointDir= 6 ! Index in Joints where the joint-direction are stored + INTEGER(IntKi), PARAMETER :: iJointStiff= 9 ! Index in Joints where the joint-stiffness is stored + + ! ID for joint types + INTEGER(IntKi), PARAMETER :: idJointCantilever = 1 + INTEGER(IntKi), PARAMETER :: idJointUniversal = 2 + INTEGER(IntKi), PARAMETER :: idJointPin = 3 + INTEGER(IntKi), PARAMETER :: idJointBall = 4 + + ! ID for member types + INTEGER(IntKi), PARAMETER :: idMemberBeam = 1 + INTEGER(IntKi), PARAMETER :: idMemberCable = 2 + INTEGER(IntKi), PARAMETER :: idMemberRigid = 3 + + ! Types of Boundary Conditions + INTEGER(IntKi), PARAMETER :: idBC_Fixed = 11 ! Fixed BC + INTEGER(IntKi), PARAMETER :: idBC_Internal = 12 ! Free BC + INTEGER(IntKi), PARAMETER :: idBC_Leader = 13 ! TODO, and maybe "BC" not appropriate here + + ! Types of Static Improvement Methods + INTEGER(IntKi), PARAMETER :: idSIM_None = 0 + INTEGER(IntKi), PARAMETER :: idSIM_Full = 1 + INTEGER(IntKi) :: idSIM_Valid(2) = (/idSIM_None, idSIM_Full/) + + ! Types of Guyan Damping + INTEGER(IntKi), PARAMETER :: idGuyanDamp_None = 0 + INTEGER(IntKi), PARAMETER :: idGuyanDamp_Rayleigh = 1 + INTEGER(IntKi), PARAMETER :: idGuyanDamp_66 = 2 + INTEGER(IntKi) :: idGuyanDamp_Valid(3) = (/idGuyanDamp_None, idGuyanDamp_Rayleigh, idGuyanDamp_66 /) + + INTEGER(IntKi), PARAMETER :: SDMaxInpCols = MAX(JointsCol,InterfCol,MembersCol,PropSetsBCol,PropSetsXCol,COSMsCol,CMassCol) + ! Implementation Flags + LOGICAL, PARAMETER :: DEV_VERSION = .false. + LOGICAL, PARAMETER :: BC_Before_CB = .true. + LOGICAL, PARAMETER :: ANALYTICAL_LIN = .true. + LOGICAL, PARAMETER :: GUYAN_RIGID_FLOATING = .true. INTERFACE FINDLOCI ! In the future, use FINDLOC from intrinsic MODULE PROCEDURE FINDLOCI_ReKi MODULE PROCEDURE FINDLOCI_IntKi END INTERFACE + CONTAINS - +!------------------------------------------------------------------------------------------------------ +! --- Helper functions +!------------------------------------------------------------------------------------------------------ !> Maps nodes to elements !! allocate NodesConnE and NodesConnN SUBROUTINE NodeCon(Init,p, ErrStat, ErrMsg) - USE qsort_c_module ,only: QsortC - TYPE(SD_InitType), INTENT( INOUT ) :: Init - TYPE(SD_ParameterType), INTENT( IN ) :: p - INTEGER(IntKi), INTENT( OUT ) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - ! Local variables - INTEGER(IntKi) :: SortA(MaxMemJnt,1) !To sort nodes and elements - INTEGER(IntKi) :: I,J,K !counter - - ! The row index is the number of the real node, i.e. ID, 1st col has number of elements attached to node, and 2nd col has element numbers (up to 10) - CALL AllocAry(Init%NodesConnE, Init%NNode, MaxMemJnt+1,'NodesConnE', ErrStat, ErrMsg); if (ErrStat/=0) return; - CALL AllocAry(Init%NodesConnN, Init%NNode, MaxMemJnt+2,'NodesConnN', ErrStat, ErrMsg); if (ErrStat/=0) return; - Init%NodesConnE = 0 - Init%NodesConnN = 0 - + TYPE(SD_InitType), INTENT( INOUT ) :: Init + TYPE(SD_ParameterType), INTENT( IN ) :: p + INTEGER(IntKi), INTENT( OUT ) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! Local variables + INTEGER(IntKi) :: I,J,K !counter + + ! The row index is the number of the real node, i.e. ID, 1st col has number of elements attached to node, and 2nd col has element numbers (up to 10) + CALL AllocAry(Init%NodesConnE, p%nNodes, MaxMemJnt+1,'NodesConnE', ErrStat, ErrMsg); if (ErrStat/=0) return; + CALL AllocAry(Init%NodesConnN, p%nNodes, MaxMemJnt+2,'NodesConnN', ErrStat, ErrMsg); if (ErrStat/=0) return; + Init%NodesConnE = 0 + Init%NodesConnN = -99999 ! Not Used + ! find the node connectivity, nodes/elements that connect to a common node - DO I = 1, Init%NNode - Init%NodesConnN(I, 1) = NINT( Init%Nodes(I, 1) ) !This should not be needed, could remove the extra 1st column like for the other array + DO I = 1, p%nNodes + !Init%NodesConnN(I, 1) = NINT( Init%Nodes(I, 1) ) !This should not be needed, could remove the extra 1st column like for the other array k = 0 DO J = 1, Init%NElem !This should be vectorized IF ( ( NINT(Init%Nodes(I, 1))==p%Elems(J, 2)) .OR. (NINT(Init%Nodes(I, 1))==p%Elems(J, 3) ) ) THEN !If i-th nodeID matches 1st node or 2nd of j-th element @@ -79,23 +120,163 @@ SUBROUTINE NodeCon(Init,p, ErrStat, ErrMsg) CALL SetErrStat(ErrID_Fatal, 'Maximum number of members reached on node'//trim(Num2LStr(NINT(Init%Nodes(I,1)))), ErrStat, ErrMsg, 'NodeCon'); endif Init%NodesConnE(I, k + 1) = p%Elems(J, 1) - Init%NodesConnN(I, k + 1) = p%Elems(J, 3) - IF ( NINT(Init%Nodes(I, 1))==p%Elems(J, 3) ) Init%NodesConnN(I, k + 1) = p%Elems(J, 2) !If nodeID matches 2nd node of element ENDIF ENDDO - - IF( k>1 )THEN ! sort the nodes ascendingly - SortA(1:k, 1) = Init%NodesConnN(I, 3:(k+2)) - CALL QsortC( SortA(1:k, 1:1) ) - Init%NodesConnN(I, 3:(k+2)) = SortA(1:k, 1) - ENDIF - Init%NodesConnE(I, 1) = k !Store how many elements connect i-th node in 2nd column - Init%NodesConnN(I, 2) = k ENDDO END SUBROUTINE NodeCon + !---------------------------------------------------------------------------- +!> Check if two elements are connected +!! returns true if they are, and return which node (1 or 2) of each element is involved +LOGICAL FUNCTION ElementsConnected(p, ie1, ie2, iWhichNode_e1, iWhichNode_e2) + TYPE(SD_ParameterType), INTENT(IN) :: p + INTEGER(IntKi), INTENT(IN) :: ie1, ie2 ! Indices of elements + INTEGER(IntKi), INTENT(OUT) :: iWhichNode_e1, iWhichNode_e2 ! 1 or 2 if node 1 or node 2 + if ((p%Elems(ie1, 2) == p%Elems(ie2, 2))) then ! node 1 connected to node 1 + iWhichNode_e1=1 + iWhichNode_e2=1 + ElementsConnected=.True. + else if((p%Elems(ie1, 2) == p%Elems(ie2, 3))) then ! node 1 connected to node 2 + iWhichNode_e1=1 + iWhichNode_e2=2 + ElementsConnected=.True. + else if((p%Elems(ie1, 3) == p%Elems(ie2, 2))) then ! node 2 connected to node 1 + iWhichNode_e1=2 + iWhichNode_e2=1 + ElementsConnected=.True. + else if((p%Elems(ie1, 3) == p%Elems(ie2, 3))) then ! node 2 connected to node 2 + iWhichNode_e1=2 + iWhichNode_e2=2 + ElementsConnected=.True. + else + ElementsConnected=.False. + iWhichNode_e1=-1 + iWhichNode_e2=-1 + endif +END FUNCTION ElementsConnected + +!> Loop through a list of elements and returns a list of unique joints +TYPE(IList) FUNCTION NodesList(p, Elements) + use IntegerList, only: init_list, append, find, sort + use IntegerList, only: print_list + TYPE(SD_ParameterType), INTENT(IN) :: p + integer(IntKi), dimension(:), INTENT(IN) :: Elements + integer(IntKi) :: ie, ei, j1, j2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + + call init_list(NodesList, 0, 0, ErrStat2, ErrMsg2) + do ie = 1, size(Elements) + ei = Elements(ie) ! Element index + j1 = p%Elems(ei,2) ! Joint 1 + j2 = p%Elems(ei,3) ! Joint 2 + ! Append joints indices if not in list already + if (find(NodesList, j1, ErrStat2, ErrMsg2)<=0) call append(NodesList, j1, ErrStat2, ErrMsg2) + if (find(NodesList, j2, ErrStat2, ErrMsg2)<=0) call append(NodesList, j2, ErrStat2, ErrMsg2) + ! Sorting required by find function + call sort(NodesList, ErrStat2, ErrMsg2) + enddo + if (DEV_VERSION) then + call print_list(NodesList, 'Joint list') + endif +END FUNCTION NodesList +!------------------------------------------------------------------------------------------------------ +!> Returns list of rigid link elements (Er) +TYPE(IList) FUNCTION RigidLinkElements(Init, p, ErrStat, ErrMsg) + use IntegerList, only: init_list, append + use IntegerList, only: print_list + TYPE(SD_InitType), INTENT(INOUT) :: Init + TYPE(SD_ParameterType), INTENT(INOUT) :: p + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! Local variables + integer(IntKi) :: ie !< Index on elements + ErrStat = ErrID_None + ErrMsg = "" + ! --- Establish a list of rigid link elements + call init_list(RigidLinkElements, 0, 0, ErrStat, ErrMsg); + + do ie = 1, Init%NElem + if (p%ElemProps(ie)%eType == idMemberRigid) then + call append(RigidLinkElements, ie, ErrStat, ErrMsg); + endif + end do + if (DEV_VERSION) then + call print_list(RigidLinkElements,'Rigid element list') + endif +END FUNCTION RigidLinkElements + +!------------------------------------------------------------------------------------------------------ +!> Returns true if one of the element connected to the node is a rigid link +LOGICAL FUNCTION NodeHasRigidElem(iJoint, Init, p, ei) + integer(IntKi), intent(in) :: iJoint + type(SD_InitType), intent(in) :: Init + type(SD_ParameterType), intent(in) :: p + integer(IntKi), intent( out) :: ei !< Element index that connects do iJoint rigidly + ! Local variables + integer(IntKi) :: ie !< Loop index on elements + + NodeHasRigidElem = .False. ! default return value + ! Loop through elements connected to node J + do ie = 1, Init%NodesConnE(iJoint, 1) + ei = Init%NodesConnE(iJoint, ie+1) + if (p%ElemProps(ei)%eType == idMemberRigid) then + NodeHasRigidElem = .True. + return ! we exit as soon as one rigid member is found + endif + enddo + ei=-1 +END FUNCTION NodeHasRigidElem +!------------------------------------------------------------------------------------------------------ +!> Returns a rigid body transformation matrix from nDOF to 6 reference DOF: T_ref (6 x nDOF), such that Uref = T_ref.U_subset +!! Typically called to get: +!! - the transformation from the interface points to the TP point +!! - the transformation from the bottom nodes to SubDyn origin (0,0,) +SUBROUTINE RigidTrnsf(Init, p, RefPoint, DOF, nDOF, T_ref, ErrStat, ErrMsg) + TYPE(SD_InitType), INTENT(IN ) :: Init ! Input data for initialization routine + TYPE(SD_ParameterType), INTENT(IN ) :: p + REAL(ReKi), INTENT(IN ) :: RefPoint(3) ! Coordinate of the reference point + INTEGER(IntKi), INTENT(IN ) :: nDOF ! Number of DOFS + INTEGER(IntKi), INTENT(IN ) :: DOF(nDOF) ! DOF indices that are used to create the transformation matrix + REAL(ReKi), INTENT( OUT) :: T_ref(nDOF,6) ! matrix that relates the subset of DOFs to the reference point + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! local variables + INTEGER :: I, iDOF, iiDOF, iNode, nDOFPerNode + REAL(ReKi) :: dx, dy, dz + REAL(ReKi), dimension(6) :: Line + ErrStat = ErrID_None + ErrMsg = "" + T_ref(:,:)=0 + DO I = 1, nDOF + iDOF = DOF(I) ! DOF index in constrained system + iNode = p%DOFred2Nodes(iDOF,1) ! First column is node + nDOFPerNode = p%DOFred2Nodes(iDOF,2) ! Second column is number of DOF per node + iiDOF = p%DOFred2Nodes(iDOF,3) ! Third column is dof index for this joint (1-6 for cantilever) + + if ((iiDOF<1) .or. (iiDOF>6)) then + ErrMsg = 'RigidTrnsf, node DOF number is not valid. DOF:'//trim(Num2LStr(iDOF))//' Node:'//trim(Num2LStr(iNode))//' iiDOF:'//trim(Num2LStr(iiDOF)); ErrStat = ErrID_Fatal + return + endif + if (nDOFPerNode/=6) then + ErrMsg = 'RigidTrnsf, node doesnt have 6 DOFs. DOF:'//trim(Num2LStr(iDOF))//' Node:'//trim(Num2LStr(iNode))//' nDOF:'//trim(Num2LStr(nDOFPerNode)); ErrStat = ErrID_Fatal + return + endif + + dx = Init%Nodes(iNode, 2) - RefPoint(1) + dy = Init%Nodes(iNode, 3) - RefPoint(2) + dz = Init%Nodes(iNode, 4) - RefPoint(3) + + CALL RigidTransformationLine(dx,dy,dz,iiDOF,Line) !returns Line + T_ref(I, 1:6) = Line + ENDDO +END SUBROUTINE RigidTrnsf + +!------------------------------------------------------------------------------------------------------ +! --- Main routines, more or less listed in order in which they are called +!------------------------------------------------------------------------------------------------------ !> ! - Removes the notion of "ID" and use Index instead ! - Creates Nodes (use indices instead of ID), similar to Joints array @@ -109,40 +290,40 @@ SUBROUTINE SD_ReIndex_CreateNodesAndElems(Init,p, ErrStat, ErrMsg) CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None ! local variable INTEGER :: I, n, iMem, iNode, JointID - CHARACTER(1024) :: sType !< String for element type + INTEGER(IntKi) :: mType !< Member Type + CHARACTER(1255) :: sType !< String for element type INTEGER(IntKi) :: ErrStat2 - CHARACTER(1024) :: ErrMsg2 + CHARACTER(ErrMsgLen) :: ErrMsg2 ErrStat = ErrID_None ErrMsg = "" + ! TODO See if Elems is actually used elsewhere + CALL AllocAry(p%Elems, Init%NElem, MembersCol, 'p%Elems', ErrStat2, ErrMsg2); if(Failed()) return - CALL AllocAry(Init%Nodes, Init%NNode, JointsCol, 'Init%Nodes', ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(Init%Nodes, p%nNodes, JointsCol, 'Init%Nodes', ErrStat2, ErrMsg2); if(Failed()) return ! --- Initialize Nodes - Init%Nodes = 0 + Init%Nodes = -999999 ! Init to unphysical values do I = 1,Init%NJoints - Init%Nodes(I, 1) = I ! JointID replaced by index I - Init%Nodes(I, 2) = Init%Joints(I, 2) - Init%Nodes(I, 3) = Init%Joints(I, 3) - Init%Nodes(I, 4) = Init%Joints(I, 4) + Init%Nodes(I, 1) = I ! JointID replaced by index I + Init%Nodes(I, 2:JointsCol) = Init%Joints(I, 2:JointsCol) ! All the rest is copied enddo ! --- Re-Initialize Reactions, pointing to index instead of JointID - do I = 1, p%NReact - JointID=p%Reacts(I,1) - p%Reacts(I,1) = FINDLOCI(Init%Joints(:,1), JointID ) ! Replace JointID with Index - if (p%Reacts(I,1)<=0) then + do I = 1, p%nNodes_C + JointID=p%Nodes_C(I,1) + p%Nodes_C(I,1) = FINDLOCI(Init%Joints(:,1), JointID ) ! Replace JointID with Index + if (p%Nodes_C(I,1)<=0) then CALL Fatal('Reaction joint table: line '//TRIM(Num2LStr(I))//' refers to JointID '//trim(Num2LStr(JointID))//' which is not in the joint list!') return endif enddo ! --- Re-Initialize interface joints, pointing to index instead of JointID - Init%IntFc = 0 - do I = 1, Init%NInterf - JointID=Init%Interf(I,1) - Init%Interf(I,1) = FINDLOCI(Init%Joints(:,1), JointID ) - if (Init%Interf(I,1)<=0) then + do I = 1, p%nNodes_I + JointID=p%Nodes_I(I,1) + p%Nodes_I(I,1) = FINDLOCI(Init%Joints(:,1), JointID ) + if (p%Nodes_I(I,1)<=0) then CALL Fatal('Interface joint table: line '//TRIM(Num2LStr(I))//' refers to JointID '//trim(Num2LStr(JointID))//' which is not in the joint list!') return endif @@ -152,7 +333,7 @@ SUBROUTINE SD_ReIndex_CreateNodesAndElems(Init,p, ErrStat, ErrMsg) do I = 1, Init%NCMass JointID = Init%CMass(I,1) Init%CMass(I,1) = FINDLOCI(Init%Joints(:,1), JointID ) - if (Init%Interf(I,1)<=0) then + if (Init%CMass(I,1)<=0) then CALL Fatal('Concentrated mass table: line '//TRIM(Num2LStr(I))//' refers to JointID '//trim(Num2LStr(JointID))//' which is not in the joint list!') return endif @@ -165,6 +346,7 @@ SUBROUTINE SD_ReIndex_CreateNodesAndElems(Init,p, ErrStat, ErrMsg) DO iMem = 1, p%NMembers ! Column 1 : member index (instead of MemberID) p%Elems(iMem, 1) = iMem + mType = Init%Members(iMem, iMType) ! ! Column 2-3: Joint index (instead of JointIDs) p%Elems(iMem, 1) = iMem ! NOTE: element/member number (not MemberID) do iNode=2,3 @@ -178,13 +360,34 @@ SUBROUTINE SD_ReIndex_CreateNodesAndElems(Init,p, ErrStat, ErrMsg) ! NOTE: this index has different meaning depending on the member type ! DO n=iMProp,iMProp+1 - sType='Member x-section property' - p%Elems(iMem,n) = FINDLOCI(Init%PropSets(:,1), Init%Members(iMem, n) ) - + if (mType==idMemberBeam) then + sType='Member x-section property' + p%Elems(iMem,n) = FINDLOCI(Init%PropSetsB(:,1), Init%Members(iMem, n) ) + else if (mType==idMemberCable) then + sType='Cable property' + p%Elems(iMem,n) = FINDLOCI(Init%PropSetsC(:,1), Init%Members(iMem, n) ) + else if (mType==idMemberRigid) then + sType='Rigid property' + p%Elems(iMem,n) = FINDLOCI(Init%PropSetsR(:,1), Init%Members(iMem, n) ) + else + ! Should not happen + print*,'Element type unknown',mType + STOP + end if + ! Test that the two properties match for non-beam + if (mType/=idMemberBeam) then + if (Init%Members(iMem, iMProp)/=Init%Members(iMem, iMProp+1)) then + call Fatal('Properties should be the same at each node for non-beam members. Check member with ID: '//TRIM(Num2LStr(Init%Members(iMem,1)))) + return + endif + endif if (p%Elems(iMem,n)<=0) then - CALL Fatal('For MemberID '//TRIM(Num2LStr(Init%Members(iMem,1)))//'the PropSetID'//TRIM(Num2LStr(n-3))//' is not in the'//trim(sType)//' table!') + CALL Fatal('For MemberID '//TRIM(Num2LStr(Init%Members(iMem,1)))//', the PropSetID'//TRIM(Num2LStr(n-3))//' is not in the'//trim(sType)//' table!') + return endif END DO !n, loop through property ids + ! Column 6: member type + p%Elems(iMem, iMType) = Init%Members(iMem, iMType) ! END DO !iMem, loop through members ! TODO in theory, we shouldn't need these anymore @@ -208,18 +411,18 @@ SUBROUTINE SD_Discrt(Init,p, ErrStat, ErrMsg) INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None ! local variable - INTEGER :: I, J, n, Node1, Node2, Prop1, Prop2 + INTEGER :: I, J, Node1, Node2, Prop1, Prop2 INTEGER :: NNE ! number of nodes per element INTEGER :: MaxNProp REAL(ReKi), ALLOCATABLE :: TempProps(:, :) INTEGER, ALLOCATABLE :: TempMembers(:, :) INTEGER :: knode, kelem, kprop, nprop REAL(ReKi) :: x1, y1, z1, x2, y2, z2, dx, dy, dz, dd, dt, d1, d2, t1, t2 - LOGICAL :: found, CreateNewProp + LOGICAL :: CreateNewProp + INTEGER(IntKi) :: nMemberCable, nMemberRigid, nMemberBeam !< Number of memebers per type + INTEGER(IntKi) :: eType !< Element Type INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - - ErrStat = ErrID_None ErrMsg = "" @@ -227,47 +430,40 @@ SUBROUTINE SD_Discrt(Init,p, ErrStat, ErrMsg) IF( ( Init%FEMMod >= 0 ) .and. (Init%FEMMod <= 3) ) THEN NNE = 2 ELSE - CALL Fatal('FEMMod '//TRIM(Num2LStr(Init%FEMMod))//' not implemented.') - RETURN + CALL Fatal('FEMMod '//TRIM(Num2LStr(Init%FEMMod))//' not implemented.'); return ENDIF - ! Total number of element - Init%NElem = p%NMembers*Init%NDiv + ! --- Total number of element + nMemberBeam = count(Init%Members(:,iMType) == idMemberBeam) + nMemberCable = count(Init%Members(:,iMType) == idMemberCable) + nMemberRigid = count(Init%Members(:,iMType) == idMemberRigid) + Init%NElem = nMemberBeam*Init%NDiv + nMemberCable + nMemberRigid ! NOTE: only Beams are divided + IF ( (nMemberBeam+nMemberRigid+nMemberCable) /= size(Init%Members,1)) then + CALL Fatal(' Member list contains an element which is not a beam, a cable or a rigid link'); return + ENDIF + ! Total number of nodes - Depends on division and number of nodes per element - Init%NNode = Init%NJoints + ( Init%NDiv - 1 )*p%NMembers - Init%NNode = Init%NNode + (NNE - 2)*Init%NElem + p%nNodes = Init%NJoints + ( Init%NDiv - 1 )*nMemberBeam ! check the number of interior modes - IF ( p%Nmodes > 6*(Init%NNode - Init%NInterf - p%NReact) ) THEN - CALL Fatal(' NModes must be less than or equal to '//TRIM(Num2LStr( 6*(Init%NNode - Init%NInterf - p%NReact) ))) - RETURN + IF ( p%nDOFM > 6*(p%nNodes - p%nNodes_I - p%nNodes_C) ) THEN + CALL Fatal(' NModes must be less than or equal to '//TRIM(Num2LStr( 6*(p%nNodes - p%nNodes_I - p%nNodes_C) ))); return ENDIF + ! TODO replace this with an integer list! CALL AllocAry(Init%MemberNodes,p%NMembers, Init%NDiv+1,'Init%MemberNodes',ErrStat2, ErrMsg2); if(Failed()) return ! for two-node element only, otherwise the number of nodes in one element is different - CALL AllocAry(Init%IntFc, 6*Init%NInterf,2, 'Init%IntFc', ErrStat2, ErrMsg2); if(Failed()) return ! --- Reindexing JointsID and MembersID into Nodes and Elems arrays ! NOTE: need NNode and NElem - CALL SD_ReIndex_CreateNodesAndElems(Init,p, ErrStat2, ErrMsg2); if(Failed()) return + CALL SD_ReIndex_CreateNodesAndElems(Init, p, ErrStat2, ErrMsg2); if(Failed()) return - ! --- Initialize boundary constraint vector - TODO: assumes order of DOF, NOTE: Needs Reindexing first - CALL AllocAry(Init%BCs, 6*p%NReact, 2, 'Init%BCs', ErrStat2, ErrMsg2); if(Failed()) return - CALL InitConstr(Init, p) - - ! --- Initialize interface constraint vector - TODO: assumes order of DOF, NOTE: Needs Reindexing first - DO I = 1, Init%NInterf - DO J = 1, 6 - Init%IntFc( (I-1)*6+J, 1) = (Init%Interf(I,1)-1)*6+J; ! TODO assumes order of DOF, and needs Interf1 reindexed - Init%IntFc( (I-1)*6+J, 2) = Init%Interf(I, J+1); - ENDDO - ENDDO - + Init%MemberNodes = 0 ! --- Setting up MemberNodes (And Elems, Props, Nodes if divisions) if (Init%NDiv==1) then ! NDiv = 1 Init%MemberNodes(1:p%NMembers, 1:2) = p%Elems(1:Init%NElem, 2:3) - Init%NProp = Init%NPropSets + Init%NPropB = Init%NPropSetsB else if (Init%NDiv > 1) then @@ -278,32 +474,44 @@ SUBROUTINE SD_Discrt(Init,p, ErrStat, ErrMsg) ! Initialize Temp arrays that will contain user inputs + input from the subdivided members ! We don't know how many properties will be needed, so allocated to size MaxNProp - MaxNProp = Init%NPropSets + Init%NElem*NNE ! Maximum possible number of property sets (temp): This is property set per element node, for all elements (bjj, added Init%NPropSets to account for possibility of entering many unused prop sets) + MaxNProp = Init%NPropSetsB + Init%NElem*NNE ! Maximum possible number of property sets (temp): This is property set per element node, for all elements (bjj, added Init%NPropSets to account for possibility of entering many unused prop sets) CALL AllocAry(TempMembers, p%NMembers, MembersCol , 'TempMembers', ErrStat2, ErrMsg2); if(Failed()) return - CALL AllocAry(TempProps, MaxNProp, PropSetsCol,'TempProps', ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(TempProps, MaxNProp, PropSetsBCol,'TempProps', ErrStat2, ErrMsg2); if(Failed()) return TempProps = -9999. - TempMembers = p%Elems(1:p%NMembers,:) - TempProps(1:Init%NPropSets, :) = Init%PropSets + TempMembers = p%Elems(1:p%NMembers,:) + TempProps(1:Init%NPropSetsB, :) = Init%PropSetsB + p%Elems(:,:) = -9999. ! Reinitialized. Elements will be ordered by member subdivisions (see setNewElem) kelem = 0 knode = Init%NJoints - kprop = Init%NPropSets + kprop = Init%NPropSetsB DO I = 1, p%NMembers !the first p%NMembers rows of p%Elems contain the element information ! Member data Node1 = TempMembers(I, 2) Node2 = TempMembers(I, 3) Prop1 = TempMembers(I, iMProp ) Prop2 = TempMembers(I, iMProp+1) - + eType = TempMembers(I, iMType ) + IF ( Node1==Node2 ) THEN CALL Fatal(' Same starting and ending node in the member.') RETURN ENDIF - + if (eType/=idMemberBeam) then + ! --- Cables and rigid links are not subdivided and have same prop at nodes + ! No need to create new properties or new nodes + Init%MemberNodes(I, 1) = Node1 + Init%MemberNodes(I, 2) = Node2 + kelem = kelem + 1 + CALL SetNewElem(kelem, Node1, Node2, eType, Prop1, Prop1, p) + cycle + endif + + ! --- Subdivision of beams Init%MemberNodes(I, 1) = Node1 Init%MemberNodes(I, Init%NDiv+1) = Node2 - + IF ( ( .not. EqualRealNos(TempProps(Prop1, 2),TempProps(Prop2, 2) ) ) & .OR. ( .not. EqualRealNos(TempProps(Prop1, 3),TempProps(Prop2, 3) ) ) & .OR. ( .not. EqualRealNos(TempProps(Prop1, 4),TempProps(Prop2, 4) ) ) ) THEN @@ -339,19 +547,19 @@ SUBROUTINE SD_Discrt(Init,p, ErrStat, ErrMsg) ! node connect to Node1 knode = knode + 1 Init%MemberNodes(I, 2) = knode - CALL SetNewNode(knode, x1+dx, y1+dy, z1+dz, Init) - + CALL SetNewNode(knode, x1+dx, y1+dy, z1+dz, Init); if (ErrStat>ErrID_None) return; + IF ( CreateNewProp ) THEN ! create a new property set ! k, E, G, rho, d, t, Init kprop = kprop + 1 CALL SetNewProp(kprop, TempProps(Prop1, 2), TempProps(Prop1, 3), TempProps(Prop1, 4), d1+dd, t1+dt, TempProps) kelem = kelem + 1 - CALL SetNewElem(kelem, Node1, knode, Prop1, kprop, p) - nprop = kprop + CALL SetNewElem(kelem, Node1, knode, eType, Prop1, kprop, p); if (ErrStat>ErrID_None) return; + nprop = kprop ELSE kelem = kelem + 1 - CALL SetNewElem(kelem, Node1, knode, Prop1, Prop1, p) + CALL SetNewElem(kelem, Node1, knode, eType, Prop1, Prop1, p); if (ErrStat>ErrID_None) return; nprop = Prop1 ENDIF @@ -360,45 +568,53 @@ SUBROUTINE SD_Discrt(Init,p, ErrStat, ErrMsg) knode = knode + 1 Init%MemberNodes(I, J+1) = knode - CALL SetNewNode(knode, x1 + J*dx, y1 + J*dy, z1 + J*dz, Init) + CALL SetNewNode(knode, x1 + J*dx, y1 + J*dy, z1 + J*dz, Init) ! Set Init%Nodes(knode,:) IF ( CreateNewProp ) THEN ! create a new property set - ! k, E, G, rho, d, t, Init + ! k, E, G, rho, d, t, Init kprop = kprop + 1 - CALL SetNewProp(kprop, TempProps(Prop1, 2), TempProps(Prop1, 3),& - Init%PropSets(Prop1, 4), d1 + J*dd, t1 + J*dt, & - TempProps) + CALL SetNewProp(kprop, TempProps(Prop1, 2), TempProps(Prop1, 3), Init%PropSetsB(Prop1, 4), d1 + J*dd, t1 + J*dt, TempProps) kelem = kelem + 1 - CALL SetNewElem(kelem, knode-1, knode, nprop, kprop, p) - nprop = kprop + CALL SetNewElem(kelem, knode-1, knode, eType, nprop, kprop, p); if (ErrStat>ErrID_None) return; + nprop = kprop ELSE kelem = kelem + 1 - CALL SetNewElem(kelem, knode-1, knode, nprop, nprop, p) - + CALL SetNewElem(kelem, knode-1, knode, eType, nprop, nprop, p); if (ErrStat>ErrID_None) return; ENDIF ENDDO ! the element connect to Node2 kelem = kelem + 1 - CALL SetNewElem(kelem, knode, Node2, nprop, Prop2, p) - + CALL SetNewElem(kelem, knode, Node2, eType, nprop, Prop2, p); if (ErrStat>ErrID_None) return; ENDDO ! loop over all members ! - Init%NProp = kprop + Init%NPropB = kprop + if(knode/=size(Init%Nodes,1)) then + call Fatal('Implementation error. Number of nodes wrongly estimated.');return + endif + if(kelem/=size(p%Elems,1)) then + call Fatal('Implementation error. Number of elements wrongly estimated.');return + endif ENDIF ! if NDiv is greater than 1 ! set the props in Init - CALL AllocAry(Init%Props, Init%NProp, PropSetsCol, 'Init%PropsBeams', ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(Init%PropsB, Init%NPropB, PropSetsBCol, 'Init%PropsBeams', ErrStat2, ErrMsg2); if(Failed()) return if (Init%NDiv==1) then - Init%Props(1:Init%NProp, 1:PropSetsCol) = Init%PropSets(1:Init%NProp, 1:PropSetsCol) + Init%PropsB(1:Init%NPropB, 1:PropSetsBCol) = Init%PropSetsB(1:Init%NPropB, 1:PropSetsBCol) else if (Init%NDiv>1) then - Init%Props(1:Init%NProp, 1:PropSetsCol) = TempProps(1:Init%NProp, 1:PropSetsCol) + Init%PropsB(1:Init%NPropB, 1:PropSetsBCol) = TempProps(1:Init%NPropB, 1:PropSetsBCol) endif - !Init%Props(1:kprop, 1:Init%PropSetsCol) = TempProps - !Init%Props = TempProps(1:Init%NProp, :) !!RRD fixed it on 1/23/14 to account for NDIV=1 + + ! --- Cables and rigid link properties (these cannot be subdivided, so direct copy of inputs) + Init%NPropC = Init%NPropSetsC + Init%NPropR = Init%NPropSetsR + CALL AllocAry(Init%PropsC, Init%NPropC, PropSetsCCol, 'Init%PropsCable', ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(Init%PropsR, Init%NPropR, PropSetsRCol, 'Init%PropsRigid', ErrStat2, ErrMsg2); if(Failed()) return + Init%PropsC(1:Init%NPropC, 1:PropSetsCCol) = Init%PropSetsC(1:Init%NPropC, 1:PropSetsCCol) + Init%PropsR(1:Init%NPropR, 1:PropSetsRCol) = Init%PropSetsR(1:Init%NPropR, 1:PropSetsRCol) CALL CleanUp_Discrt() @@ -421,258 +637,453 @@ SUBROUTINE CleanUp_Discrt() IF (ALLOCATED(TempMembers)) DEALLOCATE(TempMembers) END SUBROUTINE CleanUp_Discrt -END SUBROUTINE SD_Discrt - - -!> Returns index of val in Array (val is an integer!) -! NOTE: in the future use intrinsinc function findloc -FUNCTION FINDLOCI_ReKi(Array, Val) result(i) - real(ReKi) , dimension(:), intent(in) :: Array !< Array to search in - integer(IntKi), intent(in) :: val !< Val - integer(IntKi) :: i !< Index of joint in joint table - logical :: found - i = 1 - do while ( i <= size(Array) ) - if ( Val == NINT(Array(i)) ) THEN - return ! Exit when found - else - i = i + 1 + !> Set properties of node k + SUBROUTINE SetNewNode(k, x, y, z, Init) + TYPE(SD_InitType), INTENT(INOUT) :: Init + INTEGER, INTENT(IN) :: k + REAL(ReKi), INTENT(IN) :: x, y, z + if (k>size(Init%Nodes,1)) then + call Fatal('Implementation Error. Attempt to add more node than space allocated.'); + return endif - enddo - i=-1 -END FUNCTION -!> Returns index of val in Array (val is an integer!) -! NOTE: in the future use intrinsinc function findloc -FUNCTION FINDLOCI_IntKi(Array, Val) result(i) - integer(IntKi), dimension(:), intent(in) :: Array !< Array to search in - integer(IntKi), intent(in) :: val !< Val - integer(IntKi) :: i !< Index of joint in joint table - logical :: found - i = 1 - do while ( i <= size(Array) ) - if ( Val == Array(i) ) THEN - return ! Exit when found - else - i = i + 1 + Init%Nodes(k, 1) = k + Init%Nodes(k, 2) = x + Init%Nodes(k, 3) = y + Init%Nodes(k, 4) = z + Init%Nodes(k, iJointType) = idJointCantilever ! Note: all added nodes are Cantilever + ! Properties below are for non-cantilever joints + Init%Nodes(k, iJointDir:iJointDir+2) = 0.0_ReKi ! NOTE: irrelevant for cantilever nodes + Init%Nodes(k, iJointStiff) = 0.0_ReKi ! NOTE: irrelevant for cantilever nodes + END SUBROUTINE SetNewNode + + !> Set properties of element k + SUBROUTINE SetNewElem(k, n1, n2, etype, p1, p2, p) + INTEGER, INTENT(IN ) :: k + INTEGER, INTENT(IN ) :: n1 + INTEGER, INTENT(IN ) :: n2 + INTEGER, INTENT(IN ) :: eType + INTEGER, INTENT(IN ) :: p1 + INTEGER, INTENT(IN ) :: p2 + TYPE(SD_ParameterType), INTENT(INOUT) :: p + if (k>size(p%Elems,1)) then + call Fatal('Implementation Error. Attempt to add more element than space allocated.'); + return endif - enddo - i=-1 -END FUNCTION + p%Elems(k, 1) = k + p%Elems(k, 2) = n1 + p%Elems(k, 3) = n2 + p%Elems(k, iMProp ) = p1 + p%Elems(k, iMProp+1) = p2 + p%Elems(k, iMType) = eType + END SUBROUTINE SetNewElem + + !> Set material properties of element k, NOTE: this is only for a beam + SUBROUTINE SetNewProp(k, E, G, rho, d, t, TempProps) + INTEGER , INTENT(IN) :: k + REAL(ReKi), INTENT(IN) :: E, G, rho, d, t + REAL(ReKi), INTENT(INOUT):: TempProps(:, :) + if (k>size(TempProps,1)) then + call Fatal('Implementation Error. Attempt to add more properties than space allocated.'); + return + endif + TempProps(k, 1) = k + TempProps(k, 2) = E + TempProps(k, 3) = G + TempProps(k, 4) = rho + TempProps(k, 5) = d + TempProps(k, 6) = t + END SUBROUTINE SetNewProp +END SUBROUTINE SD_Discrt -!------------------------------------------------------------------------------------------------------ -!> Set properties of node k -SUBROUTINE SetNewNode(k, x, y, z, Init) - TYPE(SD_InitType), INTENT(INOUT) :: Init - INTEGER, INTENT(IN) :: k - REAL(ReKi), INTENT(IN) :: x, y, z - - Init%Nodes(k, 1) = k - Init%Nodes(k, 2) = x - Init%Nodes(k, 3) = y - Init%Nodes(k, 4) = z -END SUBROUTINE SetNewNode +!> Store relative vector between nodes and TP point, to later compute Guyan rigid body motion +subroutine StoreNodesRelPos(Init, p, ErrStat, ErrMsg) + type(SD_InitType), intent(in ) :: Init + type(SD_ParameterType), intent(inout) :: p + integer(IntKi), intent(out) :: ErrStat ! Error status of the operation + character(*), intent(out) :: ErrMsg ! Error message if ErrStat /= ErrID_None + integer(Intki) :: i + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + ErrStat = ErrID_None + ErrMsg = "" -!------------------------------------------------------------------------------------------------------ -!> Set properties of element k -SUBROUTINE SetNewElem(k, n1, n2, p1, p2, p) - INTEGER, INTENT(IN ) :: k - INTEGER, INTENT(IN ) :: n1 - INTEGER, INTENT(IN ) :: n2 - INTEGER, INTENT(IN ) :: p1 - INTEGER, INTENT(IN ) :: p2 - TYPE(SD_ParameterType), INTENT(INOUT) :: p - - p%Elems(k, 1) = k - p%Elems(k, 2) = n1 - p%Elems(k, 3) = n2 - p%Elems(k, iMProp ) = p1 - p%Elems(k, iMProp+1) = p2 + ! NOTE: using efficient memory order + call AllocAry(p%DP0, 3, size(Init%Nodes,1), 'DP0', ErrStat2, ErrMsg2); if(Failed()) return + + do i = 1, size(Init%Nodes,1) + p%DP0(1, i) = Init%Nodes(i, 2) - Init%TP_RefPoint(1) + p%DP0(2, i) = Init%Nodes(i, 3) - Init%TP_RefPoint(2) + p%DP0(3, i) = Init%Nodes(i, 4) - Init%TP_RefPoint(3) + enddo -END SUBROUTINE SetNewElem +contains + logical function Failed() + call SetErrStat(ErrStat2, ErrMsg2, Errstat, ErrMsg, 'StoreNodesRelPos') + failed = ErrStat >= AbortErrLev + end function Failed +end subroutine StoreNodesRelPos -!------------------------------------------------------------------------------------------------------ -!> Set material properties of element k -SUBROUTINE SetNewProp(k, E, G, rho, d, t, TempProps) - INTEGER , INTENT(IN) :: k - REAL(ReKi), INTENT(IN) :: E, G, rho, d, t - REAL(ReKi), INTENT(INOUT):: TempProps(:, :) - - TempProps(k, 1) = k - TempProps(k, 2) = E - TempProps(k, 3) = G - TempProps(k, 4) = rho - TempProps(k, 5) = d - TempProps(k, 6) = t -END SUBROUTINE SetNewProp !------------------------------------------------------------------------------------------------------ -!> Assemble stiffness and mass matrix, and gravity force vector -SUBROUTINE AssembleKM(Init,p, ErrStat, ErrMsg) - TYPE(SD_InitType), INTENT(INOUT) :: Init +!> Set Element properties p%ElemProps, different properties are set depening on element type.. +SUBROUTINE SetElementProperties(Init, p, ErrStat, ErrMsg) + TYPE(SD_InitType), INTENT(IN ) :: Init TYPE(SD_ParameterType), INTENT(INOUT) :: p INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None ! Local variables - INTEGER :: I, J, K, Jn, Kn - INTEGER, PARAMETER :: NNE=2 ! number of nodes in one element, fixed to 2 + INTEGER :: I INTEGER :: N1, N2 ! starting node and ending node in the element INTEGER :: P1, P2 ! property set numbers for starting and ending nodes REAL(ReKi) :: D1, D2, t1, t2, E, G, rho ! properties of a section - REAL(ReKi) :: x1, y1, z1, x2, y2, z2 ! coordinates of the nodes - REAL(ReKi) :: DirCos(3, 3) ! direction cosine matrices + REAL(FEKi) :: DirCos(3, 3) ! direction cosine matrices REAL(ReKi) :: L ! length of the element REAL(ReKi) :: r1, r2, t, Iyy, Jzz, Ixx, A, kappa, nu, ratioSq, D_inner, D_outer LOGICAL :: shear - REAL(ReKi), ALLOCATABLE :: Ke(:,:), Me(:, :), FGe(:) ! element stiffness and mass matrices gravity force vector - INTEGER, DIMENSION(NNE) :: nn ! node number in element - INTEGER :: r + INTEGER(IntKi) :: eType !< Member type + REAL(ReKi) :: Point1(3), Point2(3) ! (x,y,z) positions of two nodes making up an element INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - + ErrMsg = "" + ErrStat = ErrID_None + + ALLOCATE( p%ElemProps(Init%NElem), STAT=ErrStat2); ErrMsg2='Error allocating p%ElemProps' + if(Failed()) return - ! for current application - if (Init%FEMMod == 2) THEN ! tapered Euler-Bernoulli - CALL Fatal ('FEMMod = 2 is not implemented.') - return - elseif (Init%FEMMod == 4) THEN ! tapered Timoshenko - CALL Fatal ('FEMMod = 2 is not implemented.') - return - elseif ((Init%FEMMod == 1) .or. (Init%FEMMod == 3)) THEN ! - ! 1: uniform Euler-Bernouli, 3: uniform Timoshenko + ! Loop over all elements and set ElementProperties + do I = 1, Init%NElem + N1 = p%Elems(I, 2) + N2 = p%Elems(I, 3) + + P1 = p%Elems(I, iMProp ) + P2 = p%Elems(I, iMProp+1) + eType = p%Elems(I, iMType) + + ! --- Properties common to all element types: L, DirCos (and Area and rho) + Point1 = Init%Nodes(N1,2:4) + Point2 = Init%Nodes(N2,2:4) + CALL GetDirCos(Point1, Point2, DirCos, L, ErrStat2, ErrMsg2); if(Failed()) return ! L and DirCos + p%ElemProps(i)%eType = eType + p%ElemProps(i)%Length = L + p%ElemProps(i)%DirCos = DirCos + + ! Init to excessive values to detect any issue + p%ElemProps(i)%Ixx = -9.99e+36 + p%ElemProps(i)%Iyy = -9.99e+36 + p%ElemProps(i)%Jzz = -9.99e+36 + p%ElemProps(i)%Kappa = -9.99e+36 + p%ElemProps(i)%YoungE = -9.99e+36 + p%ElemProps(i)%ShearG = -9.99e+36 + p%ElemProps(i)%Area = -9.99e+36 + p%ElemProps(i)%Rho = -9.99e+36 + p%ElemProps(i)%T0 = -9.99e+36 + + ! --- Properties that are specific to some elements + if (eType==idMemberBeam) then + E = Init%PropsB(P1, 2) + G = Init%PropsB(P1, 3) + rho = Init%PropsB(P1, 4) + D1 = Init%PropsB(P1, 5) + t1 = Init%PropsB(P1, 6) + D2 = Init%PropsB(P2, 5) + t2 = Init%PropsB(P2, 6) + r1 = 0.25*(D1 + D2) + t = 0.5*(t1+t2) + if ( EqualRealNos(t, 0.0_ReKi) ) then + r2 = 0 + else + r2 = r1 - t + endif + A = Pi_D*(r1*r1-r2*r2) + Ixx = 0.25*Pi_D*(r1**4-r2**4) + Iyy = Ixx + Jzz = 2.0*Ixx + + if( Init%FEMMod == 1 ) then ! uniform Euler-Bernoulli + Shear = .false. + kappa = 0 + elseif( Init%FEMMod == 3 ) then ! uniform Timoshenko + Shear = .true. + ! kappa = 0.53 + ! equation 13 (Steinboeck et al) in SubDyn Theory Manual + nu = E / (2.0_ReKi*G) - 1.0_ReKi + D_outer = 2.0_ReKi * r1 ! average (outer) diameter + D_inner = D_outer - 2*t ! remove 2x thickness to get inner diameter + ratioSq = ( D_inner / D_outer)**2 + kappa = ( 6.0 * (1.0 + nu) **2 * (1.0 + ratioSq)**2 ) & + / ( ( 1.0 + ratioSq )**2 * ( 7.0 + 14.0*nu + 8.0*nu**2 ) + 4.0 * ratioSq * ( 5.0 + 10.0*nu + 4.0 *nu**2 ) ) + endif + ! Storing Beam specific properties + p%ElemProps(i)%Ixx = Ixx + p%ElemProps(i)%Iyy = Iyy + p%ElemProps(i)%Jzz = Jzz + p%ElemProps(i)%Shear = Shear + p%ElemProps(i)%kappa = kappa + p%ElemProps(i)%YoungE = E + p%ElemProps(i)%ShearG = G + p%ElemProps(i)%Area = A + p%ElemProps(i)%Rho = rho + + else if (eType==idMemberCable) then + if (DEV_VERSION) then + print*,'Member',I,'is a cable' + endif + p%ElemProps(i)%Area = 1 ! Arbitrary set to 1 + p%ElemProps(i)%YoungE = Init%PropsC(P1, 2)/1 ! Young's modulus, E=EA/A [N/m^2] + p%ElemProps(i)%Rho = Init%PropsC(P1, 3) ! Material density [kg/m3] + p%ElemProps(i)%T0 = Init%PropsC(P1, 4) ! Pretension force [N] + + else if (eType==idMemberRigid) then + if (DEV_VERSION) then + print*,'Member',I,'is a rigid link' + endif + p%ElemProps(i)%Area = 1 ! Arbitrary set to 1 + p%ElemProps(i)%Rho = Init%PropsR(P1, 2) + + else + ! Should not happen + print*,'Element type unknown',eType + STOP + end if + enddo ! I end loop over elements +CONTAINS + LOGICAL FUNCTION Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SetElementProperties') + Failed = ErrStat >= AbortErrLev + END FUNCTION Failed +END SUBROUTINE SetElementProperties + + +!> Distribute global DOF indices corresponding to Nodes, Elements, BCs, Reactions +!! For Cantilever Joint -> Condensation into 3 translational and 3 rotational DOFs +!! For other joint type -> Condensation of the 3 translational DOF +!! -> Keeping 3 rotational DOF for each memeber connected to the joint +SUBROUTINE DistributeDOF(Init, p, ErrStat, ErrMsg) + use IntegerList, only: init_list, len + TYPE(SD_InitType), INTENT(INOUT) :: Init + TYPE(SD_ParameterType), INTENT(INOUT) :: p + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + integer(IntKi) :: iNode, k + integer(IntKi) :: iPrev ! Cumulative counter over the global DOF + integer(IntKi) :: iElem ! + integer(IntKi) :: idElem + integer(IntKi) :: nRot ! Number of rotational DOFs (multiple of 3) to be used at the joint + integer(IntKi) :: iOff ! Offset, 0 or 6, depending if node 1 or node 2 + integer(IntKi), dimension(6) :: DOFNode_Old + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + ErrMsg = "" + ErrStat = ErrID_None + + allocate(p%NodesDOF(1:p%nNodes), stat=ErrStat2) + ErrMsg2="Error allocating NodesDOF" + if(Failed()) return + + call AllocAry(p%ElemsDOF, 12, Init%NElem, 'ElemsDOF', ErrStat2, ErrMsg2); if(Failed()) return; + p%ElemsDOF=-9999 + + iPrev =0 + do iNode = 1, p%nNodes + ! --- Distribute to joints iPrev + 1:6, or, iPrev + 1:(3+3m) + if (int(Init%Nodes(iNode,iJointType)) == idJointCantilever ) then + nRot=3 + else + nRot= 3*Init%NodesConnE(iNode,1) ! Col1: number of elements connected to this joint + endif + call init_list(p%NodesDOF(iNode), 3+nRot, iPrev, ErrStat2, ErrMsg2) + p%NodesDOF(iNode)%List(1:(3+nRot)) = (/ ((iElem+iPrev), iElem=1,3+nRot) /) + + ! --- Distribute to members + do iElem = 1, Init%NodesConnE(iNode,1) ! members connected to joint iJ + idElem = Init%NodesConnE(iNode,iElem+1) + if (iNode == p%Elems(idElem, 2)) then ! Current joint is Elem node 1 + iOff = 0 + else ! Current joint is Elem node 2 + iOff = 6 + endif + p%ElemsDOF(iOff+1:iOff+3, idElem) = p%NodesDOF(iNode)%List(1:3) + if (int(Init%Nodes(iNode,iJointType)) == idJointCantilever ) then + p%ElemsDOF(iOff+4:iOff+6, idElem) = p%NodesDOF(iNode)%List(4:6) + else + p%ElemsDOF(iOff+4:iOff+6, idElem) = p%NodesDOF(iNode)%List(3*iElem+1:3*iElem+3) + endif + enddo ! iElem, loop on members connect to joint + iPrev = iPrev + len(p%NodesDOF(iNode)) + enddo ! iNode, loop on joints + + ! --- Safety check + if (any(p%ElemsDOF<0)) then + ErrStat=ErrID_Fatal + ErrMsg ="Implementation error in Distribute DOF, some member DOF were not allocated" + endif + + ! --- Safety check (backward compatibility, only valid if all joints are Cantilever) + if (p%nNodes == count( Init%Nodes(:, iJointType) == idJointCantilever)) then + do idElem = 1, Init%NElem + iNode = p%Elems(idElem, 2) + DOFNode_Old= (/ ((iNode*6-5+k), k=0,5) /) + if ( any( (p%ElemsDOF(1:6, idElem) /= DOFNode_Old)) ) then + ErrStat=ErrID_Fatal + ErrMsg ="Implementation error in Distribute DOF, DOF indices have changed for iElem="//trim(Num2LStr(idElem)) + return + endif + enddo else - CALL Fatal('FEMMod is not valid. Please choose from 1, 2, 3, and 4. ') - return + ! Safety check does not apply if some joints are non-cantilever endif - - ! total degrees of freedom of the system - Init%TDOF = 6*Init%NNode - - ALLOCATE( p%ElemProps(Init%NElem), STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL Fatal('Error allocating p%ElemProps') - return - ENDIF - CALL AllocAry( Ke, NNE*6, NNE*6 , 'Ke', ErrStat2, ErrMsg2); if(Failed()) return; ! element stiffness matrix - CALL AllocAry( Me, NNE*6, NNE*6 , 'Me', ErrStat2, ErrMsg2); if(Failed()) return; ! element mass matrix - CALL AllocAry( FGe, NNE*6, 'FGe', ErrStat2, ErrMsg2); if(Failed()) return; ! element gravity force vector - CALL AllocAry( Init%K, Init%TDOF, Init%TDOF , 'Init%K', ErrStat2, ErrMsg2); if(Failed()) return; ! system stiffness matrix - CALL AllocAry( Init%m, Init%TDOF, Init%TDOF , 'Init%M', ErrStat2, ErrMsg2); if(Failed()) return; ! system mass matrix - CALL AllocAry( Init%FG,Init%TDOF, 'Init%FG', ErrStat2, ErrMsg2); if(Failed()) return; ! system gravity force vector - Init%K = 0.0_ReKi - Init%M = 0.0_ReKi - Init%FG = 0.0_ReKi +CONTAINS + LOGICAL FUNCTION Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SetElementProperties') + Failed = ErrStat >= AbortErrLev + END FUNCTION Failed - - ! loop over all elements - DO I = 1, Init%NElem - - DO J = 1, NNE - NN(J) = p%Elems(I, J + 1) +END SUBROUTINE DistributeDOF + + +!> Checks reaction BC, adn remap 0s and 1s +SUBROUTINE CheckBCs(p, ErrStat, ErrMsg) + TYPE(SD_ParameterType),INTENT(INOUT) :: p + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + INTEGER(IntKi) :: I, J, iNode + ErrMsg = "" + ErrStat = ErrID_None + DO I = 1, p%nNodes_C + iNode = p%Nodes_C(I,1) ! Node index + DO J = 1, 6 + if (p%Nodes_C(I,J+1)==1) then ! User input 1=Constrained/Fixed (should be eliminated) + p%Nodes_C(I, J+1) = idBC_Fixed + else if (p%Nodes_C(I,J+1)==0) then ! User input 0=Free, fill be part of Internal DOF + p%Nodes_C(I, J+1) = idBC_Internal + else if (p%Nodes_C(I,J+1)==2) then ! User input 2=Leader DOF + p%Nodes_C(I, J+1) = idBC_Leader + ErrStat=ErrID_Fatal + ErrMsg='BC 2 not allowed for now, node '//trim(Num2LStr(iNode)) + else + ErrStat=ErrID_Fatal + ErrMsg='Wrong boundary condition input for reaction node '//trim(Num2LStr(iNode)) + endif + ENDDO + ENDDO +END SUBROUTINE CheckBCs + +!> Check interface inputs, and remap 0s and 1s +SUBROUTINE CheckIntf(p, ErrStat, ErrMsg) + TYPE(SD_ParameterType),INTENT(INOUT) :: p + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + INTEGER(IntKi) :: I, J, iNode + ErrMsg = "" + ErrStat = ErrID_None + DO I = 1, p%nNodes_I + iNode = p%Nodes_I(I,1) ! Node index + DO J = 1, 6 ! ItfTDXss ItfTDYss ItfTDZss ItfRDXss ItfRDYss ItfRDZss + if (p%Nodes_I(I,J+1)==1) then ! User input 1=Leader DOF + p%Nodes_I(I,J+1) = idBC_Leader + elseif (p%Nodes_I(I,J+1)==0) then ! User input 0=Fixed DOF + p%Nodes_I(I,J+1) = idBC_Fixed + ErrStat = ErrID_Fatal + ErrMsg = 'Fixed boundary condition not yet supported for interface nodes, node:'//trim(Num2LStr(iNode)) + else + ErrStat = ErrID_Fatal + ErrMsg = 'Wrong boundary condition input for interface node'//trim(Num2LStr(iNode)) + endif ENDDO + ENDDO +END SUBROUTINE CheckIntf + + +!------------------------------------------------------------------------------------------------------ +!> Assemble stiffness and mass matrix, and gravity force vector +SUBROUTINE AssembleKM(Init, p, ErrStat, ErrMsg) + TYPE(SD_InitType), INTENT(INOUT) :: Init + TYPE(SD_ParameterType), INTENT(INOUT) :: p + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! Local variables + INTEGER :: I, J, K + INTEGER :: iGlob + REAL(FEKi) :: Ke(12,12), Me(12, 12), FGe(12) ! element stiffness and mass matrices gravity force vector + REAL(FEKi) :: FCe(12) ! Pretension force from cable element + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + INTEGER(IntKi) :: iNode !< Node index + integer(IntKi), dimension(12) :: IDOF ! 12 DOF indices in global unconstrained system + real(ReKi), dimension(6,6) :: M66 ! Mass matrix of an element node + real(ReKi) :: m, x, y, z, Jxx, Jyy, Jzz, Jxy, Jxz, Jyz + INTEGER :: jGlob, kGlob + ErrMsg = "" + ErrStat = ErrID_None - N1 = p%Elems(I, 2) - N2 = p%Elems(I, NNE + 1) - - P1 = p%Elems(I, NNE + 2) - P2 = p%Elems(I, NNE + 3) - - E = Init%Props(P1, 2) - G = Init%Props(P1, 3) - rho = Init%Props(P1, 4) - D1 = Init%Props(P1, 5) - t1 = Init%Props(P1, 6) - D2 = Init%Props(P2, 5) - t2 = Init%Props(P2, 6) - - x1 = Init%Nodes(N1, 2) - y1 = Init%Nodes(N1, 3) - z1 = Init%Nodes(N1, 4) - - x2 = Init%Nodes(N2, 2) - y2 = Init%Nodes(N2, 3) - z2 = Init%Nodes(N2, 4) + ! total unconstrained degrees of freedom of the system + p%nDOF = nDOF_Unconstrained() + if (DEV_VERSION) then + print*,'nDOF_unconstrained:',p%nDOF, ' (if all Cantilever, it would be: ',6*p%nNodes,')' + endif - CALL GetDirCos(X1, Y1, Z1, X2, Y2, Z2, DirCos, L, ErrStat2, ErrMsg2); if(Failed()) return - - r1 = 0.25*(D1 + D2) - t = 0.5*(t1+t2) - - IF ( EqualRealNos(t, 0.0_ReKi) ) THEN - r2 = 0 - ELSE - r2 = r1 - t - ENDIF - - A = Pi_D*(r1*r1-r2*r2) - Ixx = 0.25*Pi_D*(r1**4-r2**4) - Iyy = Ixx - Jzz = 2.0*Ixx - - IF( Init%FEMMod == 1 ) THEN ! uniform Euler-Bernoulli - Shear = .false. - kappa = 0 - ELSEIF( Init%FEMMod == 3 ) THEN ! uniform Timoshenko - Shear = .true. - ! kappa = 0.53 - ! equation 13 (Steinboeck et al) in SubDyn Theory Manual - nu = E / (2.0_ReKi*G) - 1.0_ReKi - D_outer = 2.0_ReKi * r1 ! average (outer) diameter - D_inner = D_outer - 2*t ! remove 2x thickness to get inner diameter - ratioSq = ( D_inner / D_outer)**2 - kappa = ( 6.0 * (1.0 + nu) **2 * (1.0 + ratioSq)**2 ) & - / ( ( 1.0 + ratioSq )**2 * ( 7.0 + 14.0*nu + 8.0*nu**2 ) + 4.0 * ratioSq * ( 5.0 + 10.0*nu + 4.0 *nu**2 ) ) - ENDIF - - p%ElemProps(i)%Area = A - p%ElemProps(i)%Length = L - p%ElemProps(i)%Ixx = Ixx - p%ElemProps(i)%Iyy = Iyy - p%ElemProps(i)%Jzz = Jzz - p%ElemProps(i)%Shear = Shear - p%ElemProps(i)%kappa = kappa - p%ElemProps(i)%YoungE = E - p%ElemProps(i)%ShearG = G - p%ElemProps(i)%Rho = rho - p%ElemProps(i)%DirCos = DirCos - - CALL ElemK(A, L, Ixx, Iyy, Jzz, Shear, kappa, E, G, DirCos, Ke) - CALL ElemM(A, L, Ixx, Iyy, Jzz, rho, DirCos, Me) - CALL ElemG(A, L, rho, DirCos, FGe, Init%g) - - ! assemble element matrices to global matrices - DO J = 1, NNE - jn = nn(j) - Init%FG( (jn*6-5):(jn*6) ) = Init%FG( (jn*6-5):(jn*6) ) + FGe( (J*6-5):(J*6) ) - DO K = 1, NNE - kn = nn(k) - Init%K( (jn*6-5):(jn*6), (kn*6-5):(kn*6) ) = Init%K( (jn*6-5):(jn*6), (kn*6-5):(kn*6) ) + Ke( (J*6-5):(J*6), (K*6-5):(K*6) ) - Init%M( (jn*6-5):(jn*6), (kn*6-5):(kn*6) ) = Init%M( (jn*6-5):(jn*6), (kn*6-5):(kn*6) ) + Me( (J*6-5):(J*6), (K*6-5):(K*6) ) - ENDDO !K - ENDDO !J - ENDDO ! I end loop over elements + CALL AllocAry( Init%K, p%nDOF, p%nDOF , 'Init%K', ErrStat2, ErrMsg2); if(Failed()) return; ! system stiffness matrix + CALL AllocAry( Init%M, p%nDOF, p%nDOF , 'Init%M', ErrStat2, ErrMsg2); if(Failed()) return; ! system mass matrix + CALL AllocAry( p%FG, p%nDOF, 'p%FG' , ErrStat2, ErrMsg2); if(Failed()) return; ! system gravity force vector + Init%K = 0.0_FEKi + Init%M = 0.0_FEKi + p%FG = 0.0_FEKi + + ! loop over all elements, compute element matrices and assemble into global matrices + DO i = 1, Init%NElem + ! --- Element Me,Ke,Fg, Fce + CALL ElemM(p%ElemProps(i), Me) + CALL ElemK(p%ElemProps(i), Ke) + CALL ElemF(p%ElemProps(i), Init%g, FGe, FCe) + + ! --- Assembly in global unconstrained system + IDOF = p%ElemsDOF(1:12, i) + p%FG ( IDOF ) = p%FG( IDOF ) + FGe(1:12)+ FCe(1:12) ! Note: gravity and pretension cable forces + Init%K(IDOF, IDOF) = Init%K( IDOF, IDOF) + Ke(1:12,1:12) + Init%M(IDOF, IDOF) = Init%M( IDOF, IDOF) + Me(1:12,1:12) + ENDDO - ! add concentrated mass - DO I = 1, Init%NCMass - DO J = 1, 3 - r = ( NINT(Init%CMass(I, 1)) - 1 )*6 + J - Init%M(r, r) = Init%M(r, r) + Init%CMass(I, 2) - ENDDO - DO J = 4, 6 - r = ( NINT(Init%CMass(I, 1)) - 1 )*6 + J - Init%M(r, r) = Init%M(r, r) + Init%CMass(I, J-1) + ! Add concentrated mass to mass matrix + DO I = 1, Init%nCMass + iNode = NINT(Init%CMass(I, 1)) ! Note index where concentrated mass is to be added + ! Safety check (otherwise we might have more than 6 DOF) + if (Init%Nodes(iNode,iJointType) /= idJointCantilever) then + ErrMsg2='Concentrated mass is only for cantilever joints. Problematic node: '//trim(Num2LStr(iNode)); ErrStat2=ErrID_Fatal; + if(Failed()) return + endif + ! Mass matrix of a rigid body + M66 = 0.0_ReKi + m = Init%CMass(I,2) + Jxx = Init%CMass(I,3 ); Jxy = Init%CMass(I,6 ); x = Init%CMass(I,9 ); + Jyy = Init%CMass(I,4 ); Jxz = Init%CMass(I,7 ); y = Init%CMass(I,10); + Jzz = Init%CMass(I,5 ); Jyz = Init%CMass(I,8 ); z = Init%CMass(I,11); + M66(1 , :)=(/ m , 0._ReKi , 0._ReKi , 0._ReKi , z*m , -y*m /) + M66(2 , :)=(/ 0._ReKi , m , 0._ReKi , -z*m , 0._ReKi , x*m /) + M66(3 , :)=(/ 0._ReKi , 0._ReKi , m , y*m , -x*m , 0._ReKi /) + M66(4 , :)=(/ 0._ReKi , -z*m , y*m , Jxx + m*(y**2+z**2) , Jxy - m*x*y , Jxz - m*x*z /) + M66(5 , :)=(/ z*m , 0._ReKi , -x*m , Jxy - m*x*y , Jyy + m*(x**2+z**2) , Jyz - m*y*z /) + M66(6 , :)=(/ -y*m , x*m , 0._ReKi , Jxz - m*x*z , Jyz - m*y*z , Jzz + m*(x**2+y**2) /) + ! Adding + DO J = 1, 6 + jGlob = p%NodesDOF(iNode)%List(J) + DO K = 1, 6 + kGlob = p%NodesDOF(iNode)%List(K) + Init%M(jGlob, kGlob) = Init%M(jGlob, kGlob) + M66(J,K) + ENDDO ENDDO ENDDO ! Loop on concentrated mass - ! add concentrated mass induced gravity force - DO I = 1, Init%NCMass - r = ( NINT(Init%CMass(I, 1)) - 1 )*6 + 3 - Init%FG(r) = Init%FG(r) - Init%CMass(I, 2)*Init%g - ENDDO ! I concentrated mass induced gravity - + ! Add concentrated mass induced gravity force + DO I = 1, Init%nCMass + iNode = NINT(Init%CMass(I, 1)) ! Note index where concentrated mass is to be added + iGlob = p%NodesDOF(iNode)%List(3) ! uz + p%FG(iGlob) = p%FG(iGlob) - Init%CMass(I, 2)*Init%g + ENDDO + CALL CleanUp_AssembleKM() CONTAINS @@ -689,330 +1100,1013 @@ SUBROUTINE Fatal(ErrMsg_in) END SUBROUTINE Fatal SUBROUTINE CleanUp_AssembleKM() - IF(ALLOCATED(Ke )) DEALLOCATE(Ke ) - IF(ALLOCATED(Me )) DEALLOCATE(Me ) - IF(ALLOCATED(FGe)) DEALLOCATE(FGe) + !pass END SUBROUTINE CleanUp_AssembleKM + + INTEGER(IntKi) FUNCTION nDOF_Unconstrained() + integer(IntKi) :: i + integer(IntKi) :: m + nDOF_Unconstrained=0 + do i = 1,p%nNodes + if (int(Init%Nodes(i,iJointType)) == idJointCantilever ) then + nDOF_Unconstrained = nDOF_Unconstrained + 6 + else + m = Init%NodesConnE(i,1) ! Col1: number of elements connected to this joint + nDOF_Unconstrained = nDOF_Unconstrained + 3 + 3*m + endif + end do + END FUNCTION END SUBROUTINE AssembleKM -!------------------------------------------------------------------------------------------------------ -!> Computes directional cosine matrix DirCos -!! rrd: This should be from local to global -!! bjj: note that this is the transpose of what is normally considered the Direction Cosine Matrix -!! in the FAST framework. It seems to be used consistantly in the code (i.e., the transpose -!! of this matrix is used later). -SUBROUTINE GetDirCos(X1, Y1, Z1, X2, Y2, Z2, DirCos, L, ErrStat, ErrMsg) - REAL(ReKi) , INTENT(IN ) :: x1, y1, z1, x2, y2, z2 ! (x,y,z) positions of two nodes making up an element - REAL(ReKi) , INTENT( OUT) :: DirCos(3, 3) ! calculated direction cosine matrix - REAL(ReKi) , INTENT( OUT) :: L ! length of element - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - REAL(ReKi) :: Dx,Dy,Dz, Dxy ! distances between nodes +!> Map control cable index to control channel index +subroutine ControlCableMapping(Init, uInit, p, ErrStat, ErrMsg) + type(SD_InitType), intent(in ) :: Init !< init + type(SD_InputType), intent(inout) :: uInit !< init input guess + type(SD_ParameterType), intent(inout) :: p !< param + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + ! Local variables + integer(IntKi) :: i, nCC, idCProp, iElem !< index, number of controlable cables, id of Cable Prop + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + ErrMsg = "" + ErrStat = ErrID_None + + ! --- Count number of Controllable cables + nCC = 0 + do i = 1, size(p%ElemProps) + if (p%ElemProps(i)%eType==idMemberCable) then + idCProp= p%Elems(i,iMProp) + if (Init%PropsC(idCProp, 5 )>0) then + !print*,'Cable Element',i,'controllable with channel',Init%PropsC(idCProp, 5 ) + nCC=nCC+1 + endif + endif + enddo + if (nCC>0) then + call WrScr('Number of controllable cables: '//trim(num2lstr(nCC))) + endif + call AllocAry( p%CtrlElem2Channel, nCC, 2, 'p%CtrlElem2Channel', ErrStat2, ErrMsg2); if(Failed()) return; ! Constant cable force + + ! --- Store mapping + nCC = 0 + do i = 1, size(p%ElemProps) + if (p%ElemProps(i)%eType==idMemberCable) then + idCProp= p%Elems(i,iMProp) + if (Init%PropsC(idCProp, 5 )>0) then + nCC=nCC+1 + p%CtrlElem2Channel(nCC, 1) = i ! Element index (in p%Elems and p%ElemProps) + p%CtrlElem2Channel(nCC, 2) = Init%PropsC(idCProp,5) ! Control channel + endif + endif + enddo + + ! --- DeltaL Guess for inputs + if (allocated(uInit%CableDeltaL)) deallocate(uInit%CableDeltaL) + call AllocAry(uInit%CableDeltaL, nCC, 'uInit%CableDeltaL', ErrStat2, ErrMsg2); if(Failed()) return; + do i = 1, nCC + iElem = p%CtrlElem2Channel(i,1) + ! DeltaL 0 = - Le T0 / (EA + T0) = - Le eps0 / (1+eps0) + uInit%CableDeltaL(i) = - p%ElemProps(iElem)%Length * p%ElemProps(iElem)%T0 / (p%ElemProps(iElem)%YoungE*p%ElemProps(iElem)%Area + p%ElemProps(iElem)%T0) + enddo + +contains + logical function Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'ControlCableMapping') + Failed = ErrStat >= AbortErrLev + end function Failed +end subroutine ControlCableMapping + +!> Init for control Cable force +!! The change of cable forces due to the control is linear, so we just store a "unit" force vector +!! We will just scale this vector at each time step based on the control input (Tcontrol): +!! Fcontrol = (Tcontrol-T0) * Funit +!! We store it in "non-reduced" system since it will added to the external forces +SUBROUTINE ControlCableForceInit(p, m, ErrStat, ErrMsg) + TYPE(SD_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(SD_MiscVarType), INTENT(INOUT) :: m !< Misc + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! Local variables + INTEGER :: iCC, iElem + REAL(FEKi) :: FCe(12) ! Pretension force from cable element + integer(IntKi), dimension(12) :: IDOF ! 12 DOF indices in global unconstrained system + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 ErrMsg = "" ErrStat = ErrID_None - Dy=y2-y1 - Dx=x2-x1 - Dz=z2-z1 - Dxy = sqrt( Dx**2 + Dy**2 ) - L = sqrt( Dx**2 + Dy**2 + Dz**2) - - IF ( EqualRealNos(L, 0.0_ReKi) ) THEN - ErrMsg = ' Same starting and ending location in the element.' - ErrStat = ErrID_Fatal - RETURN - ENDIF - - IF ( EqualRealNos(Dxy, 0.0_ReKi) ) THEN - DirCos=0.0_ReKi ! whole matrix set to 0 - IF ( Dz < 0) THEN !x is kept along global x - DirCos(1, 1) = 1.0_ReKi - DirCos(2, 2) = -1.0_ReKi - DirCos(3, 3) = -1.0_ReKi - ELSE - DirCos(1, 1) = 1.0_ReKi - DirCos(2, 2) = 1.0_ReKi - DirCos(3, 3) = 1.0_ReKi - ENDIF - ELSE - DirCos(1, 1) = Dy/Dxy - DirCos(1, 2) = +Dx*Dz/(L*Dxy) - DirCos(1, 3) = Dx/L - - DirCos(2, 1) = -Dx/Dxy - DirCos(2, 2) = +Dz*Dy/(L*Dxy) - DirCos(2, 3) = Dy/L - - DirCos(3, 1) = 0.0_ReKi - DirCos(3, 2) = -Dxy/L - DirCos(3, 3) = +Dz/L - ENDIF + ! Allocating necessary arrays + CALL AllocAry( m%FC_unit , p%nDOF, 'm%FC0' , ErrStat2, ErrMsg2); if(Failed()) return; ! Control cable force + m%FC_unit = 0.0_ReKi + + ! loop over all elements, compute element matrices and assemble into global matrices + DO iCC = 1, size(p%CtrlElem2Channel,1) + iElem = p%CtrlElem2Channel(iCC,1) + CALL ElemF_Cable(1.0_ReKi, p%ElemProps(iElem)%DirCos, FCe) !< NOTE: using unitary load T0=1.0_ReKi + ! --- Assembly in global unconstrained system + IDOF = p%ElemsDOF(1:12, iElem) + m%FC_unit( IDOF ) = m%FC_unit( IDOF ) + FCe(1:12) + ENDDO + ! Transforming the vector into reduced, direct elimination system: + !FC_red = matmul(transpose(p%T_red), FC) + !if(allocated(FC)) deallocate(FC) -END SUBROUTINE GetDirCos +CONTAINS + LOGICAL FUNCTION Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'ControlCableForceInit') + Failed = ErrStat >= AbortErrLev + END FUNCTION Failed +END SUBROUTINE ControlCableForceInit + +!> Add soil stiffness and mass to global system matrices +!! Soil stiffness can come from two sources: +!! - "SSI" matrices (specified at reaction nodes) +!! - "Soil" matrices (specified at Initalization) +SUBROUTINE InsertSoilMatrices(M, K, NodesDOF, Init, p, ErrStat, ErrMsg, Substract) + real(FEKi), dimension(:,:), intent(inout) :: M + real(FEKi), dimension(:,:), intent(inout) :: K + type(IList),dimension(:), intent(in ) :: NodesDOF !< Map from Node Index to DOF lists + type(SD_InitType), intent(inout) :: Init ! TODO look for closest indices elsewhere + type(SD_ParameterType), intent(in ) :: p + integer(IntKi), intent( out) :: ErrStat ! Error status of the operation + character(*), intent( out) :: ErrMsg ! Error message if ErrStat /= ErrID_None + logical, optional, intent(in ) :: SubStract ! If present, and if true, substract instead of adding + integer :: I, J, iiNode, nDOF + integer :: iDOF, jDOF, iNode !< DOF and node indices + real(FEKi), dimension(6,6) :: K_soil, M_soil ! Auxiliary matrices for soil + real(ReKi) :: Dist + ErrMsg = "" + ErrStat = ErrID_None + ! --- SSI matrices + ! TODO consider doing the 21 -> 6x6 conversion while reading + ! 6x6 matrix goes to one node of one element only + do iiNode = 1, p%nNodes_C ! loop on constrained nodes + iNode = p%Nodes_C(iiNode,1) + nDOF=size(NodesDOF(iNode)%List) + if (nDOF/=6) then + ErrMsg='SSI soil matrix is to be inserted at SubDyn node '//Num2LStr(iNode)//', but this node has '//num2lstr(nDOF)//' DOFs'; + ErrStat=ErrID_Fatal; return + endif + call Array21_to_6by6(Init%SSIK(:,iiNode), K_soil) + call Array21_to_6by6(Init%SSIM(:,iiNode), M_soil) + if (present(Substract)) then + if (Substract) then + K_soil = - K_soil + M_soil = - M_soil + endif + endif + do I = 1, 6 + iDOF = NodesDOF(iNode)%List(I) ! DOF index + do J = 1, 6 + jDOF = NodesDOF(iNode)%List(J) ! DOF index + K(iDOF, jDOF) = K(iDOF, jDOF) + K_soil(I,J) + M(iDOF, jDOF) = M(iDOF, jDOF) + M_soil(I,J) + enddo + enddo + enddo + ! --- "Soil" matrices + if (allocated(Init%Soil_K)) then + do iiNode = 1,size(Init%Soil_Points,2) + ! --- Find closest node + call FindClosestNodes(Init%Soil_Points(1:3,iiNode), Init%Nodes, iNode, Dist); + if (Dist>0.1_ReKi) then + ErrMsg='Closest SubDyn Node is node '//Num2LStr(iNode)//', which is more than 0.1m away from soildyn point '//num2lstr(iiNode); + ErrStat=ErrID_Fatal; return + endif + Init%Soil_Nodes(iiNode) = iNode + ! --- Insert/remove from matrices + nDOF=size(NodesDOF(iNode)%List) + if (nDOF/=6) then + ErrMsg='Soil matrix is to be inserted at SubDyn node '//Num2LStr(iNode)//', but this node has '//num2lstr(nDOF)//' DOFs'; + ErrStat=ErrID_Fatal; return + endif + K_soil = Init%Soil_K(1:6,1:6,iiNode) + if (present(Substract)) then + if (Substract) then + K_soil = - K_soil + endif + endif + do I = 1, 6 + iDOF = NodesDOF(iNode)%List(I) ! DOF index + do J = 1, 6 + jDOF = NodesDOF(iNode)%List(J) ! DOF index + K(iDOF, jDOF) = K(iDOF, jDOF) + K_soil(I,J) + enddo + enddo + if (.not.present(Substract)) then + CALL WrScr(' Soil stiffness inserted at SubDyn node '//trim(Num2LStr(iNode))) + print*,' ',K_Soil(1,1:6) + print*,' ',K_Soil(2,1:6) + print*,' ',K_Soil(3,1:6) + print*,' ',K_Soil(4,1:6) + print*,' ',K_Soil(5,1:6) + print*,' ',K_Soil(6,1:6) + endif + enddo + endif +contains + !> Convert a flatten array of 21 values into a symmetric 6x6 matrix + SUBROUTINE Array21_to_6by6(A21, M66) + use NWTC_LAPACK, only: LAPACK_TPTTR + real(FEKi), dimension(21) , intent(in) :: A21 + real(FEKi), dimension(6,6), intent(out) :: M66 + integer :: j + M66 = 0.0_ReKi + ! Reconstruct from sparse elements + CALL LAPACK_TPTTR('U',6,A21,M66,6, ErrStat, ErrMsg) + ! Ensuring symmetry + do j=1,6 + M66(j,j) = M66(j,j)/2 + enddo + M66=M66+TRANSPOSE(M66) + END SUBROUTINE Array21_to_6by6 +END SUBROUTINE InsertSoilMatrices !------------------------------------------------------------------------------------------------------ -!> Element stiffness matrix for classical beam elements -!! shear is true -- non-tapered Timoshenko beam -!! shear is false -- non-tapered Euler-Bernoulli beam -SUBROUTINE ElemK(A, L, Ixx, Iyy, Jzz, Shear, kappa, E, G, DirCos, K) - REAL(ReKi), INTENT( IN) :: A, L, Ixx, Iyy, Jzz, E, G, kappa - REAL(ReKi), INTENT( IN) :: DirCos(3,3) - LOGICAL , INTENT( IN) :: Shear - REAL(ReKi), INTENT(OUT) :: K(12, 12) +!> Find closest node index to a point, returns distance as well +SUBROUTINE FindClosestNodes(Point, Nodes, iNode, Dist) + real(ReKi), dimension(3), intent(IN ) :: Point !< Point coordinates + real(ReKi), dimension(:,:), intent(IN ) :: Nodes !< List of nodes, Positions are in columns 2-4... + integer(IntKi), intent( OUT) :: iNode !< Index of closest node + real(ReKi), intent( OUT) :: Dist !< Distance from Point to node iNode + integer(IntKi) :: I + real(ReKi) :: min_dist, loc_dist + ! + min_dist=999999._ReKi + iNode=-1 + do i = 1, size(Nodes,1) + loc_dist = sqrt((Point(1) - Nodes(i,2))**2 + (Point(2) - Nodes(i,3))**2+ (Point(3) - Nodes(i,4))**2) + if (loc_dist Build transformation matrix T, such that x= T.x~ where x~ is the reduced vector of DOF +SUBROUTINE BuildTMatrix(Init, p, RA, RAm1, Tred, ErrStat, ErrMsg) + use IntegerList, only: init_list, find, pop, destroy_list, len + use IntegerList, only: print_list + TYPE(SD_InitType), INTENT(INOUT) :: Init + TYPE(SD_ParameterType),target,INTENT(INOUT) :: p + type(IList), dimension(:), INTENT(IN ) :: RA !< RA(a) = [e1,..,en] list of elements forming a rigid link assembly + integer(IntKi), dimension(:), INTENT(IN ) :: RAm1 !< RA^-1(e) = a , for a given element give the index of a rigid assembly + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + real(FEKi), dimension(:,:), allocatable :: Tred !< Transformation matrix for DOF elimination + ! Local + real(ReKi), dimension(:,:), allocatable :: Tc + integer(IntKi), dimension(:), allocatable :: INodesID !< List of unique nodes involved in Elements + integer(IntKi), dimension(:), allocatable :: IDOFOld !< + integer(IntKi), dimension(:), pointer :: IDOFNew !< + real(ReKi), dimension(6,6) :: I6 !< Identity matrix of size 6 + integer(IntKi) :: iPrev + type(IList) :: IRA !< list of rigid assembly indices to process + integer(IntKi) :: aID, ia ! assembly ID, and index in IRA + integer(IntKi) :: iNode + integer(IntKi) :: er !< Index of one rigid element belong to a rigid assembly + integer(IntKi) :: JType + integer(IntKi) :: I + integer(IntKi) :: nc !< Number of DOF after constraints applied + integer(IntKi) :: nj + real(ReKi) :: phat(3) !< Directional vector of the joint + type(IList), dimension(:), allocatable :: RA_DOFred ! DOF indices for each rigid assembly, in reduced system + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + ErrStat = ErrID_None + ErrMsg = "" + + ! --- Misc inits + nullify(IDOFNew) + I6(1:6,1:6)=0; do i = 1,6 ; I6(i,i)=1_ReKi; enddo ! I6 = eye(6) + allocate(p%NodesDOFred(1:p%nNodes), stat=ErrStat2); if(Failed()) return; ! Indices of DOF for each joint, in reduced system + allocate(RA_DOFred(1:size(RA)), stat=ErrStat2); if(Failed()) return; ! Indices of DOF for each rigid assmbly, in reduced system + + p%nDOF_red = nDOF_ConstraintReduced() + p%reduced = reductionNeeded() ! True if reduction needed, allow for optimization if not needed + + if (DEV_VERSION) then + print*,'nDOF constraint elim', p%nDOF_red , '/' , p%nDOF + endif + CALL AllocAry( Tred, p%nDOF, p%nDOF_red, 'p%T_red', ErrStat2, ErrMsg2); if(Failed()) return; ! system stiffness matrix + Tred=0 + call init_list(IRA, size(RA), 0, ErrStat2, ErrMsg2); if(Failed()) return; + IRA%List(1:size(RA)) = (/(ia , ia = 1,size(RA))/) + if (DEV_VERSION) then + call print_list(IRA, 'List of RA indices') + endif + + ! --- For each node: + ! - create list of indices I in the assembled vector of DOF + ! - create list of indices Itilde in the reduced vector of DOF + ! - increment iPrev by the number of DOF of Itilde + iPrev =0 + do iNode = 1, p%nNodes + if (allocated(Tc)) deallocate(Tc) + if (allocated(IDOFOld)) deallocate(IDOFOld) + JType = int(Init%Nodes(iNode,iJointType)) + if(JType == idJointCantilever ) then + if ( NodeHasRigidElem(iNode, Init, p, er)) then + ! --- Joint involved in a rigid link assembly + aID = RAm1(er) + if (aID<0) then + call Fatal('No rigid assembly attributed to node'//trim(Num2LStr(iNode))//'. RAm1 wrong'); return + endif + ia = find(IRA, aID, ErrStat2, ErrMsg2); if(Failed()) return + if (DEV_VERSION) then + print*,'Node',iNode, 'is involved in RA:', aID, '. Index in list of RA to process', ia + endif + if ( ia <= 0) then + ! This rigid assembly has already been processed + ! OLD: The DOF list is taken from the stored RA DOF list + ! call init_list(p%NodesDOFred(iNode), RA_DOFred(aID)%List, ErrStat2, ErrMsg2) + ! NEW: this node has no DOFs + call init_list(p%NodesDOFred(iNode), 0, 0, ErrStat2, ErrMsg2) + if (DEV_VERSION) then + print*,'The RA',aID,', has already been processed!' + print*,'N',iNode,'I ',p%NodesDOF(iNode)%List(1:6) + print*,'N',iNode,'It',RA_DOFred(aID)%List + endif + cycle ! We pass to the next joint + else + call RAElimination( RA(aID)%List, Tc, INodesID, Init, p, ErrStat2, ErrMsg2); if(Failed()) return; + aID = pop(IRA, ia, ErrStat2, ErrMsg2) ! this assembly has been processed + nj = size(INodesID) + allocate(IDOFOld(1:6*nj)) + do I=1, nj + IDOFOld( (I-1)*6+1 : I*6 ) = p%NodesDOF(INodesID(I))%List(1:6) + enddo + + ! Storing DOF list for this RA (Note: same as NodesDOFred below) + nc=size(Tc,2) + call init_list(RA_DOFred(aID), (/ (iprev + i, i=1,nc) /), ErrStat2, ErrMsg2); + + endif + else + ! --- Regular cantilever joint + ! TODO/NOTE: We could apply fixed constraint/BC here, returning Tc as a 6xn matrix with n<6 + ! Extreme case would be Tc: 6*0, in which case NodesDOFred would be empty ([]) + allocate(Tc(1:6,1:6)) + allocate(IDOFOld(1:6)) + Tc=I6 + IDOFOld = p%NodesDOF(iNode)%List(1:6) + endif + else + ! --- Ball/Pin/Universal joint + allocate(IDOFOld(1:len(p%NodesDOF(iNode)))) + IDOFOld(:) = p%NodesDOF(iNode)%List(:) + phat = Init%Nodes(iNode, iJointDir:iJointDir+2) + call JointElimination(Init%NodesConnE(iNode,:), JType, phat, p, Tc, ErrStat2, ErrMsg2); if(Failed()) return + endif + nc=size(Tc,2) + call init_list(p%NodesDOFred(iNode), nc, 0, ErrStat2, ErrMsg2) + p%NodesDOFred(iNode)%List(1:nc) = (/ (iprev + i, i=1,nc) /) + IDOFNew => p%NodesDOFred(iNode)%List(1:nc) ! alias to shorten notations + !print*,'N',iNode,'I ',IDOFOld + !print*,'N',iNode,'It',IDOFNew + Tred(IDOFOld, IDOFNew) = Tc + iPrev = iPrev + nc + enddo + ! --- Safety checks + if (len(IRA)>0) then + call Fatal('Not all rigid assemblies were processed'); return + endif + if (iPrev /= p%nDOF_red) then + call Fatal('Inconsistency in number of reduced DOF'); return + endif + call CleanUp_BuildTMatrix() +contains + LOGICAL FUNCTION Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'BuildTMatrix') + Failed = ErrStat >= AbortErrLev + if (Failed) call CleanUp_BuildTMatrix() + END FUNCTION Failed + + SUBROUTINE Fatal(ErrMsg_in) + CHARACTER(len=*), intent(in) :: ErrMsg_in + CALL SetErrStat(ErrID_Fatal, ErrMsg_in, ErrStat, ErrMsg, 'BuildTMatrix'); + END SUBROUTINE Fatal + + SUBROUTINE CleanUp_BuildTMatrix() + nullify(IDOFNew) + call destroy_list(IRA, ErrStat2, ErrMsg2) + if (allocated(Tc) ) deallocate(Tc) + if (allocated(IDOFOld)) deallocate(IDOFOld) + if (allocated(INodesID)) deallocate(INodesID) + if (allocated(RA_DOFred)) deallocate(RA_DOFred) + END SUBROUTINE CleanUp_BuildTMatrix + + !> Returns number of DOF after constraint reduction (via the matrix T) + INTEGER(IntKi) FUNCTION nDOF_ConstraintReduced() + integer(IntKi) :: iNode + integer(IntKi) :: ia ! Index on rigid link assembly + integer(IntKi) :: m ! Number of elements connected to a joint + integer(IntKi) :: NodeType + nDOF_ConstraintReduced = 0 + + ! Rigid assemblies contribution + nDOF_ConstraintReduced = nDOF_ConstraintReduced + 6*size(RA) + + ! Contribution from all the other joints + do iNode = 1, p%nNodes + m = Init%NodesConnE(iNode,1) ! Col1: number of elements connected to this joint + NodeType = Init%Nodes(iNode,iJointType) + + if (NodeType == idJointPin ) then + nDOF_ConstraintReduced = nDOF_ConstraintReduced + 5 + 1*m + print*,'Node',iNode, 'is a pin joint, number of members involved: ', m + + elseif(NodeType == idJointUniversal ) then + nDOF_ConstraintReduced = nDOF_ConstraintReduced + 4 + 2*m + print*,'Node',iNode, 'is an universal joint, number of members involved: ', m + + elseif(NodeType == idJointBall ) then + nDOF_ConstraintReduced = nDOF_ConstraintReduced + 3 + 3*m + print*,'Node',iNode, 'is a ball joint, number of members involved: ', m + + elseif(NodeType == idJointCantilever ) then + if ( NodeHasRigidElem(iNode, Init, p, er)) then + ! This joint is involved in a rigid link assembly, we skip it (accounted for above) + print*,'Node',iNode, 'is involved in a Rigid assembly' + else + ! That's a regular Cantilever joint + nDOF_ConstraintReduced = nDOF_ConstraintReduced + 6 + !print*,'Node',iNode, 'is a regular cantilever' + endif + else + ErrMsg='Wrong joint type'; ErrStat=ErrID_Fatal + endif + end do + END FUNCTION nDOF_ConstraintReduced + + !> return true if reduction needed (i.e. special joints, special elements) + logical FUNCTION reductionNeeded() + integer(IntKi) :: i + integer(IntKi) :: myType + reductionNeeded=.false. + ! Rigid or cable links + do i =1,size(p%Elems,1) + myType = p%Elems(i, iMType) + if (any((/idMemberCable, idMemberRigid/)==myType)) then + reductionNeeded=.true. + return + endif + enddo + ! Special joints + do i = 1, p%nNodes + myType = Init%Nodes(i,iJointType) + if (any((/idJointPin, idJointUniversal, idJointBall/)==myType)) then + reductionNeeded=.true. + return + endif + enddo + end FUNCTION reductionNeeded + +END SUBROUTINE BuildTMatrix +!------------------------------------------------------------------------------------------------------ +!> Assemble stiffness and mass matrix, and gravity force vector +SUBROUTINE DirectElimination(Init, p, ErrStat, ErrMsg) + use NWTC_LAPACK, only: LAPACK_GEMM + use IntegerList, only: len + TYPE(SD_InitType), INTENT(INOUT) :: Init + TYPE(SD_ParameterType),target,INTENT(INOUT) :: p + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None ! Local variables - REAL(ReKi) :: Ax, Ay, Kx, Ky - REAL(ReKi) :: DC(12, 12) - - Ax = kappa*A - Ay = kappa*A - - K(1:12,1:12) = 0 - - IF (Shear) THEN - Kx = 12.0*E*Iyy / (G*Ax*L*L) - Ky = 12.0*E*Ixx / (G*Ay*L*L) - ELSE - Kx = 0.0 - Ky = 0.0 - ENDIF - - K( 9, 9) = E*A/L - K( 7, 7) = 12.0*E*Iyy/( L*L*L*(1.0 + Kx) ) - K( 8, 8) = 12.0*E*Ixx/( L*L*L*(1.0 + Ky) ) - K(12, 12) = G*Jzz/L - K(10, 10) = (4.0 + Ky)*E*Ixx / ( L*(1.0+Ky) ) - K(11, 11) = (4.0 + Kx)*E*Iyy / ( L*(1.0+Kx) ) - K( 2, 4) = -6.*E*Ixx / ( L*L*(1.0+Ky) ) - K( 1, 5) = 6.*E*Iyy / ( L*L*(1.0+Kx) ) - K( 4, 10) = (2.0-Ky)*E*Ixx / ( L*(1.0+Ky) ) - K( 5, 11) = (2.0-Kx)*E*Iyy / ( L*(1.0+Kx) ) - - K( 3, 3) = K(9,9) - K( 1, 1) = K(7,7) - K( 2, 2) = K(8,8) - K( 6, 6) = K(12,12) - K( 4, 4) = K(10,10) - K(5,5) = K(11,11) - K(4,2) = K(2,4) - K(5,1) = K(1,5) - K(10,4) = K(4,10) - K(11,5) = K(5,11) - K(12,6)= -K(6,6) - K(10,2)= K(4,2) - K(11,1)= K(5,1) - K(9,3) = -K(3,3) - K(7,1) = -K(1,1) - K(8,2) = -K(2,2) - K(6, 12) = -K(6,6) - K(2, 10) = K(4,2) - K(1, 11) = K(5,1) - K(3, 9) = -K(3,3) - K(1, 7) = -K(1,1) - K(2, 8) = -K(2,2) - K(11,7) = -K(5,1) - K(10,8) = -K(4,2) - K(7,11) = -K(5,1) - K(8,10) = -K(4,2) - K(7,5) = -K(5,1) - K(5,7) = -K(5,1) - K(8,4) = -K(4,2) - K(4,8) = -K(4,2) - - DC = 0 - DC( 1: 3, 1: 3) = DirCos - DC( 4: 6, 4: 6) = DirCos - DC( 7: 9, 7: 9) = DirCos - DC(10:12, 10:12) = DirCos - - K = MATMUL( MATMUL(DC, K), TRANSPOSE(DC) ) ! TODO: change me if DirCos convention is transposed - -END SUBROUTINE ElemK + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + ! Varaibles for rigid assembly + type(IList), dimension(:), allocatable :: RA !< RA(a) = [e1,..,en] list of elements forming a rigid link assembly + integer(IntKi), dimension(:), allocatable :: RAm1 !< RA^-1(e) = a , for a given element give the index of a rigid assembly + real(FEKi), dimension(:,:), allocatable :: MM, KK + real(FEKi), dimension(:,:), allocatable :: Temp + integer(IntKi) :: nDOF, iDOF, nDOFPerNode, iNode, iiDOF, i,j + ErrStat = ErrID_None + ErrMsg = "" + + ! Setup list of rigid link assemblies (RA) and the inverse function RA^{-1} + call RigidLinkAssemblies(Init, p, RA, RAm1, ErrStat2, ErrMsg2); if(Failed()) return + call BuildTMatrix(Init, p, RA, RAm1, p%T_red, ErrStat2, ErrMsg2); if (Failed()) return + if (allocated(RAm1)) deallocate(RAm1) + if (allocated(RA )) deallocate(RA ) + + ! --- DOF elimination for system matrices and RHS vector + nDOF = p%nDOF_red + if (p%reduced) then + ! Temporary backup of M and K of full system + call move_alloc(Init%M, MM) + call move_alloc(Init%K, KK) + ! Reallocating + CALL AllocAry( Init%K, nDOF, nDOF, 'Init%K' , ErrStat2, ErrMsg2); if(Failed()) return; ! system stiffness matrix + CALL AllocAry( Init%M, nDOF, nDOF, 'Init%M' , ErrStat2, ErrMsg2); if(Failed()) return; ! system mass matrix + CALL AllocAry( Temp ,size(MM,1), nDOF, 'Temp' , ErrStat2, ErrMsg2); if(Failed()) return; + CALL AllocAry( p%T_red_T,nDOF , size(MM,1), 'T_red_T' , ErrStat2, ErrMsg2); if(Failed()) return; + ! --- Elimination (stack expensive) + !Init%M = matmul(transpose(p%T_red), matmul(MM, p%T_red)) + !Init%K = matmul(transpose(p%T_red), matmul(KK, p%T_red)) + !p%T_red_T = transpose(p%T_red) + do i = 1, size(p%T_red,1) + do j = 1, size(p%T_red,2) + p%T_red_T(j,i) = p%T_red(i,j) + enddo + enddo + !Temp = matmul(MM, p%T_red) + CALL LAPACK_gemm( 'N', 'N', 1.0_FeKi, MM , p%T_red, 0.0_FeKi, Temp , ErrStat2, ErrMsg2); if(Failed()) return + !Init%M = matmul(p%T_red_T, Temp) + CALL LAPACK_gemm( 'T', 'N', 1.0_FeKi, p%T_red, Temp , 0.0_FeKi, Init%M, ErrStat2, ErrMsg2); if(Failed()) return + !Temp = matmul(KK, p%T_red) + CALL LAPACK_gemm( 'N', 'N', 1.0_FeKi, KK , p%T_red, 0.0_FeKi, Temp , ErrStat2, ErrMsg2); if(Failed()) return + !Init%K = matmul(p%T_red_T, Temp) + CALL LAPACK_gemm( 'T', 'N', 1.0_FeKi, p%T_red, Temp , 0.0_FeKi, Init%K, ErrStat2, ErrMsg2); if(Failed()) return + if (allocated(Temp)) deallocate(Temp) + endif + !CALL AllocAry( Init%D, nDOF, nDOF, 'Init%D' , ErrStat2, ErrMsg2); if(Failed()) return; ! system damping matrix + !Init%D = 0 !< Used for additional damping + + ! --- Creating a convenient Map from DOF to Nodes + call AllocAry(p%DOFred2Nodes, p%nDOF_red, 3, 'DOFred2Nodes', ErrStat2, ErrMsg2); if(Failed()) return; + p%DOFred2Nodes=-999 + do iNode=1,p%nNodes + nDOFPerNode = len(p%NodesDOFred(iNode)) + do iiDOF = 1, nDOFPerNode + iDOF = p%NodesDOFred(iNode)%List(iiDOF) + p%DOFred2Nodes(iDOF,1) = iNode ! First column is Node index + p%DOFred2Nodes(iDOF,2) = nDOFPerNode ! Second column is number of DOF per node + p%DOFred2Nodes(iDOF,3) = iiDOF ! Third column is number of DOF per node + enddo + enddo + + call CleanUp_DirectElimination() + +CONTAINS + LOGICAL FUNCTION Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'DirectElimination') + Failed = ErrStat >= AbortErrLev + if (Failed) call CleanUp_DirectElimination() + END FUNCTION Failed + SUBROUTINE CleanUp_DirectElimination() + ! Cleaning up memory + if (allocated(MM )) deallocate(MM ) + if (allocated(KK )) deallocate(KK ) + if (allocated(RA )) deallocate(RA ) + if (allocated(RAm1)) deallocate(RAm1) + if (allocated(Temp)) deallocate(Temp) + END SUBROUTINE CleanUp_DirectElimination +END SUBROUTINE DirectElimination !------------------------------------------------------------------------------------------------------ -!> Element mass matrix for classical beam elements -SUBROUTINE ElemM(A, L, Ixx, Iyy, Jzz, rho, DirCos, M) - REAL(ReKi), INTENT( IN) :: A, L, Ixx, Iyy, Jzz, rho - REAL(ReKi), INTENT( IN) :: DirCos(3,3) - REAL(ReKi), INTENT(OUT) :: M(12, 12) - - REAL(ReKi) :: t, rx, ry, po - REAL(ReKi) :: DC(12, 12) - - t = rho*A*L; - rx = rho*Ixx; - ry = rho*Iyy; - po = rho*Jzz*L; +!> Returns constraint matrix Tc for a rigid assembly (RA) formed by a set of elements. +!! x_c = Tc.x_c_tilde +!! where x_c are all the DOF of the rigid assembly, and x_c_tilde are the 6 reduced DOF (leader DOF) +SUBROUTINE RAElimination(Elements, Tc, INodesID, Init, p, ErrStat, ErrMsg) + use IntegerList, only: init_list, len, append, print_list, pop, destroy_list, get, unique, find + integer(IntKi), dimension(:), INTENT(IN ) :: Elements !< List of elements + real(ReKi), dimension(:,:), allocatable :: Tc + integer(IntKi), dimension(:), allocatable :: INodesID !< List of unique nodes involved in Elements + TYPE(SD_InitType), INTENT(IN ) :: Init + TYPE(SD_ParameterType), INTENT(IN ) :: p + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + ! Local variables + type(IList) :: LNodesID !< List of nodes id involved in element + type(IList) :: LNodesInterf !< List of nodes id involved in interface + integer(IntKi) :: NodeID !< NodeID + integer(IntKi) :: iTmp !< Temporary index + integer(IntKi) :: iNodeID !< Loop index on node ID list + integer(IntKi) :: iiMainNode !< Index of main node selected for rigid assembly within INodesID list + integer(IntKi) :: iMainNode !< Main node index + integer(IntKi) :: nNodes !< Number of Nodes involved in RA + integer(IntKi) :: iFound !< Loop index on node ID list + integer(IntKi) :: i !< Loop index + real(ReKi) :: TRigid(6,6) ! Transformation matrix such that xi = T.x1 + real(ReKi) :: P1(3), Pi(3) ! Nodal points + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + ErrStat = ErrID_None + ErrMsg = "" - M(1:12,1:12) = 0 - - M( 9, 9) = t/3.0 - M( 7, 7) = 13.0*t/35.0 + 6.0*ry/(5.0*L) - M( 8, 8) = 13.0*t/35.0 + 6.0*rx/(5.0*L) - M(12, 12) = po/3.0 - M(10, 10) = t*L*L/105.0 + 2.0*L*rx/15.0 - M(11, 11) = t*L*L/105.0 + 2.0*L*ry/15.0 - M( 2, 4) = -11.0*t*L/210.0 - rx/10.0 - M( 1, 5) = 11.0*t*L/210.0 + ry/10.0 - M( 3, 9) = t/6.0 - M( 5, 7) = 13.*t*L/420. - ry/10. - M( 4, 8) = -13.*t*L/420. + rx/10. - M( 6, 12) = po/6. - M( 2, 10) = 13.*t*L/420. - rx/10. - M( 1, 11) = -13.*t*L/420. + ry/10. - M( 8, 10) = 11.*t*L/210. + rx/10. - M( 7, 11) = -11.*t*L/210. - ry/10. - M( 1, 7) = 9.*t/70. - 6.*ry/(5.*L) - M( 2, 8) = 9.*t/70. - 6.*rx/(5.*L) - M( 4, 10) = -L*L*t/140. - rx*L/30. - M( 5, 11) = -L*L*t/140. - ry*L/30. - - M( 3, 3) = M( 9, 9) - M( 1, 1) = M( 7, 7) - M( 2, 2) = M( 8, 8) - M( 6, 6) = M(12, 12) - M( 4, 4) = M(10, 10) - M( 5, 5) = M(11, 11) - M( 4, 2) = M( 2, 4) - M( 5, 1) = M( 1, 5) - M( 9, 3) = M( 3, 9) - M( 7, 5) = M( 5, 7) - M( 8, 4) = M( 4, 8) - M(12, 6) = M( 6, 12) - M(10, 2) = M( 2, 10) - M(11, 1) = M( 1, 11) - M(10, 8) = M( 8, 10) - M(11, 7) = M( 7, 11) - M( 7, 1) = M( 1, 7) - M( 8, 2) = M( 2, 8) - M(10, 4) = M( 4, 10) - M(11, 5) = M( 5, 11) - - DC = 0 - DC( 1: 3, 1: 3) = DirCos - DC( 4: 6, 4: 6) = DirCos - DC( 7: 9, 7: 9) = DirCos - DC(10:12, 10:12) = DirCos - - M = MATMUL( MATMUL(DC, M), TRANSPOSE(DC) ) ! TODO change me if direction cosine is transposed + ! --- List of nodes stored first in LINodes than moved to INodes + LNodesID = NodesList(p, Elements) + if (DEV_VERSION) then + print*,'Nodes involved in assembly (bfr1) ',LNodesID%List + endif + call unique(LNodesID, ErrStat2, ErrMsg2); + if (DEV_VERSION) then + print*,'Nodes involved in assembly (bfr2) ',LNodesID%List + endif -END SUBROUTINE ElemM + !--- Look for potential interface node + call init_list(LNodesInterf, 0, 0, ErrStat2, ErrMsg2); + do iNodeID = 1, len(LNodesID) + NodeID = LNodesID%List(iNodeID) + iFound = FINDLOCI( p%Nodes_I(:,1), NodeID) + if (iFound>0) then + call append(LNodesInterf, NodeID, ErrStat2, ErrMsg2) + ! This node is an interface node + print*,'Node',NodeID, 'is an interface node, selecting it for the rigid assembly' + endif + enddo + + ! --- Decide which node will be the main node of the rigid assembly + if (len(LNodesInterf)==0) then + iiMainNode = 1 ! By default we select the first node + else if (len(LNodesInterf)==1) then + ! Finding the index of the interface node + iMainNode = pop(LNodesInterf, ErrStat2, ErrMsg2) + iiMainNode = find(LNodesID, iMainNode, ErrStat2, ErrMsg2); + else + ErrStat=ErrID_Fatal + ErrMsg='Cannot have several interface nodes linked within a same rigid assembly' + return + endif + call destroy_list(LNodesInterf, ErrStat2, ErrMsg2) + + ! --- Extracting index array from list + if (allocated(INodesID)) deallocate(INodesID) + call move_alloc(LNodesID%List, INodesID) + call destroy_list(LNodesID, ErrStat2, ErrMsg2) + + ! --- Order list of joints with main node first (swapping iMainNode with INodes(1)) + iTmp = INodesID(1) + INodesID(1) = INodesID(iiMainNode) + INodesID(iiMainNode) = iTmp + if (DEV_VERSION) then + print*,'Nodes involved in assembly (after)',INodesID + endif + ! --- Building Transformation matrix + nNodes =size(INodesID) + allocate(Tc(6*nNodes,6)) + Tc(:,:)=0 + ! I6 for first node + do i = 1,6 ; Tc(i,i)=1_ReKi; enddo ! I6 = eye(6) + ! Rigid transformation matrix for the other nodes + P1 = Init%Nodes(INodesID(1), 2:4) ! reference node coordinates + do i = 2, nNodes + Pi = Init%Nodes(INodesID(i), 2:4) ! follower node coordinates + call GetRigidTransformation(P1, Pi, TRigid, ErrStat2, ErrMsg2) + Tc( ((i-1)*6)+1:6*i, 1:6) = TRigid(1:6,1:6) + enddo +END SUBROUTINE RAElimination !------------------------------------------------------------------------------------------------------ -!> Sets a list of DOF indices and the value these DOF should have -!! NOTE: need p%Reacts to have an updated first column that uses indices and not JointID -SUBROUTINE InitConstr(Init, p) - TYPE(SD_InitType ),INTENT(INOUT) :: Init - TYPE(SD_ParameterType),INTENT(IN ) :: p - ! - INTEGER(IntKi) :: I,J +!> Returns constraint matrix Tc for a joint involving several Elements +!! x_c = Tc.x_c_tilde +!! where +! x_c are all the DOF of the joint (3 translation + 3*m, m the number of elements) +! x_c_tilde are the nc reduced DOF +SUBROUTINE JointElimination(Elements, JType, phat, p, Tc, ErrStat, ErrMsg) + use IntegerList, only: init_list, len, append, print_list, pop, destroy_list, get + integer(IntKi), dimension(:), INTENT(IN ) :: Elements !< List of elements involved at a joint + integer(IntKi), INTENT(IN ) :: JType !< Joint type + real(ReKi), INTENT(IN ) :: phat(3) !< Directional vector of the joint + TYPE(SD_ParameterType), INTENT(IN ) :: p + real(ReKi), dimension(:,:), allocatable :: Tc !< Transformation matrix from eliminated to full + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + ! Local variables + !type(IList) :: I !< List of indices for Nodes involved in interface + integer(IntKi) :: i, j, ie, ne !< Loop index + integer(IntKi) :: nDOFr !< Number of reduced DOF + integer(IntKi) :: nDOFt !< Number of total DOF *nreduced) + real(ReKi) :: e1(3), e2(3), e3(3) ! forming orthonormal basis with phat + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + real(FEKi), dimension(:,:), allocatable :: Tc_rot !< Part of Tc just for rotational DOF + real(FEKi), dimension(:,:), allocatable :: Tc_rot_m1 !< Inverse of Tc_rot + real(ReKi) :: ColMean + ErrStat = ErrID_None + ErrMsg = "" - Init%BCs = 0 - DO I = 1, p%NReact - DO J = 1, 6 - Init%BCs( (I-1)*6+J, 1) = (p%Reacts(I,1)-1)*6+J; ! DOF Index, looping through Joints in index order - Init%BCs( (I-1)*6+J, 2) = p%Reacts(I, J+1); - ENDDO - ENDDO -END SUBROUTINE InitConstr + ne = Elements(1) ! TODO TODO + nDOFt = 3 + 3*ne + + ! The elements already share the same translational DOF + + if (JType == idJointPin ) then + nDOFr = 5 + 1*ne + allocate(Tc (nDOFt, nDOFr)); + allocate(Tc_rot_m1(nDOFr-3, nDOFt-3)); + Tc(:,:)=0 + Tc_rot_m1(:,:)=0 + + ! Normalizing + e3= phat/sqrt(phat(1)**2 + phat(2)**2 + phat(3)**2) + call GetOrthVectors(e3, e1, e2, ErrStat2, ErrMsg2); + ! Forming Tcm1, inverse of Tc + do ie=1,ne + Tc_rot_m1(1 , (ie-1)*3+1:ie*3 ) = e1(1:3)/ne + Tc_rot_m1(2 , (ie-1)*3+1:ie*3 ) = e2(1:3)/ne + Tc_rot_m1(ie+2, (ie-1)*3+1:ie*3 ) = e3(1:3) + enddo + ! Pseudo inverse: + call PseudoInverse(Tc_rot_m1, Tc_rot, ErrStat2, ErrMsg2) + ! --- Forming Tc + do i = 1,3 ; Tc(i,i)=1_ReKi; enddo ! I3 for translational DOF + Tc(4:nDOFt,4:nDOFr)=Tc_rot(1:nDOFt-3, 1:nDOFr-3) + do i = 1,size(Tc,1); do ie = 1,size(Tc,2) + if (abs(Tc(i,ie))<1e-13) then + Tc(i,ie)=0.0_ReKi + endif; enddo; + enddo; + deallocate(Tc_rot) + deallocate(Tc_rot_m1) + + elseif(JType == idJointUniversal ) then + if (ne/=2) then + ErrMsg='JointElimination: universal joints should only connect two elements.'; ErrStat=ErrID_Fatal + return + endif + nDOFr = 4 + 2*ne + allocate(Tc(nDOFt, nDOFr)); + allocate(Tc_rot_m1(nDOFr-3, nDOFt-3)); + Tc(:,:)=0 + Tc_rot_m1(:,:)=0 ! Important init + ! Forming the inverse of Tc_rot + Tc_rot_m1(1,1:3) = p%ElemProps(Elements(1))%DirCos(:,3)/2._ReKi + Tc_rot_m1(1,4:6) = p%ElemProps(Elements(2))%DirCos(:,3)/2._ReKi + Tc_rot_m1(2,1:3) = p%ElemProps(Elements(1))%DirCos(:,1) + Tc_rot_m1(3,1:3) = p%ElemProps(Elements(1))%DirCos(:,2) + Tc_rot_m1(4,4:6) = p%ElemProps(Elements(2))%DirCos(:,1) + Tc_rot_m1(5,4:6) = p%ElemProps(Elements(2))%DirCos(:,2) + ! Pseudo inverse + call PseudoInverse(Tc_rot_m1, Tc_rot, ErrStat2, ErrMsg2) + ! --- Forming Tc + do i = 1,3 ; Tc(i,i)=1_ReKi; enddo ! I3 for translational DOF + Tc(4:nDOFt,4:nDOFr)=Tc_rot(1:nDOFt-3, 1:nDOFr-3) + deallocate(Tc_rot) + deallocate(Tc_rot_m1) + + elseif(JType == idJointBall ) then + nDOFr = 3 + 3*ne + allocate(Tc(nDOFt, nDOFr)); + Tc(:,:)=0 + do i = 1,3 ; Tc(i,i)=1_ReKi; enddo ! I3 for translational DOF + do i = 3,nDOFr; Tc(i,i)=1_ReKi; enddo ! Identity for other DOF as well -!> Apply constraint (Boundary conditions) on Mass and Stiffness matrices -SUBROUTINE ApplyConstr(Init,p) - TYPE(SD_InitType ),INTENT(INOUT):: Init - TYPE(SD_ParameterType),INTENT(IN ):: p - - INTEGER :: I !, J, k - INTEGER :: row_n !bgn_j, end_j, - - DO I = 1, p%NReact*6 - row_n = Init%BCs(I, 1) - IF (Init%BCs(I, 2) == 1) THEN - Init%K(row_n,: )= 0 - Init%K(: ,row_n)= 0 - Init%K(row_n,row_n)= 1 - - Init%M(row_n,: )= 0 - Init%M(: ,row_n)= 0 - Init%M(row_n,row_n)= 0 - ENDIF - ENDDO ! I, loop on reaction nodes -END SUBROUTINE ApplyConstr + else + ErrMsg='JointElimination: Wrong joint type'; ErrStat=ErrID_Fatal + endif + !do i=1,nDOFt + ! print*,'Tc',Tc(i,:) + !enddo + ! --- Safety check + do j =1, size(Tc,2) + ColMean=0; do i=1,size(Tc,1) ; ColMean = ColMean + abs(Tc(i,j)); enddo + ColMean = ColMean/size(Tc,1) + if (ColMean<1e-6) then + ErrMsg='JointElimination: a reduced degree of freedom has a singular mapping.'; ErrStat=ErrID_Fatal + return + endif + enddo + +END SUBROUTINE JointElimination !------------------------------------------------------------------------------------------------------ -!> calculates the lumped forces and moments due to gravity on a given element: -!! the element has two nodes, with the loads for both elements stored in array F. Indexing of F is: -!! Fx_n1=1,Fy_n1=2,Fz_n1=3,Mx_n1= 4,My_n1= 5,Mz_n1= 6, -!! Fx_n2=7,Fy_n2=8,Fz_n2=9,Mx_n2=10,My_n2=11,Mz_n2=12 -SUBROUTINE ElemG(A, L, rho, DirCos, F, g) - REAL(ReKi), INTENT( IN ) :: A !< area - REAL(ReKi), INTENT( IN ) :: L !< element length - REAL(ReKi), INTENT( IN ) :: rho !< density - REAL(ReKi), INTENT( IN ) :: DirCos(3, 3) !< direction cosine matrix (for determining distance between nodes 1 and 2) - REAL(ReKi), INTENT( IN ) :: g !< gravity - REAL(ReKi), INTENT( OUT) :: F(12) !< returned loads. positions 1-6 are the loads for node 1; 7-12 are loads for node 2. - REAL(ReKi) :: TempCoeff - REAL(ReKi) :: w ! weight per unit length - - F = 0 ! initialize whole array to zero, then set the non-zero portions - w = rho*A*g ! weight per unit length - - ! lumped forces on both nodes (z component only): - F(3) = -0.5*L*w - F(9) = F(3) - - ! lumped moments on node 1 (x and y components only): - ! bjj: note that RRD wants factor of 1/12 because of boundary conditions. Our MeshMapping routines use factor of 1/6 (assuming generic/different boundary - ! conditions), so we may have some inconsistent behavior. JMJ suggests using line2 elements for SubDyn's input/output meshes to improve the situation. - TempCoeff = L*L*w/12.0_ReKi ! let's not calculate this twice - F(4) = -TempCoeff * DirCos(2,3) ! = -L*w*Dy/12. !bjj: DirCos(2,3) = Dy/L - F(5) = TempCoeff * DirCos(1,3) ! = L*w*Dx/12. !bjj: DirCos(1,3) = Dx/L - - ! lumped moments on node 2: (note the opposite sign of node 1 moment) - F(10) = -F(4) - F(11) = -F(5) - !F(12) is 0 for g along z alone - -END SUBROUTINE ElemG +!> Setup a list of rigid link assemblies (RA) +!! RA(a) = [e1,..,en] : list of elements that form the rigid assembly of index "a" +SUBROUTINE RigidLinkAssemblies(Init, p, RA, RAm1, ErrStat, ErrMsg) + use IntegerList, only: init_list, len, append, print_list, pop, destroy_list, get + TYPE(SD_InitType), INTENT(INOUT) :: Init + TYPE(SD_ParameterType), INTENT(INOUT) :: p + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + type(IList), dimension(:), allocatable :: RA !< RA(a) = [e1,..,en] list of elements forming a rigid link assembly + integer(IntKi), dimension(:), allocatable :: RAm1 !< RA^-1(e) = a , for a given element give the index of a rigid assembly + ! Local variables + type(IList) :: Er !< List of rigid elements + type(IList) :: Ea !< List of elements in a rigid assembly + integer(IntKi) :: nRA !< Number of rigid assemblies + integer(IntKi) :: ie !< Index on elements + integer(IntKi) :: ia !< Index on assemblies + integer(IntKi) :: e0 !< Index of an element + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + ErrStat = ErrID_None + ErrMsg = "" + allocate(RAm1(1:Init%NElem)) + RAm1(1:Init%NElem) = -1 + + ! --- Establish a list of rigid link elements + Er = RigidLinkElements(Init, p, ErrStat2, ErrMsg2) + nRA=0 + do while (len(Er)>0) + nRA=nRA+1 + ! Creating List Ea of elements of a given assembly + call init_list(Ea, 0, 0, ErrStat2, ErrMsg2); + e0 = pop(Er, ErrStat2, ErrMsg2); + call append(Ea, e0, ErrStat2, ErrMsg2); + call AddNeighbors(e0, Er, Ea) + if (DEV_VERSION) then + call print_list(Ea,'Rigid assembly (loop 1)') + endif + do ie = 1, len(Ea) + e0 = get(Ea, ie, ErrStat2, ErrMsg2) + RAm1(e0) = nRA ! Index of rigid assembly that this element belongs to + enddo + call destroy_list(Ea, ErrStat2, ErrMsg2) + enddo + call destroy_list(Er, ErrStat2, ErrMsg2) + + ! --- Creating RA, array of lists of assembly elements. + ! Note: exactly the same as all the Ea created above, but we didn't know the total number of RA + allocate(RA(1:nRA)) + do ia = 1, nRA + call init_list(RA(ia), 0, 0, ErrStat2, ErrMsg2) + enddo + do ie = 1, Init%NElem + ia = RAm1(ie) ! Index of the assembly the element belongs to: RA^{-1}(ie) = ia + if (ia>0) then + call append(RA(ia), ie, ErrStat2, ErrMsg2) + endif + enddo + if (DEV_VERSION) then + do ia = 1, nRA + call print_list(RA(ia),'Rigid assembly (loop 2)') + enddo + endif +CONTAINS + !> The neighbor-elements of element e0 (that are found within the list Er) are added to the list Ea + RECURSIVE SUBROUTINE AddNeighbors(e0, Er, Ea) + integer(IntKi), intent(in) :: e0 !< Index of an element + type(IList), intent(inout) :: Er !< List of rigid elements + type(IList), intent(inout) :: Ea !< List of elements in a rigid assembly + type(IList) :: En !< List of neighbors of e0 + integer (IntKi) :: ik + integer (IntKi) :: ek, ek2 + integer (IntKi) :: iWhichNode_e0, iWhichNode_ek + call init_list(En, 0, 0, ErrStat2, ErrMsg2) + ! Loop through all elements, setup list of e0-neighbors, add them to Ea, remove them from Er + ik=0 + do while (ik< len(Er)) + ik=ik+1 + ek = Er%List(ik) + if (ElementsConnected(p, e0, ek, iWhichNode_e0, iWhichNode_ek)) then + if (DEV_VERSION) then + print*,'Element ',ek,'is connected to element',e0,'via its node',iWhichNode_ek + endif + ! Remove element from Er (a rigid element can belong to only one assembly) + ek2 = pop(Er, ik, ErrStat2, ErrMsg2) ! same as ek before + ik=ik-1 + if (ek/=ek2) then + print*,'Problem in popping',ek,ek2 + STOP + endif + call append(En, ek, ErrStat2, ErrMsg2) + call append(Ea, ek, ErrStat2, ErrMsg2) + endif + enddo + ! Loop through neighbors and recursively add neighbors of neighbors + do ik = 1, len(En) + ek = En%List(ik) + call AddNeighbors(ek, Er, Ea) + enddo + call destroy_list(En, ErrStat2, ErrMsg2) + END SUBROUTINE AddNeighbors + +END SUBROUTINE RigidLinkAssemblies + + !------------------------------------------------------------------------------------------------------ -!> Calculates the lumped gravity forces at the nodes given the element geometry -!! It assumes a linear variation of the dimensions from node 1 to node 2, thus the area may be quadratically varying if crat<>1 -!! bjj: note this routine is a work in progress, intended for future version of SubDyn. Compare with ElemG. -SUBROUTINE LumpForces(Area1,Area2,crat,L,rho, g, DirCos, F) - REAL(ReKi), INTENT( IN ) :: Area1,Area2,crat !< X-sectional areas at node 1 and node 2, t2/t1 thickness ratio - REAL(ReKi), INTENT( IN ) :: g !< gravity - REAL(ReKi), INTENT( IN ) :: L !< Length of element - REAL(ReKi), INTENT( IN ) :: rho !< density - REAL(ReKi), INTENT( IN ) :: DirCos(3, 3) !< Direction cosine matrix - REAL(ReKi), INTENT( OUT) :: F(12) !< Lumped forces - !LOCALS - REAL(ReKi) :: TempCoeff,a0,a1,a2 !coefficients of the gravity quadratically distributed force - print*,'Error: the function lumpforces is not ready to use' - STOP - - !Calculate quadratic polynomial coefficients - a0 = -99999 ! TODO: this is wrong - a2 = ( (Area1+A2) - (Area1*crat+Area2/crat) )/L**2. ! *x**2 - a1 = (Area2-Area1)/L -a2*L ! *x - - !Now calculate the Lumped Forces - F = 0 - F(3) = -(a0*L/2. +a1*L**2/6. +a2*L**3/12. )*rho*g !Forces along z (must be negative on earth) - F(9) = -(a0*L/2. +a1*L**2/3. +a2*L**3/4. )*rho*g !Forces along z (must be negative on earth) - - !Now calculate the Lumped Moments - !HERE TO BE COMPLETED FOR THE BELOW - TempCoeff = 1.0/12.0*g*L*L*rho*Area2 !RRD : I am changing this to >0 sign 6/10/13 - - !F(4) = TempCoeff*( DirCos(1, 3)*DirCos(2, 1) - DirCos(1, 1)*DirCos(2, 3) ) !These do not work if convnetion on z2>z1, x2>x1, y2>y1 are not followed as I have discovered 7/23 - !F(5) = TempCoeff*( DirCos(1, 3)*DirCos(2, 2) - DirCos(1, 2)*DirCos(2, 3) ) - - !RRD attempt at new dircos which keeps x in the X-Y plane - F(4) = -TempCoeff * SQRT(1-DirCos(3,3)**2) * DirCos(1,1) !bjj: compare with ElemG() and verify this lumping is consistent - F(5) = -TempCoeff * SQRT(1-DirCos(3,3)**2) * DirCos(2,1) !bjj: compare with ElemG() and verify this lumping is consistent - !RRD ends - F(10) = -F(4) - F(11) = -F(5) - !F(12) is 0 for g along z alone -END SUBROUTINE LumpForces +!> Add stiffness and damping to some joints +!! NOTE: damping was removed around 13/07/2020 +SUBROUTINE InsertJointStiffDamp(p, Init, ErrStat, ErrMsg) + TYPE(SD_ParameterType),target,INTENT(IN ) :: p + TYPE(SD_InitType), INTENT(INOUT) :: Init + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! Local variables + integer(IntKi) :: iNode, JType, iStart, i + integer(IntKi) :: nFreeRot ! Number of free rot DOF + integer(IntKi) :: nMembers ! Number of members attached to this node + integer(IntKi) :: nSpace ! Number of spaces between diagonal "bands" (0:pin, 1:univ, 2:ball) + real(ReKi) :: StifAdd + real(ReKi), dimension(:,:), allocatable :: K_Add ! Stiffness matrix added to global system + integer(IntKi), dimension(:), pointer :: Ifreerot + ErrStat = ErrID_None + ErrMsg = "" + do iNode = 1, p%nNodes + JType = int(Init%Nodes(iNode,iJointType)) + StifAdd = Init%Nodes(iNode, iJointStiff) + if(JType == idJointCantilever ) then + ! Cantilever joints should not have damping or stiffness + if(StifAdd>0) then + ErrMsg='InsertJointStiffDamp: Additional stiffness should be 0 for cantilever joints. Index of problematic node: '//trim(Num2LStr(iNode)); ErrStat=ErrID_Fatal; + return + endif + else + ! Ball/Univ/Pin joints have damping/stiffness inserted at indices of "free rotation" + nMembers = Init%NodesConnE(iNode,1) ! Col1: number of elements connected to this joint + if ( JType == idJointBall ) then; iStart=4; nSpace=2; + else if ( JType == idJointUniversal ) then; iStart=5; nSpace=1; + else if ( JType == idJointPin ) then; iStart=6; nSpace=0; + endif + Ifreerot=>p%NodesDOFred(iNode)%List(iStart:) + nFreeRot = size(Ifreerot) + ! Creating matrices of 0, and -K and nK on diagonals + allocate(K_Add(1:nFreeRot,1:nFreeRot)); + call ChessBoard(K_Add, -StifAdd, 0._ReKi, nSpace=nSpace, diagVal=(nMembers-1)*StifAdd) + ! Ball/Pin/Universal joints + if(StifAdd>0) then + !print*,'Stiffness Add, Node:',iNode,'DOF:', Ifreerot + !do i=1,nFreeRot + ! print*,'K Add',K_Add(i,:) + !enddo + Init%K(Ifreerot,Ifreerot) = Init%K(Ifreerot,Ifreerot) + K_Add + endif + if(allocated(K_Add)) deallocate(K_Add) + endif + enddo +END SUBROUTINE InsertJointStiffDamp + +!> Returns true if the substructure can be considered "fixed bottom" +LOGICAL FUNCTION isFixedBottom(Init, p) + TYPE(SD_InitType), INTENT(IN ) :: Init + TYPE(SD_ParameterType),INTENT(IN ) :: p + isFixedBottom=.not.isFloating(Init,p) + !INTEGER(IntKi) :: i, nFixed + !nFixed=0 + !do i =1,size(p%Nodes_C,1) + ! if (ALL(p%Nodes_C(I,2:7)==idBC_Fixed)) then + ! nFixed=nFixed+1 + ! elseif (Init%SSIfile(I)/='') then + ! nFixed=nFixed+1 + ! endif + !enddo + !bFixed = nFixed >=1 +END FUNCTION isFixedBottom + +!> True if a structure is floating, no fixed BC at the bottom +logical function isFloating(Init, p) + type(SD_InitType), intent(in ):: Init + type(SD_ParameterType),intent(in ) :: p + integer(IntKi) :: i + !isFloating=size(p%Nodes_C)>0 + isFloating=.True. + do i =1,size(p%Nodes_C,1) + if ((all(p%Nodes_C(I,2:7)==idBC_Internal)) .and. (Init%SSIfile(i)=='')) then + continue + else + isFloating=.False. + return + endif + enddo +end function isFloating + +SUBROUTINE ElemM(ep, Me) + TYPE(ElemPropType), INTENT(IN) :: eP !< Element Property + REAL(FEKi), INTENT(OUT) :: Me(12, 12) + REAL(FEKi) :: L0, Eps0 + if (ep%eType==idMemberBeam) then + !Calculate Ke, Me to be used for output + CALL ElemM_Beam(eP%Area, eP%Length, eP%Ixx, eP%Iyy, eP%Jzz, eP%rho, eP%DirCos, Me) + + else if (ep%eType==idMemberCable) then + Eps0 = ep%T0/(ep%YoungE*ep%Area) + L0 = ep%Length/(1+Eps0) ! "rest length" for which pretension would be 0 + CALL ElemM_Cable(ep%Area, L0, ep%rho, ep%DirCos, Me) + + else if (ep%eType==idMemberRigid) then + if ( EqualRealNos(eP%rho, 0.0_ReKi) ) then + Me=0.0_FEKi + else + CALL ElemM_Cable(ep%Area, real(ep%Length,FEKi), ep%rho, ep%DirCos, Me) + !CALL ElemM_(A, L, rho, DirCos, Me) + endif + endif +END SUBROUTINE ElemM + +SUBROUTINE ElemK(ep, Ke) + TYPE(ElemPropType), INTENT(IN) :: eP !< Element Property + REAL(FEKi), INTENT(OUT) :: Ke(12, 12) + + if (ep%eType==idMemberBeam) then + CALL ElemK_Beam( eP%Area, eP%Length, eP%Ixx, eP%Iyy, eP%Jzz, eP%Shear, eP%kappa, eP%YoungE, eP%ShearG, eP%DirCos, Ke) + + else if (ep%eType==idMemberCable) then + CALL ElemK_Cable(ep%Area, ep%Length, ep%YoungE, ep%T0, eP%DirCos, Ke) + + else if (ep%eType==idMemberRigid) then + Ke = 0.0_FEKi + endif +END SUBROUTINE ElemK + +SUBROUTINE ElemF(ep, gravity, Fg, Fo) + TYPE(ElemPropType), INTENT(IN) :: eP !< Element Property + REAL(ReKi), INTENT(IN) :: gravity !< acceleration of gravity + REAL(FEKi), INTENT(OUT) :: Fg(12) + REAL(FEKi), INTENT(OUT) :: Fo(12) + if (ep%eType==idMemberBeam) then + Fo(1:12)=0.0_FEKi + else if (ep%eType==idMemberCable) then + CALL ElemF_Cable(ep%T0, ep%DirCos, Fo) + else if (ep%eType==idMemberRigid) then + Fo(1:12)=0.0_FEKi + endif + CALL ElemG( eP%Area, eP%Length, eP%rho, eP%DirCos, Fg, gravity ) +END SUBROUTINE ElemF END MODULE SD_FEM diff --git a/modules/subdyn/src/SubDyn.f90 b/modules/subdyn/src/SubDyn.f90 index e93577dff6..1c545885b1 100644 --- a/modules/subdyn/src/SubDyn.f90 +++ b/modules/subdyn/src/SubDyn.f90 @@ -19,24 +19,20 @@ !********************************************************************************************************************************** !> SubDyn is a time-domain structural-dynamics module for multi-member fixed-bottom substructures. !! SubDyn relies on two main engineering schematizations: (1) a linear frame finite-element beam model (LFEB), and -!! (2) a dynamics system reduction via Craig-Bampton�s (C-B) method, together with a Static-Improvement method, greatly reducing +!! (2) a dynamics system reduction via Craig-Bampton's (C-B) method, together with a Static-Improvement method, greatly reducing !! the number of modes needed to obtain an accurate solution. Module SubDyn USE NWTC_Library - USE NWTC_LAPACK USE SubDyn_Types USE SubDyn_Output + USE SubDyn_Tests USE SD_FEM IMPLICIT NONE PRIVATE - !............................ - ! NOTE: for debugging, add preprocessor definition SD_SUMMARY_DEBUG - ! this will add additional matrices to the SubDyn summary file. - !............................ TYPE(ProgDesc), PARAMETER :: SD_ProgDesc = ProgDesc( 'SubDyn', '', '' ) ! ..... Public Subroutines ................................................................................................... @@ -45,13 +41,18 @@ Module SubDyn PUBLIC :: SD_UpdateStates ! Loose coupling routine for solving for constraint states, integrating PUBLIC :: SD_CalcOutput ! Routine for computing outputs PUBLIC :: SD_CalcContStateDeriv ! Tight coupling routine for computing derivatives of continuous states + PUBLIC :: SD_JacobianPContState ! + PUBLIC :: SD_JacobianPInput ! + PUBLIC :: SD_JacobianPDiscState ! + PUBLIC :: SD_JacobianPConstrState ! + PUBLIC :: SD_GetOP ! CONTAINS SUBROUTINE CreateTPMeshes( TP_RefPoint, inputMesh, outputMesh, ErrStat, ErrMsg ) REAL(ReKi), INTENT( IN ) :: TP_RefPoint(3) - TYPE(MeshType), INTENT( INOUT ) :: inputMesh - TYPE(MeshType), INTENT( INOUT ) :: outputMesh + TYPE(MeshType), INTENT( INOUT ) :: inputMesh ! u%TPMesh + TYPE(MeshType), INTENT( INOUT ) :: outputMesh ! y%Y1Mesh INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None @@ -67,23 +68,10 @@ SUBROUTINE CreateTPMeshes( TP_RefPoint, inputMesh, outputMesh, ErrStat, ErrMsg ) ,RotationVel = .TRUE. & ,TranslationAcc = .TRUE. & ,RotationAcc = .TRUE. ) - - ! Create the node on the mesh - CALL MeshPositionNode ( inputMesh & - , 1 & - , TP_RefPoint & - , ErrStat & - , ErrMsg ) !note: assumes identiy matrix as reference orientation - IF ( ErrStat >= AbortErrLev ) RETURN - - ! Create the mesh element - CALL MeshConstructElement ( inputMesh & - , ELEMENT_POINT & - , ErrStat & - , ErrMsg & - , 1 ) - CALL MeshCommit ( inputMesh, ErrStat, ErrMsg ) - IF ( ErrStat >= AbortErrLev ) RETURN + ! Create the node and mesh element, note: assumes identiy matrix as reference orientation + CALL MeshPositionNode (inputMesh, 1, TP_RefPoint, ErrStat, ErrMsg); IF(ErrStat>=AbortErrLev) return + CALL MeshConstructElement(inputMesh, ELEMENT_POINT, ErrStat, ErrMsg, 1) + CALL MeshCommit( inputMesh, ErrStat, ErrMsg); if(ErrStat >= AbortErrLev) return ! Create the Transition Piece reference point output mesh as a sibling copy of the input mesh CALL MeshCopy ( SrcMesh = inputMesh & @@ -95,95 +83,35 @@ SUBROUTINE CreateTPMeshes( TP_RefPoint, inputMesh, outputMesh, ErrStat, ErrMsg ) ,Force = .TRUE. & ,Moment = .TRUE. ) END SUBROUTINE CreateTPMeshes - -SUBROUTINE CreateY2Meshes( NNode, Nodes, NNodes_I, IDI, NNodes_L, IDL, NNodes_C, IDC, inputMesh, outputMesh, ErrStat, ErrMsg ) +!--------------------------------------------------------------------------- +!> Create output (Y2, for motion) and input (u, for forces)meshes, based on SubDyn nodes +!! Ordering of nodes is the same as SubDyn (used to be : I L C) +SUBROUTINE CreateInputOutputMeshes( NNode, Nodes, inputMesh, outputMesh, ErrStat, ErrMsg ) INTEGER(IntKi), INTENT( IN ) :: NNode !total number of nodes in the structure, used to size the array Nodes, i.e. its rows REAL(ReKi), INTENT( IN ) :: Nodes(NNode, JointsCol) - INTEGER(IntKi), INTENT( IN ) :: NNodes_I ! number interface nodes i.e. Y2 stuff at the beginning - INTEGER(IntKi), INTENT( IN ) :: IDI(NNodes_I*6) - INTEGER(IntKi), INTENT( IN ) :: NNodes_L ! number interior nodes (no constraints) i.e. Y2 stuff after interface stuff - INTEGER(IntKi), INTENT( IN ) :: IDL(NNodes_L*6) - INTEGER(IntKi), INTENT( IN ) :: NNodes_C ! number base reaction nodes i.e. Y2 stuff after interior stuff - INTEGER(IntKi), INTENT( IN ) :: IDC(NNodes_C*6) - TYPE(MeshType), INTENT( INOUT ) :: inputMesh - TYPE(MeshType), INTENT( INOUT ) :: outputMesh + TYPE(MeshType), INTENT( INOUT ) :: inputMesh ! u%LMesh + TYPE(MeshType), INTENT( INOUT ) :: outputMesh ! y%Y2Mesh INTEGER(IntKi), INTENT( OUT ) :: ErrStat ! Error status of the operation CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None ! Local variables - INTEGER :: I ! generic counter variable + REAL(ReKi), dimension(3) :: Point + INTEGER :: I ! generic counter variable INTEGER :: nodeIndx - CALL MeshCreate( BlankMesh = inputMesh & - ,IOS = COMPONENT_INPUT & - ,Nnodes = NNodes_I + NNodes_L + NNodes_C & - ,ErrStat = ErrStat & - ,ErrMess = ErrMsg & - ,Force = .TRUE. & - ,Moment = .TRUE. ) - !--------------------------------------------------------------------- - ! Interface nodes - !--------------------------------------------------------------------- - DO I = 1,NNodes_I - ! Create the node on the mesh - nodeIndx = IDI(I*6) / 6 !integer division gives me the actual node index, is it true? Yes it is not the nodeID - CALL MeshPositionNode ( inputMesh & - , I & - , Nodes(nodeIndx,2:4) & ! position - , ErrStat & - , ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - - ! Create the mesh element - CALL MeshConstructElement ( inputMesh & - , ELEMENT_POINT & - , ErrStat & - , ErrMsg & - , I ) - END DO - - !--------------------------------------------------------------------- - ! Interior nodes - !--------------------------------------------------------------------- - DO I = 1,NNodes_L - ! Create the node on the mesh - nodeIndx = IDL(I*6) / 6 !integer division gives me the actual node index, is it true? Yes it is not the nodeID of the input file that may not be sequential, but the renumbered list of nodes - CALL MeshPositionNode ( inputMesh & - , I + NNodes_I & - , Nodes(nodeIndx,2:4) & - , ErrStat & - , ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - - ! Create the mesh element - CALL MeshConstructElement ( inputMesh & - , ELEMENT_POINT & - , ErrStat & - , ErrMsg & - , I + NNodes_I ) - END DO - - !--------------------------------------------------------------------- - ! Base Reaction nodes - !--------------------------------------------------------------------- - DO I = 1,NNodes_C - ! Create the node on the mesh - nodeIndx = IDC(I*6) / 6 !integer division gives me the actual node index, is it true? Yes it is not the nodeID - CALL MeshPositionNode ( inputMesh & - , I + NNodes_I + NNodes_L & - , Nodes(nodeIndx,2:4) & - , ErrStat & - , ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - - ! Create the mesh element - CALL MeshConstructElement ( inputMesh & - , ELEMENT_POINT & - , ErrStat & - , ErrMsg & - , I + NNodes_I + NNodes_L ) - END DO - CALL MeshCommit ( inputMesh, ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN + CALL MeshCreate( BlankMesh = inputMesh & + ,IOS = COMPONENT_INPUT & + ,Nnodes = size(Nodes,1) & + ,ErrStat = ErrStat & + ,ErrMess = ErrMsg & + ,Force = .TRUE. & + ,Moment = .TRUE. ) + + DO I = 1,size(Nodes,1) + Point = Nodes(I, 2:4) + CALL MeshPositionNode(inputMesh, I, Point, ErrStat, ErrMsg); IF(ErrStat/=ErrID_None) RETURN + CALL MeshConstructElement(inputMesh, ELEMENT_POINT, ErrStat, ErrMsg, I) + ENDDO + CALL MeshCommit ( inputMesh, ErrStat, ErrMsg); IF(ErrStat/=ErrID_None) RETURN ! Create the Interior Points output mesh as a sibling copy of the input mesh CALL MeshCopy ( SrcMesh = inputMesh & @@ -203,44 +131,7 @@ SUBROUTINE CreateY2Meshes( NNode, Nodes, NNodes_I, IDI, NNodes_L, IDL, NNodes_C, !Identity should mean no rotation, which is our first guess at the output -RRD CALL Eye( outputMesh%Orientation, ErrStat, ErrMsg ) -END SUBROUTINE CreateY2Meshes -!------------------------------------------------------------------------------------------------------ -!> Set the index array that maps SD internal nodes to the Y2Mesh nodes. -!! NOTE: SDtoMesh is not checked for size, nor are the index array values checked for validity, -!! so this routine could easily have segmentation faults if any errors exist. -SUBROUTINE SD_Y2Mesh_Mapping(p, SDtoMesh ) - TYPE(SD_ParameterType), INTENT(IN ) :: p !< Parameters - INTEGER(IntKi), INTENT( OUT) :: SDtoMesh(:) !< index/mapping of mesh nodes with SD mesh - ! locals - INTEGER(IntKi) :: i - INTEGER(IntKi) :: SDnode - INTEGER(IntKi) :: y2Node - - y2Node = 0 - ! Interface nodes (IDI) - DO I = 1,SIZE(p%IDI,1)/6 - y2Node = y2Node + 1 - SDnode = p%IDI(I*6) / 6 !integer division gives me the actual node index; it is not the nodeID - SDtoMesh( SDnode ) = y2Node ! TODO add safety check - END DO - - ! Interior nodes (IDL) - DO I = 1,SIZE(p%IDL,1)/6 - y2Node = y2Node + 1 - SDnode = p%IDL(I*6) / 6 !integer division gives me the actual node index; it is not the nodeID - SDtoMesh( SDnode ) = y2Node ! TODO add safety check - END DO - - ! Base Reaction nodes (IDC) - DO I = 1,SIZE(p%IDC,1)/6 - y2Node = y2Node + 1 - SDnode = p%IDC(I*6) / 6 !integer division gives me the actual node index; it is not the nodeID - SDtoMesh( SDnode ) = y2Node ! TODO add safety check - END DO - -END SUBROUTINE SD_Y2Mesh_Mapping - - +END SUBROUTINE CreateInputOutputMeshes !--------------------------------------------------------------------------- !> This routine is called at the start of the simulation to perform initialization steps. !! The parameters are set here and not changed during the simulation. @@ -268,7 +159,6 @@ SUBROUTINE SD_Init( InitInput, u, p, x, xd, z, OtherState, y, m, Interval, InitO ! local variables TYPE(SD_InitType) :: Init TYPE(CB_MatArrays) :: CBparams ! CB parameters to be stored and written to summary file - TYPE(FEM_MatArrays) :: FEMparams ! FEM parameters to be stored and written to summary file INTEGER(IntKi) :: ErrStat2 ! Error status of the operation CHARACTER(ErrMsgLen) :: ErrMsg2 ! Error message if ErrStat /= ErrID_None @@ -282,12 +172,34 @@ SUBROUTINE SD_Init( InitInput, u, p, x, xd, z, OtherState, y, m, Interval, InitO ! Display the module information CALL DispNVD( SD_ProgDesc ) InitOut%Ver = SD_ProgDesc + + ! --- Test TODO remove me in the future + if (DEV_VERSION) then + CALL SD_Tests(ErrStat2, ErrMsg2); if(Failed()) return + endif ! transfer glue-code information to data structure for SubDyn initialization: Init%g = InitInput%g Init%TP_RefPoint = InitInput%TP_RefPoint Init%SubRotateZ = InitInput%SubRotateZ - p%NAvgEls = 2 + if ((allocated(InitInput%SoilStiffness)) .and. (InitInput%SoilMesh%Initialized)) then + ! Soil Mesh and Stiffness + ! SoilMesh has N points. Correspond in order to the SoilStiffness matrices passed in + ! %RefOrientation is the identity matrix (3,3,N) + ! %Position is the reference position (3,N) + ! Maybe some logic to make sure these points correspond roughly to nodes -- though this may not be true for a long pile into the soil with multiple connection points + ! Note: F = -kx whre k is the relevant 6x6 matrix from SoilStiffness + call AllocAry(Init%Soil_K, 6,6, size(InitInput%SoilStiffness,3), 'Soil_K', ErrStat2, ErrMsg2); + call AllocAry(Init%Soil_Points, 3, InitInput%SoilMesh%NNodes, 'Soil_Points', ErrStat2, ErrMsg2); + call AllocAry(Init%Soil_Nodes, InitInput%SoilMesh%NNodes, 'Soil_Nodes' , ErrStat2, ErrMsg2); + Init%Soil_K = InitInput%SoilStiffness ! SoilStiffness is dimensioned (6,6,N) + Init%Soil_Points = InitInput%SoilMesh%Position ! SoilStiffness is dimensioned (6,6,N) + Init%Soil_Nodes = -1 ! Will be determined in InsertSoilMatrices, Nodes not known yet + if (size(Init%Soil_K,3) /= size(Init%Soil_Points,2)) then + ErrStat2=ErrID_Fatal; ErrMsg2='Number of soil points inconsistent with number of soil stiffness matrix' + endif + if (Failed()) return + endif !bjj added this ugly check (mostly for checking SubDyn driver). not sure if anyone would want to play with different values of gravity so I don't return an error. IF (Init%g < 0.0_ReKi ) CALL ProgWarn( ' SubDyn calculations use gravity assuming it is input as a positive number; the input value is negative.' ) @@ -302,34 +214,76 @@ SUBROUTINE SD_Init( InitInput, u, p, x, xd, z, OtherState, y, m, Interval, InitO ! Parse the SubDyn inputs CALL SD_Input(InitInput%SDInputFile, Init, p, ErrStat2, ErrMsg2); if(Failed()) return - + if (p%Floating) then + call WrScr(' Floating case detected, Guyan modes will be rigid body modes') + else + call WrScr(' Fixed bottom case detected') + endif + + ! -------------------------------------------------------------------------------- + ! --- Manipulation of Init and parameters + ! -------------------------------------------------------------------------------- ! Discretize the structure according to the division size - ! sets Init%NNode, Init%NElm - CALL SD_Discrt(Init,p, ErrStat2, ErrMsg2); if(Failed()) return + ! sets p%nNodes, Init%NElm + CALL SD_Discrt(Init, p, ErrStat2, ErrMsg2); if(Failed()) return + + ! Store relative distance to TP node, for floating rigid body motion + CALL StoreNodesRelPos(Init, p, ErrStat2, ErrMsg2); if(Failed()) return - ! Assemble Stiffness and mass matrix - CALL AssembleKM(Init,p, ErrStat2, ErrMsg2); if(Failed()) return + ! Set element properties (p%ElemProps) + CALL SetElementProperties(Init, p, ErrStat2, ErrMsg2); if(Failed()) return - ! --- Calculate values for FEMparams (for summary file output only - ! Solve dynamics problem - FEMparams%NOmega = Init%TDOF - p%Nreact*6 !removed an extra "-6" !Note if fixity changes at the reaction points, this will need to change - - CALL AllocAry(FEMparams%Omega, FEMparams%NOmega, 'FEMparams%Omega', ErrStat2, ErrMsg2 ); if(Failed()) return - CALL AllocAry(FEMparams%Modes, Init%TDOF, FEMparams%NOmega, 'FEMparams%Modes', ErrStat2, ErrMsg2 ); if(Failed()) return - - ! We call the EigenSolver here only so that we get a print-out the eigenvalues from the full system (minus Reaction DOF) - ! The results, Phi is not used in the remainder of this Init subroutine, Omega goes to outsummary. - CALL EigenSolve( Init%K, Init%M, Init%TDOF, FEMparams%NOmega, .True., Init, p, FEMparams%Modes, FEMparams%Omega, ErrStat2, ErrMsg2 ); if(Failed()) return - + !Store mapping between nodes and elements + CALL NodeCon(Init, p, ErrStat2, ErrMsg2); if(Failed()) return + + !Store mapping between controllable elements and control channels, and return guess input + CALL ControlCableMapping(Init, u, p, ErrStat2, ErrMsg2); if(Failed()) return + + ! --- Allocate DOF indices to joints and members + call DistributeDOF(Init, p ,ErrStat2, ErrMsg2); if(Failed()) return; + + ! Assemble Stiffness and mass matrix + CALL AssembleKM(Init, p, ErrStat2, ErrMsg2); if(Failed()) return + + ! Insert soil stiffness and mass matrix (NOTE: using NodesDOF, unreduced matrix) + CALL InsertSoilMatrices(Init%M, Init%K, p%NodesDOF, Init, p, ErrStat2, ErrMsg2); if(Failed()) return + + ! --- Elimination of constraints (reset M, K, D, to lower size, and BCs IntFc ) + CALL DirectElimination(Init, p, ErrStat2, ErrMsg2); if(Failed()) return + + ! --- Additional Damping and stiffness at pin/ball/universal joints + CALL InsertJointStiffDamp(p, Init, ErrStat2, ErrMsg2); if(Failed()) return + + ! --- Prepare for control cable load, RHS + if (size(p%CtrlElem2Channel,1)>0) then + CALL ControlCableForceInit(p, m, ErrStat2, ErrMsg2); if(Failed()) return + print*,'Controlable cables are present, this feature is not ready at the glue code level.' + STOP + endif + + ! -------------------------------------------------------------------------------- + ! --- CB, Misc + ! -------------------------------------------------------------------------------- + ! --- Partitioning + ! Nodes into (I,C,L,R): I=Interface ,C=Boundary (bottom), R=(I+C), L=Interior + ! DOFs into (B,F,L): B=Leader (i.e. Rbar) ,F=Fixed, L=Interior + call PartitionDOFNodes(Init, m, p, ErrStat2, ErrMsg2) ; if(Failed()) return + if (p%GuyanLoadCorrection) then + if (p%Floating) then + call WrScr(' Guyan extra moment and rotated CB-frame will be used (floating case detected)') + else + call WrScr(' Guyan extra moment will be included in loads (fixed-bottom case detected)') + endif + endif ! --- Craig-Bampton reduction (sets many parameters) - CALL Craig_Bampton(Init, p, CBparams, ErrStat2, ErrMsg2); if(Failed()) return + CALL SD_Craig_Bampton(Init, p, CBparams, ErrStat2, ErrMsg2); if(Failed()) return ! --- Initial system states - IF ( p%qmL > 0 ) THEN - CALL AllocAry(x%qm, p%qmL, 'x%qm', ErrStat2, ErrMsg2 ); if(Failed()) return - CALL AllocAry(x%qmdot, p%qmL, 'x%qmdot', ErrStat2, ErrMsg2 ); if(Failed()) return - CALL AllocAry(m%qmdotdot, p%qmL, 'm%qmdotdot', ErrStat2, ErrMsg2 ); if(Failed()) return + IF ( p%nDOFM > 0 ) THEN + CALL AllocAry(x%qm, p%nDOFM, 'x%qm', ErrStat2, ErrMsg2 ); if(Failed()) return + CALL AllocAry(x%qmdot, p%nDOFM, 'x%qmdot', ErrStat2, ErrMsg2 ); if(Failed()) return + CALL AllocAry(m%qmdotdot, p%nDOFM, 'm%qmdotdot', ErrStat2, ErrMsg2 ); if(Failed()) return x%qm = 0.0_ReKi x%qmdot = 0.0_ReKi m%qmdotdot= 0.0_ReKi @@ -351,22 +305,22 @@ SUBROUTINE SD_Init( InitInput, u, p, x, xd, z, OtherState, y, m, Interval, InitO ! Allocate miscellaneous variables, used only to avoid temporary copies of variables allocated/deallocated and sometimes recomputed each time CALL AllocMiscVars(p, m, ErrStat2, ErrMsg2); if(Failed()) return + + ! -------------------------------------------------------------------------------- + ! --- Initialize Inputs and Outputs + ! -------------------------------------------------------------------------------- + ! Create the input and output meshes associated with Transition Piece reference point + CALL CreateTPMeshes( InitInput%TP_RefPoint, u%TPMesh, y%Y1Mesh, ErrStat2, ErrMsg2 ); if(Failed()) return + + ! Construct the input mesh (u%LMesh, force on nodes) and output mesh (y%Y2Mesh, displacements) + CALL CreateInputOutputMeshes( p%nNodes, Init%Nodes, u%LMesh, y%Y2Mesh, ErrStat2, ErrMsg2 ); if(Failed()) return ! --- Write the summary file IF ( Init%SSSum ) THEN ! note p%KBB/MBB are KBBt/MBBt ! Write a summary of the SubDyn Initialization - CALL OutSummary(Init,p,FEMparams,CBparams, ErrStat2, ErrMsg2); if(Failed()) return - IF( ALLOCATED(Init%K) ) DEALLOCATE(Init%K) - IF( ALLOCATED(Init%M) ) DEALLOCATE(Init%M) + CALL OutSummary(Init, p, m, InitInput, CBparams, ErrStat2, ErrMsg2); if(Failed()) return ENDIF - - ! --- Initialize Inputs and Outputs - ! Create the input and output meshes associated with Transition Piece reference point - CALL CreateTPMeshes( InitInput%TP_RefPoint, u%TPMesh, y%Y1Mesh, ErrStat2, ErrMsg2 ); if(Failed()) return - - ! Construct the input mesh for the interior nodes which result from the Craig-Bampton reduction - CALL CreateY2Meshes( Init%NNode, Init%Nodes, Init%NInterf, p%IDI, p%NNodes_L, p%IDL, p%NReact, p%IDC, u%LMesh, y%Y2Mesh, ErrStat2, ErrMsg2 ); if(Failed()) return ! Initialize the outputs & Store mapping between nodes and elements CALL SDOUT_Init( Init, y, p, m, InitOut, InitInput%WtrDpth, ErrStat2, ErrMsg2 ); if(Failed()) return @@ -376,6 +330,9 @@ SUBROUTINE SD_Init( InitInput, u, p, x, xd, z, OtherState, y, m, Interval, InitO CALL SDOUT_OpenOutput( SD_ProgDesc, Init%RootName, p, InitOut, ErrStat2, ErrMsg2 ); if(Failed()) return END IF + if (InitInput%Linearize) then + call SD_Init_Jacobian(Init, p, u, y, InitOut, ErrStat2, ErrMsg2); if(Failed()) return + endif ! Tell GLUECODE the SubDyn timestep interval Interval = p%SDdeltaT @@ -391,7 +348,6 @@ END FUNCTION Failed SUBROUTINE CleanUp() CALL SD_DestroyInitType(Init, ErrStat2, ErrMsg2) CALL SD_DestroyCB_MatArrays( CBparams, ErrStat2, ErrMsg2 ) ! local variables - CALL SD_DestroyFEM_MatArrays( FEMparams, ErrStat2, ErrMsg2 ) ! local variables END SUBROUTINE CleanUp END SUBROUTINE SD_Init @@ -420,7 +376,7 @@ SUBROUTINE SD_UpdateStates( t, n, Inputs, InputTimes, p, x, xd, z, OtherState, m ErrStat = ErrID_None ! no error has occurred ErrMsg = "" - IF ( p%qml == 0) RETURN ! no retained modes = no states + IF ( p%nDOFM == 0) RETURN ! no retained modes = no states IF (p%IntMethod .eq. 1) THEN CALL SD_RK4( t, n, Inputs, InputTimes, p, x, xd, z, OtherState, m, ErrStat, ErrMsg ) @@ -440,7 +396,7 @@ END SUBROUTINE SD_UpdateStates SUBROUTINE SD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds TYPE(SD_InputType), INTENT(IN ) :: u !< Inputs at t - TYPE(SD_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(SD_ParameterType),target,INTENT(IN ) :: p !< Parameters TYPE(SD_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at t TYPE(SD_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at t TYPE(SD_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at t @@ -451,157 +407,256 @@ SUBROUTINE SD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None !locals - INTEGER(IntKi) :: L1,L2 ! partial Lengths of state and input arrays - INTEGER(IntKi) :: I,J ! Counters + INTEGER(IntKi) :: I ! Counters + INTEGER(IntKi) :: iSDNode REAL(ReKi) :: AllOuts(0:MaxOutPts+p%OutAllInt*p%OutAllDims) REAL(ReKi) :: rotations(3) - REAL(ReKi) :: ULS(p%DOFL), UL0m(p%DOFL), FLt(p%DOFL) ! Temporary values in static improvement method + REAL(ReKi) :: ULS(p%nDOF__L), UL0m(p%nDOF__L), FLt(p%nDOF__L) ! Temporary values in static improvement method REAL(ReKi) :: Y1(6) - INTEGER(IntKi) :: startDOF - REAL(ReKi) :: DCM(3,3),junk(6,p%NNodes_L) - REAL(ReKi) :: HydroForces(6*p%NNodes_I) ! !Forces from all interface nodes listed in one big array ( those translated to TP ref point HydroTP(6) are implicitly calculated in the equations) + REAL(ReKi) :: Y1_CB(6) + REAL(ReKi) :: Y1_CB_L(6) + REAL(ReKi) :: Y1_Guy_R(6) + REAL(ReKi) :: Y1_Guy_L(6) + REAL(ReKi) :: Y1_Utp(6) + REAL(ReKi) :: Y1_GuyanLoadCorrection(3) ! Lever arm moment contributions due to interface displacement + REAL(ReKi) :: udotdot_TP(6) + INTEGER(IntKi), pointer :: DOFList(:) + REAL(ReKi) :: DCM(3,3) + REAL(ReKi) :: F_I(6*p%nNodes_I) ! !Forces from all interface nodes listed in one big array ( those translated to TP ref point HydroTP(6) are implicitly calculated in the equations) TYPE(SD_ContinuousStateType) :: dxdt ! Continuous state derivatives at t- for output file qmdotdot purposes only + ! Variables for Guayn rigid body motion + real(ReKi), dimension(3) :: Om, OmD ! Omega, OmegaDot (body rotational speed and acceleration) + real(ReKi), dimension(3) :: rIP ! Vector from TP to rotated Node + real(ReKi), dimension(3) :: rIP0 ! Vector from TP to Node (undeflected) + real(ReKi), dimension(3) :: Om_X_r ! Crossproduct of Omega and r + real(ReKi), dimension(3) :: duP ! Displacement of node due to rigid rotation + real(ReKi), dimension(3) :: vP ! Rigid-body velocity of node + real(ReKi), dimension(3) :: aP ! Rigid-body acceleration of node + real(R8Ki), dimension(3,3) :: Rg2b ! Rotation matrix global 2 body coordinates + real(R8Ki), dimension(3,3) :: Rb2g ! Rotation matrix body 2 global coordinates + real(R8Ki), dimension(6,6) :: RRb2g ! Rotation matrix global 2 body coordinates, acts on a 6-vector INTEGER(IntKi) :: ErrStat2 ! Error status of the operation (occurs after initial error) CHARACTER(ErrMsgLen) :: ErrMsg2 ! Error message if ErrStat2 /= ErrID_None - ! Initialize ErrStat ErrStat = ErrID_None ErrMsg = "" - + + ! --- Convert inputs to FEM DOFs and convenient 6-vector storage ! Compute the small rotation angles given the input direction cosine matrix rotations = GetSmllRotAngs(u%TPMesh%Orientation(:,:,1), ErrStat2, Errmsg2); if(Failed()) return - - ! Inputs at the transition piece: m%u_TP = (/REAL(u%TPMesh%TranslationDisp(:,1),ReKi), rotations/) m%udot_TP = (/u%TPMesh%TranslationVel( :,1), u%TPMesh%RotationVel(:,1)/) m%udotdot_TP = (/u%TPMesh%TranslationAcc( :,1), u%TPMesh%RotationAcc(:,1)/) - ! Inputs on interior nodes: - CALL ConstructUFL( u, p, m%UFL ) - - !________________________________________ - ! Set motion outputs on y%Y2mesh - !________________________________________ - ! Y2 = C2*x + D2*u + F2 (Eq. 17) - m%UR_bar = matmul( p%TI , m%u_TP ) ! UR_bar [ Y2(1) = 0*x(1) + D2(1,1)*u(1) ] - m%UR_bar_dot = matmul( p%TI , m%udot_TP ) ! UR_bar_dot [ Y2(3) = 0*x(1) + D2(3,2)*u(2) ] - m%UR_bar_dotdot = matmul( p%TI , m%udotdot_TP ) ! U_R_bar_dotdot [ Y2(5) = 0*x(2) + D2(5,3)*u(3) ] - - IF ( p%qml > 0) THEN - m%UL = matmul( p%PhiM, x%qm ) + matmul( p%PhiRb_TI, m%u_TP ) ! UL [ Y2(2) = C2(2,1)*x(1) + D2(2,1)*u(1) ] : IT MAY BE MODIFIED LATER IF STATIC IMPROVEMENT - m%UL_dot = matmul( p%PhiM, x%qmdot ) + matmul( p%PhiRb_TI, m%udot_TP ) ! UL_dot [ Y2(4) = C2(2,2)*x(2) + D2(4,2)*u(2) ] - m%UL_dotdot = matmul( p%C2_61, x%qm ) + matmul( p%C2_62 , x%qmdot ) & ! UL_dotdot [ Y2(6) = C2(6,1)*x(1) + C2(6,2)*x(2) ... - + matmul( p%D2_63, m%udotdot_TP ) + matmul( p%D2_64, m%UFL ) & ! + D2(6,3)*u(3) + D2(6,4)*u(4) ... ! -> bjj: this line takes up a lot of time. are any matrices sparse? - + p%F2_61 ! + F2(6) ] - ELSE ! There are no states when p%qml=0 (i.e., no retained modes: p%Nmodes=0), so we omit those portions of the equations - m%UL = matmul( p%PhiRb_TI, m%u_TP ) ! UL [ Y2(2) = 0*x(1) + D2(2,1)*u(1) ] : IT MAY BE MODIFIED LATER IF STATIC IMPROVEMENT - m%UL_dot = matmul( p%PhiRb_TI, m%udot_TP ) ! UL_dot [ Y2(4) = 0*x(2) + D2(4,2)*u(2) ] - m%UL_dotdot = matmul( p%PhiRb_TI, m%udotdot_TP ) ! UL_dotdot [ Y2(6) = 0*x(:) + D2(6,3)*u(3) + 0*u(4) + 0] - END IF - - !STATIC IMPROVEMENT METHOD ( modify UL ) - IF (p%SttcSolve) THEN - FLt = MATMUL(p%PhiL_T, m%UFL + p%FGL) ! -> bjj: todo: this line takes up A LOT of time. is PhiL sparse???? no (solution: don't call this routine thousands of time to calculate the jacobian) - ULS = MATMUL(p%PhiLInvOmgL2, FLt ) ! -> bjj: todo: this line takes up A LOT of time. is PhiL sparse???? + Rg2b(1:3,1:3) = u%TPMesh%Orientation(:,:,1) ! global 2 body coordinates + Rb2g(1:3,1:3) = transpose(u%TPMesh%Orientation(:,:,1)) + RRb2g(:,:) = 0.0_ReKi + RRb2g(1:3,1:3) = Rb2g + RRb2g(4:6,4:6) = Rb2g + + ! -------------------------------------------------------------------------------- + ! --- Output 2, Y2Mesh: motions on all FEM nodes (R, and L DOFs, then full DOF vector) + ! -------------------------------------------------------------------------------- + ! External force on internal nodes (F_L) + call GetExtForceOnInternalDOF(u, p, x, m, m%F_L, ErrStat2, ErrMsg2, GuyanLoadCorrection=(p%GuyanLoadCorrection.and..not.p%Floating), RotateLoads=(p%GuyanLoadCorrection.and.p%Floating)); if(Failed()) return + m%UR_bar = 0.0_ReKi + m%UR_bar_dot = 0.0_ReKi + m%UR_bar_dotdot = 0.0_ReKi + m%UL = 0.0_ReKi + m%UL_dot = 0.0_ReKi + m%UL_dotdot = 0.0_ReKi + ! --- CB modes contribution to motion (L-DOF only) + if ( p%nDOFM > 0) then + if (p%GuyanLoadCorrection.and.p%Floating) then ! >>> Rotate All + udotdot_TP(1:3) = matmul(Rg2b, u%TPMesh%TranslationAcc( :,1)) + udotdot_TP(4:6) = matmul(Rg2b, u%TPMesh%RotationAcc(:,1) ) + else + udotdot_TP = (/u%TPMesh%TranslationAcc( :,1), u%TPMesh%RotationAcc(:,1)/) + endif + m%UL = matmul( p%PhiM, x%qm ) + m%UL_dot = matmul( p%PhiM, x%qmdot ) + m%UL_dotdot = matmul( p%C2_61, x%qm ) + matmul( p%C2_62 , x%qmdot ) & + + matmul( p%D2_63, udotdot_TP ) + matmul( p%D2_64, m%F_L ) + end if + ! Static improvement (modify UL) + if (p%SttcSolve/=idSIM_None) then + FLt = MATMUL(p%PhiL_T , m%F_L) ! NOTE: Gravity in F_L + ULS = MATMUL(p%PhiLInvOmgL2, FLt ) + if ( p%nDOFM > 0) then + UL0M = MATMUL(p%PhiLInvOmgL2(:,1:p%nDOFM), FLt(1:p%nDOFM) ) + ULS = ULS-UL0M + end if m%UL = m%UL + ULS - - IF ( p%qml > 0) THEN - UL0M = MATMUL(p%PhiLInvOmgL2(:,1:p%qmL), FLt(1:p%qmL) ) - m%UL = m%UL - UL0M - END IF - ENDIF + endif + ! --- Adding Guyan contribution to R and L DOFs + if (.not.p%Floating) then + ! Then we add the Guyan motion here + m%UR_bar = matmul( p%TI , m%u_TP ) + m%UR_bar_dot = matmul( p%TI , m%udot_TP ) + m%UR_bar_dotdot = matmul( p%TI , m%udotdot_TP ) + m%UL = m%UL + matmul( p%PhiRb_TI, m%u_TP ) + m%UL_dot = m%UL_dot + matmul( p%PhiRb_TI, m%udot_TP ) + m%UL_dotdot = m%UL_dotdot + matmul( p%PhiRb_TI, m%udotdot_TP ) + else + ! We know that the Guyan modes are rigid body modes. + ! We will add them in the "Full system" later + endif + ! --- Build original DOF vectors (DOF before the CB reduction) + m%U_red (p%IDI__) = m%UR_bar + m%U_red (p%ID__L) = m%UL + m%U_red (p%IDC_Rb)= 0 ! NOTE: for now we don't have leader DOF at "C" (bottom) + m%U_red (p%ID__F) = 0 + m%U_red_dot (p%IDI__) = m%UR_bar_dot + m%U_red_dot (p%ID__L) = m%UL_dot + m%U_red_dot (p%IDC_Rb)= 0 ! NOTE: for now we don't have leader DOF at "C" (bottom) + m%U_red_dot (p%ID__F) = 0 + m%U_red_dotdot(p%IDI__) = m%UR_bar_dotdot + m%U_red_dotdot(p%ID__L) = m%UL_dotdot + m%U_red_dotdot(p%IDC_Rb)= 0 ! NOTE: for now we don't have leader DOF at "C" (bottom) + m%U_red_dotdot(p%ID__F) = 0 + + if (p%reduced) then + m%U_full = matmul(p%T_red, m%U_red) + m%U_full_dot = matmul(p%T_red, m%U_red_dot) + m%U_full_dotdot = matmul(p%T_red, m%U_red_dotdot) + else + m%U_full = m%U_red + m%U_full_dot = m%U_red_dot + m%U_full_dotdot = m%U_red_dotdot + endif + + ! Storing elastic motion (full motion for fixed bottom, CB motion only for floating) + m%U_full_elast = m%U_full - ! --------------------------------------------------------------------------------- - ! Place the outputs onto interface node portion of Y2 output mesh - ! --------------------------------------------------------------------------------- - DO I = 1, p%NNodes_I - startDOF = (I-1)*6 + 1 - ! Construct the direction cosine matrix given the output angles - CALL SmllRotTrans( 'UR_bar input angles', m%UR_bar(startDOF + 3), m%UR_bar(startDOF + 4), m%UR_bar(startDOF + 5), DCM, '', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SD_CalcOutput') - - y%Y2mesh%TranslationDisp (:,I) = m%UR_bar ( startDOF : startDOF + 2 ) - y%Y2mesh%Orientation (:,:,I) = DCM - y%Y2mesh%TranslationVel (:,I) = m%UR_bar_dot ( startDOF : startDOF + 2 ) - y%Y2mesh%RotationVel (:,I) = m%UR_bar_dot ( startDOF + 3 : startDOF + 5 ) - y%Y2mesh%TranslationAcc (:,I) = m%UR_bar_dotdot ( startDOF : startDOF + 2 ) - y%Y2mesh%RotationAcc (:,I) = m%UR_bar_dotdot ( startDOF + 3 : startDOF + 5 ) - - ENDDO - - ! --------------------------------------------------------------------------------- - ! Place the outputs onto interior node portion of Y2 output mesh - ! --------------------------------------------------------------------------------- - DO I = 1, p%NNodes_L !Only interior nodes here - ! starting index in the master arrays for the current node - startDOF = (I-1)*6 + 1 - - ! index into the Y2Mesh - J = p%NNodes_I + I - - ! Construct the direction cosine matrix given the output angles - CALL SmllRotTrans( 'UL input angles', m%UL(startDOF + 3), m%UL(startDOF + 4), m%UL(startDOF + 5), DCM, '', ErrStat2, ErrMsg2 ) + ! --- Place displacement/velocity/acceleration into Y2 output mesh + if (p%Floating) then + ! For floating, we compute the Guyan motion directly (rigid body motion with TP as origin) + ! This introduce non-linear "rotations" effects, where the bottom node should "go up", and not just translate horizontally + Om(1:3) = u%TPMesh%RotationVel(1:3,1) + OmD(1:3) = u%TPMesh%RotationAcc(1:3,1) + do iSDNode = 1,p%nNodes + DOFList => p%NodesDOF(iSDNode)%List ! Alias to shorten notations + ! --- Guyan (rigid body) motion in global coordinates + rIP0(1:3) = p%DP0(1:3, iSDNode) + rIP(1:3) = matmul(Rb2g, rIP0) + duP(1:3) = rIP - rIP0 + m%u_TP(1:3) + Om_X_r(1:3) = cross_product(Om, rIP) + vP(1:3) = u%TPMesh%TranslationVel(1:3,1) + Om_X_r + aP(1:3) = u%TPMesh%TranslationAcc(1:3,1) + cross_product(OmD, rIP) + cross_product(Om, Om_X_r) + + ! Full displacements CB-rotated + Guyan (KEEP ME) >>> Rotate All + if (p%GuyanLoadCorrection) then + m%U_full (DOFList(1:3)) = matmul(Rb2g, m%U_full (DOFList(1:3))) + duP(1:3) + m%U_full (DOFList(4:6)) = matmul(Rb2g, m%U_full (DOFList(4:6))) + rotations(1:3) + m%U_full_dot (DOFList(1:3)) = matmul(Rb2g, m%U_full_dot (DOFList(1:3))) + vP(1:3) + m%U_full_dot (DOFList(4:6)) = matmul(Rb2g, m%U_full_dot (DOFList(4:6))) + Om(1:3) + m%U_full_dotdot(DOFList(1:3)) = matmul(Rb2g, m%U_full_dotdot(DOFList(1:3))) + aP(1:3) + m%U_full_dotdot(DOFList(4:6)) = matmul(Rb2g, m%U_full_dotdot(DOFList(4:6))) + OmD(1:3) + else + m%U_full (DOFList(1:3)) = m%U_full (DOFList(1:3)) + duP(1:3) + m%U_full (DOFList(4:6)) = m%U_full (DOFList(4:6)) + rotations(1:3) + m%U_full_dot (DOFList(1:3)) = m%U_full_dot (DOFList(1:3)) + vP(1:3) + m%U_full_dot (DOFList(4:6)) = m%U_full_dot (DOFList(4:6)) + Om(1:3) + m%U_full_dotdot(DOFList(1:3)) = m%U_full_dotdot(DOFList(1:3)) + aP(1:3) + m%U_full_dotdot(DOFList(4:6)) = m%U_full_dotdot(DOFList(4:6)) + OmD(1:3) + endif + + ! NOTE: For now, displacements passed to HydroDyn are Guyan only! + ! Construct the direction cosine matrix given the output angles + !call SmllRotTrans( 'UR_bar input angles', m%U_full(DOFList(4)), m%U_full(DOFList(5)), m%U_full(DOFList(6)), DCM, '', ErrStat2, ErrMsg2) + call SmllRotTrans( 'UR_bar input angles', rotations(1), rotations(2), rotations(3), DCM, '', ErrStat2, ErrMsg2) ! NOTE: using only Guyan rotations + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SD_CalcOutput') + y%Y2mesh%Orientation (:,:,iSDNode) = DCM + !y%Y2mesh%TranslationDisp (:,iSDNode) = m%U_full (DOFList(1:3)) + y%Y2mesh%TranslationDisp (:,iSDNode) = duP(1:3) ! NOTE: using only the Guyan Displacements + y%Y2mesh%TranslationVel (:,iSDNode) = m%U_full_dot (DOFList(1:3)) + y%Y2mesh%TranslationAcc (:,iSDNode) = m%U_full_dotdot (DOFList(1:3)) + y%Y2mesh%RotationVel (:,iSDNode) = m%U_full_dot (DOFList(4:6)) + y%Y2mesh%RotationAcc (:,iSDNode) = m%U_full_dotdot (DOFList(4:6)) + enddo + else + ! --- Fixed bottom + do iSDNode = 1,p%nNodes + DOFList => p%NodesDOF(iSDNode)%List ! Alias to shorten notations + ! TODO TODO which orientation to give for joints with more than 6 dofs? + ! Construct the direction cosine matrix given the output angles + CALL SmllRotTrans( 'UR_bar input angles', m%U_full(DOFList(4)), m%U_full(DOFList(5)), m%U_full(DOFList(6)), DCM, '', ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SD_CalcOutput') - - ! Y2 = Interior node displacements and velocities for use as inputs to HydroDyn - y%Y2mesh%TranslationDisp (:,J) = m%UL ( startDOF : startDOF + 2 ) - y%Y2mesh%Orientation (:,:,J) = DCM - y%Y2mesh%TranslationVel (:,J) = m%UL_dot ( startDOF : startDOF + 2 ) - y%Y2mesh%RotationVel (:,J) = m%UL_dot ( startDOF + 3 : startDOF + 5 ) - - END DO - - !Repeat for the acceleration, there should be a way to combine into 1 loop - L1 = p%NNodes_I+1 - L2 = p%NNodes_I+p%NNodes_L - junk= RESHAPE(m%UL_dotdot,(/6 ,p%NNodes_L/)) - y%Y2mesh%TranslationAcc ( :,L1:L2) = junk(1:3,:) - y%Y2mesh%RotationAcc ( :,L1:L2) = junk(4:6,:) - - ! --------------------------------------------------------------------------------- - ! Base reaction nodes - ! --------------------------------------------------------------------------------- - L1 = p%NNodes_I+p%NNodes_L+1 - L2 = p%NNodes_I+p%NNodes_L+p%NReact - - y%Y2mesh%TranslationDisp( :,L1:L2) = 0.0 - CALL Eye( y%Y2mesh%Orientation(:,:,L1:L2), ErrStat2, ErrMsg2 ) ; if(Failed()) return - - y%Y2mesh%TranslationVel ( :,L1:L2) = 0.0 - y%Y2mesh%RotationVel ( :,L1:L2) = 0.0 - y%Y2mesh%TranslationAcc ( :,L1:L2) = 0.0 - y%Y2mesh%RotationAcc ( :,L1:L2) = 0.0 - - !________________________________________ - ! Set loads outputs on y%Y1Mesh - !________________________________________ - ! --------------------------------------------------------------------------------- - !Y1= TP reaction Forces, i.e. force that the jacket exerts onto the TP and above - ! --------------------------------------------------------------------------------- - ! Eq. 15: Y1 = -(C1*x + D1*u + FY) [note the negative sign!!!!] - !NEED TO ADD HYDRODYNAMIC FORCES AT THE Interface NODES - !Aggregate the forces and moments at the interface nodes to the reference point - !TODO: where are these HydroTP, HydroForces documented? - DO I = 1, p%NNodes_I - startDOF = (I-1)*6 + 1 - !Take care of Hydrodynamic Forces that will go into INterface Forces later - HydroForces(startDOF:startDOF+5 ) = (/u%LMesh%Force(:,I),u%LMesh%Moment(:,I)/) !(6,NNODES_I) - ENDDO - - !HydroTP = matmul(transpose(p%TI),HydroForces) ! (6,1) calculated below - ! note: matmul( HydroForces, p%TI ) = matmul( transpose(p%TI), HydroForces) because HydroForces is 1-D - IF ( p%qml > 0) THEN - Y1 = -( matmul(p%C1_11, x%qm) + matmul(p%C1_12,x%qmdot) & ! -( C1(1,1)*x(1) + C1(1,2)*x(2) - + matmul(p%KBB, m%u_TP) + matmul(p%D1_13, m%udotdot_TP) + matmul(p%D1_14, m%UFL) & ! + D1(1,1)*u(1) + 0*u(2) + D1(1,3)*u(3) + D1(1,4)*u(4) - - matmul( HydroForces, p%TI ) + p%FY ) ! + D1(1,5)*u(5) + Fy(1) ) - ELSE ! No retained modes, so there are no states - Y1 = -( matmul(p%KBB, m%u_TP) + matmul(p%MBB, m%udotdot_TP) + matmul(p%D1_14, m%UFL) & ! -( 0*x + D1(1,1)*u(1) + 0*u(2) + D1(1,3)*u(3) + D1(1,4)*u(4) - - matmul( HydroForces, p%TI ) + p%FY ) ! + D1(1,5)*u(5) + Fy(1) ) - END IF - + y%Y2mesh%Orientation (:,:,iSDNode) = DCM + y%Y2mesh%TranslationDisp (:,iSDNode) = m%U_full (DOFList(1:3)) + y%Y2mesh%TranslationVel (:,iSDNode) = m%U_full_dot (DOFList(1:3)) + y%Y2mesh%TranslationAcc (:,iSDNode) = m%U_full_dotdot (DOFList(1:3)) + y%Y2mesh%RotationVel (:,iSDNode) = m%U_full_dot (DOFList(4:6)) + y%Y2mesh%RotationAcc (:,iSDNode) = m%U_full_dotdot (DOFList(4:6)) + enddo + endif + + ! -------------------------------------------------------------------------------- + ! --- Outputs 1, Y1=-F_TP, reaction force from SubDyn to ElastoDyn (stored in y%Y1Mesh) + ! -------------------------------------------------------------------------------- + ! --- Special case for floating with extramoment + if (p%GuyanLoadCorrection.and.p%Floating) then + Y1_CB_L = - (matmul(p%D1_141, m%F_L)) ! Uses rotated loads + endif + + ! Compute external force on internal (F_L) and interface nodes (F_I) + call GetExtForceOnInternalDOF(u, p, x, m, m%F_L, ErrStat2, ErrMsg2, GuyanLoadCorrection=(p%GuyanLoadCorrection), RotateLoads=.False.); if(Failed()) return + call GetExtForceOnInterfaceDOF(p, m%Fext, F_I) + + ! Compute reaction/coupling force at TP + Y1_Utp = - (matmul(p%KBB, m%u_TP) + matmul(p%CBB, m%udot_TP) + matmul(p%MBB, m%udotdot_TP) ) + if (p%nDOFM>0) then + !>>> Rotate All + ! NOTE: this introduces some hysteresis + !if (p%Floating) then + ! udotdot_TP(1:3) = matmul(Rg2b, u%TPMesh%TranslationAcc( :,1)) + ! udotdot_TP(4:6) = matmul(Rg2b, u%TPMesh%RotationAcc(:,1) ) + ! Y1_Utp = Y1_Utp + matmul(RRb2g, matmul(p%MBmmB, udotdot_TP)) + !else + Y1_Utp = Y1_Utp + matmul(p%MBmmB, m%udotdot_TP) + !endif + endif + if ( p%nDOFM > 0) then + Y1_CB = -( matmul(p%C1_11, x%qm) + matmul(p%C1_12, x%qmdot) ) + if (p%GuyanLoadCorrection.and.p%Floating) then + Y1_CB = matmul(RRb2g, Y1_CB) !>>> Rotate All + endif + else + Y1_CB = 0.0_ReKi + endif + Y1_Guy_R = matmul( F_I, p%TI ) + Y1_Guy_L = - matmul(p%D1_142, m%F_L) ! non rotated loads + if (.not.(p%GuyanLoadCorrection.and.p%Floating)) then + Y1_CB_L = - (matmul(p%D1_141, m%F_L)) ! Uses non rotated loads + endif + if (p%GuyanLoadCorrection.and.p%Floating) then + Y1_CB_L = matmul(RRb2g, Y1_CB_L) !>>> Rotate All + endif + + Y1 = Y1_CB + Y1_Utp + Y1_CB_L+ Y1_Guy_L + Y1_Guy_R + ! KEEP ME + !if ( p%nDOFM > 0) then + ! Y1 = -( matmul(p%C1_11, x%qm) + matmul(p%C1_12,x%qmdot) & + ! + matmul(p%KBB, m%u_TP) + matmul(p%CBB, m%udot_TP) + matmul(p%MBB - p%MBmmB, m%udotdot_TP) & + ! + matmul(p%D1_141, m%F_L) + matmul(p%D1_142, m%F_L) - matmul( F_I, p%TI ) ) + !else ! No retained modes, so there are no states + ! Y1 = -( matmul(p%KBB, m%u_TP) + matmul(p%CBB, m%udot_TP) + matmul(p%MBB - p%MBmmB, m%udotdot_TP) & + ! + matmul(p%D1_141, m%F_L) + matmul(p%D1_142, m%F_L) - matmul( F_I, p%TI ) ) + !end if + + ! Computing extra moments due to lever arm introduced by interface displacement + ! Y1_MExtra = - MExtra = -u_TP x Y1(1:3) ! NOTE: double cancellation of signs + if (p%GuyanLoadCorrection) then + if (.not.p%floating) then ! if Fixed, transfer from non deflected TP to u_TP + Y1_GuyanLoadCorrection(1) = - m%u_TP(2) * Y1(3) + m%u_TP(3) * Y1(2) + Y1_GuyanLoadCorrection(2) = - m%u_TP(3) * Y1(1) + m%u_TP(1) * Y1(3) + Y1_GuyanLoadCorrection(3) = - m%u_TP(1) * Y1(2) + m%u_TP(2) * Y1(1) + Y1(4:6) = Y1(4:6) + Y1_GuyanLoadCorrection + endif + endif ! values on the interface mesh are Y1 (SubDyn forces) + Hydrodynamic forces y%Y1Mesh%Force (:,1) = Y1(1:3) - y%Y1Mesh%Moment(:,1) = Y1(4:6) - + y%Y1Mesh%Moment(:,1) = Y1(4:6) + !________________________________________ ! CALCULATE OUTPUT TO BE WRITTEN TO FILE !________________________________________ @@ -613,14 +668,17 @@ SUBROUTINE SD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) IF ( p%OutSwtch > 0 ) THEN ! call CalcContStateDeriv one more time to store these qmdotdot for debugging purposes in the output file !find xdot at t - IF ( p%NModes > 0 ) THEN - ! note that this re-sets m%udotdot_TP and m%UFL, but they are the same values as earlier in this routine so it doesn't change results in SDOut_MapOutputs() + IF ( p%nDOFM > 0 ) THEN + ! note that this re-sets m%udotdot_TP and m%F_L, but they are the same values as earlier in this routine so it doesn't change results in SDOut_MapOutputs() CALL SD_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dxdt, ErrStat2, ErrMsg2 ); if(Failed()) return !Assign the acceleration to the x variable since it will be used for output file purposes for SSqmdd01-99, and dxdt will disappear m%qmdotdot=dxdt%qmdot ! Destroy dxdt because it is not necessary for the rest of the subroutine CALL SD_DestroyContState( dxdt, ErrStat2, ErrMsg2); if(Failed()) return END IF + ! 6-vectors (making sure they are up to date for outputs + m%udot_TP = (/u%TPMesh%TranslationVel( :,1),u%TPMesh%RotationVel(:,1)/) + m%udotdot_TP = (/u%TPMesh%TranslationAcc(:,1), u%TPMesh%RotationAcc(:,1)/) ! Write the previous output data into the output file IF ( ( p%OutSwtch == 1 .OR. p%OutSwtch == 3 ) .AND. ( t > m%LastOutTime ) ) THEN @@ -633,7 +691,7 @@ SUBROUTINE SD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) END IF ! Map calculated results into the AllOuts Array + perform averaging and all necessary extra calculations - CALL SDOut_MapOutputs(t, u,p,x,y, m, AllOuts, ErrStat2, ErrMsg2); if(Failed()) return + CALL SDOut_MapOutputs(u, p, x, y, m, AllOuts, ErrStat2, ErrMsg2); if(Failed()) return ! Put the output data in the WriteOutput array DO I = 1,p%NumOuts+p%OutAllInt*p%OutAllDims @@ -660,7 +718,7 @@ END SUBROUTINE SD_CalcOutput !---------------------------------------------------------------------------------------------------------------------------------- !> Tight coupling routine for computing derivatives of continuous states -!! note that this also sets m%UFL and m%udotdot_TP +!! note that this also sets m%F_L and m%udotdot_TP SUBROUTINE SD_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dxdt, ErrStat, ErrMsg ) REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds TYPE(SD_InputType), INTENT(IN ) :: u !< Inputs at t @@ -673,6 +731,7 @@ SUBROUTINE SD_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dxdt, ErrSta TYPE(SD_ContinuousStateType), INTENT( OUT) :: dxdt !< Continuous state derivatives at t INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + REAL(ReKi) :: udotdot_TP(6) INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 ! Initialize ErrStat @@ -680,25 +739,25 @@ SUBROUTINE SD_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dxdt, ErrSta ErrMsg = "" ! INTENT(OUT) automatically deallocates the arrays on entry, we have to allocate them here - CALL AllocAry(dxdt%qm, p%qmL, 'dxdt%qm', ErrStat2, ErrMsg2 ); CALL SetErrStat ( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SD_CalcContStateDeriv' ) - CALL AllocAry(dxdt%qmdot, p%qmL, 'dxdt%qmdot', ErrStat2, ErrMsg2 ); CALL SetErrStat ( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SD_CalcContStateDeriv' ) + CALL AllocAry(dxdt%qm, p%nDOFM, 'dxdt%qm', ErrStat2, ErrMsg2 ); CALL SetErrStat ( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SD_CalcContStateDeriv' ) + CALL AllocAry(dxdt%qmdot, p%nDOFM, 'dxdt%qmdot', ErrStat2, ErrMsg2 ); CALL SetErrStat ( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SD_CalcContStateDeriv' ) IF ( ErrStat >= AbortErrLev ) RETURN - - IF ( p%qmL == 0 ) RETURN - - ! form u(3) in Eq. 10: - m%udotdot_TP = (/u%TPMesh%TranslationAcc(:,1), u%TPMesh%RotationAcc(:,1)/) - - ! form u(4) in Eq. 10: - CALL ConstructUFL( u, p, m%UFL ) + IF ( p%nDOFM == 0 ) RETURN + + ! Compute F_L, force on internal DOF + CALL GetExtForceOnInternalDOF(u, p, x, m, m%F_L, ErrStat2, ErrMsg2, GuyanLoadCorrection=(p%GuyanLoadCorrection.and..not.p%Floating), RotateLoads=(p%GuyanLoadCorrection.and.p%Floating)) + + udotdot_TP = (/u%TPMesh%TranslationAcc(:,1), u%TPMesh%RotationAcc(:,1)/) + if (p%GuyanLoadCorrection.and.p%Floating) then + ! >>> Rotate All - udotdot_TP to body coordinates + udotdot_TP(1:3) = matmul( u%TPMesh%Orientation(:,:,1), udotdot_TP(1:3) ) + udotdot_TP(4:6) = matmul( u%TPMesh%Orientation(:,:,1), udotdot_TP(4:6) ) + endif - !Equation 12: X=A*x + B*u + Fx (Eq 12) + ! State equation dxdt%qm= x%qmdot - - ! NOTE: matmul( TRANSPOSE(p%PhiM), m%UFL ) = matmul( m%UFL, p%PhiM ) because UFL is 1-D - != a(2,1) * x(1) + a(2,2) * x(2) + b(2,3) * u(3) + b(2,4) * u(4) + fx(2) - !dxdt%qmdot = p%NOmegaM2*x%qm + p%N2OmegaMJDamp*x%qmdot - matmul(p%MMB,m%udotdot_TP) + matmul(p%PhiM_T,m%UFL) + p%FX - dxdt%qmdot = p%NOmegaM2*x%qm + p%N2OmegaMJDamp*x%qmdot - matmul(p%MMB,m%udotdot_TP) + matmul(m%UFL, p%PhiM ) + p%FX + ! NOTE: matmul( TRANSPOSE(p%PhiM), m%F_L ) = matmul( m%F_L, p%PhiM ) because F_L is 1-D + dxdt%qmdot = -p%KMMDiag*x%qm - p%CMMDiag*x%qmdot - matmul(p%MMB,udotdot_TP) + matmul(m%F_L, p%PhiM) END SUBROUTINE SD_CalcContStateDeriv @@ -710,19 +769,22 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None ! local variable for input and output -CHARACTER(1024) :: PriPath ! The path to the primary input file -CHARACTER(1024) :: Line ! String to temporarially hold value of read line - +CHARACTER(1024) :: PriPath ! The path to the primary input file +CHARACTER(1024) :: Line, Dummy_Str ! String to temporarially hold value of read line +CHARACTER(64), ALLOCATABLE :: StrArray(:) ! Array of strings, for better control of table inputs LOGICAL :: Echo +LOGICAL :: LegacyFormat +LOGICAL :: bNumeric INTEGER(IntKi) :: UnIn +INTEGER(IntKi) :: nColumns, nColValid, nColNumeric INTEGER(IntKi) :: IOS INTEGER(IntKi) :: UnEc !Echo file ID - REAL(ReKi),PARAMETER :: WrongNo=-9999. ! Placeholder value for bad(old) values in JDampings - INTEGER(IntKi) :: I, J, flg, K -REAL(ReKi) :: Dummy_ReAry(SDMaxInpCols) +REAL(ReKi) :: Dummy_ReAry(SDMaxInpCols) , DummyFloat INTEGER(IntKi) :: Dummy_IntAry(SDMaxInpCols) +LOGICAL :: Dummy_Bool +INTEGER(IntKi) :: Dummy_Int INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 ! Initialize ErrStat @@ -783,9 +845,30 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) END IF CALL ReadVar ( UnIn, SDInputFile, p%IntMethod, 'IntMethod', 'Integration Method',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return -CALL ReadLVar(UnIn, SDInputFile, p%SttcSolve, 'SttcSolve', 'Solve dynamics about static equilibrium point', ErrStat2, ErrMsg2, UnEc); if(Failed()) return +CALL ReadVar (UnIn, SDInputFile, Dummy_Str, 'SttcSolve', 'Solve dynamics about static equilibrium point', ErrStat2, ErrMsg2, UnEc); if(Failed()) return +p%SttcSolve = idSIM_None +if (is_numeric(Dummy_Str, DummyFloat)) then + p%SttcSolve = int(DummyFloat) +else if (is_logical(Dummy_Str, Dummy_Bool)) then + if (Dummy_Bool) p%SttcSolve = idSIM_Full +else + call Fatal('SttcSolve should be an integer or a logical, received: '//trim(Dummy_Str)) + return +endif +IF (Check(.not.(any(idSIM_Valid==p%SttcSolve)), 'Invalid value entered for SttcSolve')) return + +! GuyanLoadCorrection - For legacy, allowing this line to be a comment +CALL ReadVar (UnIn, SDInputFile, Dummy_Str, 'GuyanLoadCorrection', 'Add extra lever arm contribution to interface loads', ErrStat2, ErrMsg2, UnEc); if(Failed()) return +if (is_logical(Dummy_Str, Dummy_Bool)) then ! the parameter was present + p%GuyanLoadCorrection=Dummy_Bool + ! We still need to read the comment on the next line + CALL ReadCom ( UnIn, SDInputFile, ' FEA and CRAIG-BAMPTON PARAMETERS ', ErrStat2, ErrMsg2, UnEc ); if(Failed()) return +else ! we have a actually read a comment line, we do nothing. + call LegacyWarning('ExtraMom line missing from input file. Assuming no extra moment.') + p%GuyanLoadCorrection=.False. ! For Legacy, GuyanLoadCorrection is False +endif + !-------------------- FEA and CRAIG-BAMPTON PARAMETERS--------------------------- -CALL ReadCom ( UnIn, SDInputFile, ' FEA and CRAIG-BAMPTON PARAMETERS ', ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL ReadIVar ( UnIn, SDInputFile, Init%FEMMod, 'FEMMod', 'FEM analysis mode' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return ! 0= Euler-Bernoulli(E-B); 1=Tapered E-B; 2= Timoshenko; 3= tapered Timoshenko CALL ReadIVar ( UnIn, SDInputFile, Init%NDiv , 'NDiv' , 'Number of divisions per member',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL ReadLVar ( UnIn, SDInputFile, Init%CBMod , 'CBMod' , 'C-B mod flag' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return @@ -793,74 +876,117 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) IF (Check( (p%IntMethod < 1) .OR.(p%IntMethod > 4) , 'IntMethod must be 1 through 4.')) return IF (Check( (Init%FEMMod < 0 ) .OR. ( Init%FEMMod > 4 ) , 'FEMMod must be 0, 1, 2, or 3.')) return IF (Check( Init%NDiv < 1 , 'NDiv must be a positive integer')) return +IF (Check( Init%FEMMod==2 , 'FEMMod = 2 (tapered Euler-Bernoulli) not implemented')) return +IF (Check( Init%FEMMod==4 , 'FEMMod = 4 (tapered Timoshenko) not implemented')) return IF (Init%CBMod) THEN ! Nmodes - Number of interal modes to retain. - CALL ReadIVar ( UnIn, SDInputFile, p%Nmodes, 'Nmodes', 'Number of internal modes',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return + CALL ReadIVar ( UnIn, SDInputFile, p%nDOFM, 'Nmodes', 'Number of internal modes',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return - IF (Check( p%Nmodes < 0 , 'Nmodes must be a non-negative integer.')) return + IF (Check( p%nDOFM < 0 , 'Nmodes must be a non-negative integer.')) return - if ( p%Nmodes > 0 ) THEN + if ( p%nDOFM > 0 ) THEN ! Damping ratios for retained modes - CALL AllocAry(Init%JDampings, p%Nmodes, 'JDamping', ErrStat2, ErrMsg2) ; if(Failed()) return + CALL AllocAry(Init%JDampings, p%nDOFM, 'JDamping', ErrStat2, ErrMsg2) ; if(Failed()) return Init%JDampings=WrongNo !Initialize - CALL ReadAry( UnIn, SDInputFile, Init%JDampings, p%Nmodes, 'JDamping', 'Damping ratio of the internal modes', ErrStat2, ErrMsg2, UnEc ); + CALL ReadAry( UnIn, SDInputFile, Init%JDampings, p%nDOFM, 'JDamping', 'Damping ratio of the internal modes', ErrStat2, ErrMsg2, UnEc ); ! note that we don't check the ErrStat2 here; if the user entered fewer than Nmodes values, we will use the ! last entry to fill in remaining values. !Check 1st value, we need at least one good value from user or throw error - IF ((Init%JDampings(1) < 0 ) .OR. (Init%JDampings(1) >= 100.0)) THEN - CALL Fatal('Damping ratio should be larger than 0 and less than 100') - return - ELSE - DO I = 2, p%Nmodes - IF ( Init%JDampings(I) .EQ. WrongNo ) THEN - Init%Jdampings(I:p%Nmodes)=Init%JDampings(I-1) - IF (i /= 2) THEN ! display an informational message if we're repeating the last value (unless we only entered one value) - ErrStat = ErrID_Info - ErrMsg = 'Using damping ratio '//trim(num2lstr(Init%JDampings(I-1)))//' for modes '//trim(num2lstr(I))//' - '//trim(num2lstr(p%Nmodes))//'.' - END IF - EXIT - ELSEIF ( ( Init%JDampings(I) < 0 ) .OR.( Init%JDampings(I) >= 100.0 ) ) THEN - CALL Fatal('Damping ratio should be larger than 0 and less than 100') - return - ENDIF - ENDDO - ENDIF + DO I = 2, p%nDOFM + IF ( Init%JDampings(I) .EQ. WrongNo ) THEN + Init%Jdampings(I:p%nDOFM)=Init%JDampings(I-1) + IF (i /= 2) THEN ! display an informational message if we're repeating the last value (unless we only entered one value) + ErrStat = ErrID_Info + ErrMsg = 'Using damping ratio '//trim(num2lstr(Init%JDampings(I-1)))//' for modes '//trim(num2lstr(I))//' - '//trim(num2lstr(p%nDOFM))//'.' + END IF + EXIT + ENDIF + ENDDO IF (ErrStat2 /= ErrID_None .AND. Echo) THEN ! ReadAry had an error because it couldn't read the entire array so it didn't write this to the echo file; we assume the last-read values are used for remaining JDampings - WRITE( UnEc, Ec_ReAryFrmt ) 'JDamping', 'Damping ratio of the internal modes', Init%Jdampings(1:MIN(p%Nmodes,NWTC_MaxAryLen)) + WRITE( UnEc, Ec_ReAryFrmt ) 'JDamping', 'Damping ratio of the internal modes', Init%Jdampings(1:MIN(p%nDOFM,NWTC_MaxAryLen)) END IF ELSE CALL ReadCom( UnIn, SDInputFile, 'JDamping', ErrStat2, ErrMsg2, UnEc ); if(Failed()) return END IF ELSE !CBMOD=FALSE : all modes are retained, not sure how many they are yet - !note at this stage I do not know DOFL yet; Nmodes will be updated later for the FULL FEM CASE. - p%Nmodes = -1 + !note at this stage I do not know nDOFL yet; Nmodes will be updated later for the FULL FEM CASE. + p%nDOFM = -1 !Ignore next line CALL ReadCom( UnIn, SDInputFile, 'Nmodes', ErrStat2, ErrMsg2, UnEc ); if(Failed()) return !Read 1 damping value for all modes CALL AllocAry(Init%JDampings, 1, 'JDamping', ErrStat2, ErrMsg2) ; if(Failed()) return CALL ReadVar ( UnIn, SDInputFile, Init%JDampings(1), 'JDampings', 'Damping ratio',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return - IF ( ( Init%JDampings(1) < 0 ) .OR.( Init%JDampings(1) >= 100.0 ) ) THEN - CALL Fatal('Damping ratio should be larger than 0 and less than 100.') - RETURN - ENDIF ENDIF -IF ((p%Nmodes > 0) .OR. (.NOT.(Init%CBMod))) THEN !This if should not be at all, dampings should be divided by 100 regardless, also if CBmod=false p%Nmodes is undefined, but if Nmodes=0 then JDampings does not exist +IF ((p%nDOFM > 0) .OR. (.NOT.(Init%CBMod))) THEN !This if should not be at all, dampings should be divided by 100 regardless, also if CBmod=false p%nDOFM is undefined, but if Nmodes=0 then JDampings does not exist Init%JDampings = Init%JDampings/100.0_ReKi !now the 20 is .20 as it should in all cases for 1 or Nmodes JDampings END IF +! --- Guyan damping +! For legacy, allowing these lines to be missing +CALL ReadVar (UnIn, SDInputFile, Dummy_Str, 'GuyanDampMod', 'Guyan damping', ErrStat2, ErrMsg2, UnEc); if(Failed()) return +if (is_numeric(Dummy_Str, DummyFloat)) then + Init%GuyanDampMod=int(DummyFloat) + CALL ReadAry( UnIn, SDInputFile, Init%RayleighDamp, 2, "RayleighDamp", "", ErrStat2, ErrMsg2, UnEc) + CALL ReadVar (UnIn, SDInputFile, Dummy_Int, 'GuyanDampSize', 'Guyan damping matrix size', ErrStat2, ErrMsg2, UnEc); if(Failed()) return + IF (Check(Dummy_Int/=6, 'Invalid value entered for GuyanDampSize, value should be 6 for now.')) return + CALL ReadAry( UnIn, SDInputFile, Init%GuyanDampMat(1,:), 6, "GuyanDampMat1", "Guyan Damping matrix ", ErrStat2, ErrMsg2, UnEc) + CALL ReadAry( UnIn, SDInputFile, Init%GuyanDampMat(2,:), 6, "GuyanDampMat2", "Guyan Damping matrix ", ErrStat2, ErrMsg2, UnEc) + CALL ReadAry( UnIn, SDInputFile, Init%GuyanDampMat(3,:), 6, "GuyanDampMat3", "Guyan Damping matrix ", ErrStat2, ErrMsg2, UnEc) + CALL ReadAry( UnIn, SDInputFile, Init%GuyanDampMat(4,:), 6, "GuyanDampMat4", "Guyan Damping matrix ", ErrStat2, ErrMsg2, UnEc) + CALL ReadAry( UnIn, SDInputFile, Init%GuyanDampMat(5,:), 6, "GuyanDampMat5", "Guyan Damping matrix ", ErrStat2, ErrMsg2, UnEc) + CALL ReadAry( UnIn, SDInputFile, Init%GuyanDampMat(6,:), 6, "GuyanDampMat6", "Guyan Damping matrix ", ErrStat2, ErrMsg2, UnEc) + CALL ReadCom ( UnIn, SDInputFile, 'STRUCTURE JOINTS' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return +else + call LegacyWarning('GuyanDampMod and following lines missing from input file. Assuming 0 Guyan damping.') + Init%GuyanDampMod = idGuyanDamp_None + Init%RayleighDamp = 0.0_ReKi + Init%GuyanDampMat = 0.0_ReKi +endif +IF (Check(.not.(any(idGuyanDamp_Valid==Init%GuyanDampMod)), 'Invalid value entered for GuyanDampMod')) return + !--------------------- STRUCTURE JOINTS: joints connect structure members ------------------------------- -CALL ReadCom ( UnIn, SDInputFile, 'STRUCTURE JOINTS' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL ReadIVar ( UnIn, SDInputFile, Init%NJoints, 'NJoints', 'Number of joints',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL ReadCom ( UnIn, SDInputFile, 'Joint Coordinates Headers' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL ReadCom ( UnIn, SDInputFile, 'Joint Coordinates Units' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL AllocAry(Init%Joints, Init%NJoints, JointsCol, 'Joints', ErrStat2, ErrMsg2 ); if(Failed()) return -DO I = 1, Init%NJoints - CALL ReadAry( UnIn, SDInputFile, Dummy_ReAry, JointsCol, 'Joints', 'Joint number and coordinates', ErrStat2, ErrMsg2, UnEc ); if(Failed()) return - Init%Joints(I,:) = Dummy_ReAry(1:JointsCol) +IF (Check( Init%NJoints < 2, 'NJoints must be greater than 1')) return +! --- Reading first line to detect file format +READ(UnIn, FMT='(A)', IOSTAT=ErrStat2) Line ; ErrMsg2='First line of joints array'; if (Failed()) return +! --- Reading first line to detect file format based on number of columns +nColumns=JointsCol +CALL AllocAry(StrArray, nColumns, 'StrArray',ErrStat2,ErrMsg2); if (Failed()) return +CALL ReadCAryFromStr ( Line, StrArray, nColumns, 'Joints', 'First line of joints array', ErrStat2, ErrMsg2 ) +if (ErrStat2/=0) then + ! We try with 4 columns (legacy format) + nColumns = 4 + deallocate(StrArray) + CALL AllocAry(StrArray, nColumns, 'StrArray',ErrStat2,ErrMsg2); if (Failed()) return + CALL ReadCAryFromStr ( Line, StrArray, nColumns, 'Joints', 'First line of joints array', ErrStat2, ErrMsg2 ); if(Failed()) return + call LegacyWarning('Joint table contains 4 columns instead of 9. All joints will be assumed cantilever, all members regular beams.') + Init%Joints(:,iJointType) = idJointCantilever ! All joints assumed cantilever + Init%Joints(:,iJointType+1:JointsCol) = 0.0 ! remaining columns set to 0 + LegacyFormat=.True. ! Legacy format - Delete me in 2024 +else + ! New format + LegacyFormat=.False. +endif +! Extract fields from first line +DO I = 1, nColumns + bNumeric = is_numeric(StrArray(I), Init%Joints(1,I)) ! Convert from string to float + if (.not.bNumeric) then + CALL Fatal(' Error in file "'//TRIM(SDInputFile)//'": Non numeric character found in Joints line. Problematic line: "'//trim(Line)//'"') + return + endif +ENDDO +deallocate(StrArray) +! Read remaining lines +DO I = 2, Init%NJoints + CALL ReadAry( UnIn, SDInputFile, Dummy_ReAry, nColumns, 'Joints', 'Joint number and coordinates', ErrStat2, ErrMsg2, UnEc ); if(Failed()) return + Init%Joints(I,1:nColumns) = Dummy_ReAry(1:nColumns) ENDDO IF (Check( Init%NJoints < 2, 'NJoints must be greater than 1')) return @@ -870,28 +996,73 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) !------------------- BASE REACTION JOINTS: T/F for Locked/Free DOF @ each Reaction Node --------------------- ! The joints should be all clamped for now CALL ReadCom ( UnIn, SDInputFile, 'BASE REACTION JOINTS' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return -CALL ReadIVar ( UnIn, SDInputFile, p%NReact, 'NReact', 'Number of joints with reaction forces',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return +CALL ReadIVar ( UnIn, SDInputFile, p%nNodes_C, 'NReact', 'Number of joints with reaction forces',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL ReadCom ( UnIn, SDInputFile, 'Base reaction joints headers ' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL ReadCom ( UnIn, SDInputFile, 'Base reaction joints units ' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return -CALL AllocAry(p%Reacts, p%NReact, ReactCol, 'Reacts', ErrStat2, ErrMsg2 ); if(Failed()) return -DO I = 1, p%NReact - CALL ReadAry( UnIn, SDInputFile, Dummy_IntAry, ReactCol, 'Reacts', 'Joint number and dof', ErrStat2 ,ErrMsg2, UnEc); if(Failed()) return - p%Reacts(I,:) = Dummy_IntAry(1:ReactCol) -ENDDO -IF (Check ( ( p%NReact < 1 ) .OR. (p%NReact > Init%NJoints) , 'NReact must be greater than 0 and less than number of joints')) return + +CALL AllocAry(p%Nodes_C, p%nNodes_C, ReactCol , 'Reacts', ErrStat2, ErrMsg2 ); if(Failed()) return +p%Nodes_C(:,:) = 1 ! Important: By default all DOFs are contrained +p%Nodes_C(:,1) = -1 ! First column is node, initalize to wrong value for safety + +call AllocAry(Init%SSIfile, p%nNodes_C, 'SSIFile', ErrStat2, ErrMsg2); if(Failed()) return +call AllocAry(Init%SSIK, 21, p%nNodes_C, 'SSIK', ErrStat2, ErrMsg2); if(Failed()) return +call AllocAry(Init%SSIM, 21, p%nNodes_C, 'SSIM', ErrStat2, ErrMsg2); if(Failed()) return +Init%SSIfile(:) = '' +Init%SSIK = 0.0_ReKi ! Important init TODO: read these matrices on the fly in SD_FEM maybe? +Init%SSIM = 0.0_ReKi ! Important init +! Reading reaction lines one by one, allowing for 1, 7 or 8 columns, with col8 being a string for the SSIfile +do I = 1, p%nNodes_C + READ(UnIn, FMT='(A)', IOSTAT=ErrStat2) Line; ErrMsg2='Error reading reaction line'; if (Failed()) return + call ReadIAryFromStr(Line, p%Nodes_C(I,:), 8, nColValid, nColNumeric, Init%SSIfile(I:I)); + if (nColValid==1 .and. nColNumeric==1) then + ! Temporary allowing this + call LegacyWarning('SubDyn reaction line has only 1 column. Please use 7 or 8 values') + else if (nColNumeric==7 .and.(nColValid==7.or.nColValid==8)) then + ! This is fine. + else + call Fatal(' Error in file "'//TRIM(SDInputFile)//'": Reaction lines must consist of 7 numerical values, followed by an optional string. Problematic line: "'//trim(Line)//'"') + return + endif +enddo +IF (Check ( p%nNodes_C > Init%NJoints , 'NReact must be less than number of joints')) return +call CheckBCs(p, ErrStat2, ErrMsg2); if (Failed()) return + +! Trigger - Reading SSI matrices if present +DO I = 1, p%nNodes_C + if ( Init%SSIfile(I)/='' .and. (ANY(p%Nodes_C(I,2:ReactCol)==idBC_Internal))) then + Init%SSIfile(I) = trim(PriPath)//trim(Init%SSIfile(I)) + CALL ReadSSIfile( Init%SSIfile(I), p%Nodes_C(I,1), Init%SSIK(:,I),Init%SSIM(:,I), ErrStat, ErrMsg, UnEc ); if(Failed()) return + endif +enddo +! Trigger: determine if floating/fixed based on BCs and SSI file +p%Floating = isFloating(Init,p) + !------- INTERFACE JOINTS: T/F for Locked (to the TP)/Free DOF @each Interface Joint (only Locked-to-TP implemented thus far (=rigid TP)) --------- ! Joints with reaction forces, joint number and locked/free dof -CALL ReadCom ( UnIn, SDInputFile, 'INTERFACE JOINTS' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return -CALL ReadIVar ( UnIn, SDInputFile, Init%NInterf, 'NInterf', 'Number of joints fixed to TP',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return -CALL ReadCom ( UnIn, SDInputFile, 'Interface joints headers',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return -CALL ReadCom ( UnIn, SDInputFile, 'Interface joints units ',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return -CALL AllocAry(Init%Interf, Init%NInterf, InterfCol, 'Interf', ErrStat2, ErrMsg2); if(Failed()) return -DO I = 1, Init%NInterf - CALL ReadIAry( UnIn, SDInputFile, Dummy_IntAry, InterfCol, 'Interf', 'Interface joint number and dof', ErrStat2,ErrMsg2, UnEc); if(Failed()) return - Init%Interf(I,:) = Dummy_IntAry(1:InterfCol) +CALL ReadCom ( UnIn, SDInputFile, 'INTERFACE JOINTS' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return +CALL ReadIVar ( UnIn, SDInputFile, p%nNodes_I, 'NInterf', 'Number of joints fixed to TP',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return +CALL ReadCom ( UnIn, SDInputFile, 'Interface joints headers',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return +CALL ReadCom ( UnIn, SDInputFile, 'Interface joints units ',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return + +CALL AllocAry(p%Nodes_I, p%nNodes_I, InterfCol, 'Interf', ErrStat2, ErrMsg2); if(Failed()) return +p%Nodes_I(:,:) = 1 ! Important: By default all DOFs are contrained +p%Nodes_I(:,1) = -1 ! First column is node, initalize to wrong value for safety +! Reading interface lines one by one, allowing for 1 or 7 columns (cannot use ReadIAry) +DO I = 1, p%nNodes_I + READ(UnIn, FMT='(A)', IOSTAT=ErrStat2) Line ; ErrMsg2='Error reading interface line'; if (Failed()) return + call ReadIAryFromStr(Line, p%Nodes_I(I,:), 7, nColValid, nColNumeric); + if ((nColValid/=nColNumeric).or.((nColNumeric/=1).and.(nColNumeric/=7)) ) then + CALL Fatal(' Error in file "'//TRIM(SDInputFile)//'": Interface line must consist of 1 or 7 numerical values. Problematic line: "'//trim(Line)//'"') + return + endif + if (any(p%Nodes_I(I,:)<=0)) then + CALL Fatal(' Error in file "'//TRIM(SDInputFile)//'": For now, all DOF must be activated for interface lines. Problematic line: "'//trim(Line)//'"') + return + endif ENDDO -IF (Check( ( Init%NInterf < 0 ) .OR. (Init%NInterf > Init%NJoints), 'NInterf must be non-negative and less than number of joints.')) RETURN +IF (Check( ( p%nNodes_I < 0 ) .OR. (p%nNodes_I > Init%NJoints), 'NInterf must be non-negative and less than number of joints.')) RETURN +call CheckIntf(p, ErrStat2, ErrMsg2); if (Failed()) return !----------------------------------- MEMBERS -------------------------------------- ! One day we will need to take care of COSMIDs for non-circular members @@ -900,34 +1071,79 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) CALL ReadCom ( UnIn, SDInputFile, 'Members Headers' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL ReadCom ( UnIn, SDInputFile, 'Members Units ' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL AllocAry(Init%Members, p%NMembers, MembersCol, 'Members', ErrStat2, ErrMsg2) +Init%Members(:,:) = 0.0_ReKi +if (LegacyFormat) then + nColumns = 5 + Init%Members(:,iMType) = idMemberBeam ! Important, in legacy all members are beams +else + nColumns = MembersCol +endif DO I = 1, p%NMembers - CALL ReadAry( UnIn, SDInputFile, Dummy_IntAry, MembersCol, 'Members', 'Member number and connectivity ', ErrStat2,ErrMsg2, UnEc); if(Failed()) return - Init%Members(I,:) = Dummy_IntAry(1:MembersCol) + CALL ReadAry( UnIn, SDInputFile, Dummy_IntAry, nColumns, 'Members line '//Num2LStr(I), 'Member number and connectivity ', ErrStat2,ErrMsg2, UnEc); if(Failed()) return + Init%Members(I,1:nColumns) = Dummy_IntAry(1:nColumns) ENDDO IF (Check( p%NMembers < 1 , 'NMembers must be > 0')) return !------------------ MEMBER X-SECTION PROPERTY data 1/2 [isotropic material for now: use this table if circular-tubular elements ------------------------ CALL ReadCom ( UnIn, SDInputFile, ' Member X-Section Property Data 1/2 ',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return -CALL ReadIVar ( UnIn, SDInputFile, Init%NPropSets, 'NPropSets', 'Number of property sets',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return +CALL ReadIVar ( UnIn, SDInputFile, Init%NPropSetsB, 'NPropSets', 'Number of property sets',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL ReadCom ( UnIn, SDInputFile, 'Property Data 1/2 Header' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL ReadCom ( UnIn, SDInputFile, 'Property Data 1/2 Units ' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return -CALL AllocAry(Init%PropSets, Init%NPropSets, PropSetsCol, 'ProSets', ErrStat2, ErrMsg2) ; if(Failed()) return -DO I = 1, Init%NPropSets - CALL ReadAry( UnIn, SDInputFile, Dummy_ReAry, PropSetsCol, 'PropSets', 'PropSets number and values ', ErrStat2 , ErrMsg2, UnEc); if(Failed()) return - Init%PropSets(I,:) = Dummy_ReAry(1:PropSetsCol) +CALL AllocAry(Init%PropSetsB, Init%NPropSetsB, PropSetsBCol, 'ProSets', ErrStat2, ErrMsg2) ; if(Failed()) return +DO I = 1, Init%NPropSetsB + CALL ReadAry( UnIn, SDInputFile, Dummy_ReAry, PropSetsBCol, 'PropSets', 'PropSets number and values ', ErrStat2 , ErrMsg2, UnEc); if(Failed()) return + Init%PropSetsB(I,:) = Dummy_ReAry(1:PropSetsBCol) ENDDO -IF (Check( Init%NPropSets < 1 , 'NPropSets must be >0')) return +IF (Check( Init%NPropSetsB < 1 , 'NPropSets must be >0')) return !------------------ MEMBER X-SECTION PROPERTY data 2/2 [isotropic material for now: use this table if any section other than circular, however provide COSM(i,j) below) ------------------------ CALL ReadCom ( UnIn, SDInputFile, 'Member X-Section Property Data 2/2 ' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return -CALL ReadIVar ( UnIn, SDInputFile, Init%NXPropSets, 'NXPropSets', 'Number of non-circular property sets',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return +CALL ReadIVar ( UnIn, SDInputFile, Init%NPropSetsX, 'NXPropSets', 'Number of non-circular property sets',ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL ReadCom ( UnIn, SDInputFile, 'Property Data 2/2 Header' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL ReadCom ( UnIn, SDInputFile, 'Property Data 2/2 Unit ' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return -CALL AllocAry(Init%XPropSets, Init%NXPropSets, XPropSetsCol, 'XPropSets', ErrStat2, ErrMsg2); if(Failed()) return -DO I = 1, Init%NXPropSets - CALL ReadAry( UnIn, SDInputFile, Init%XPropSets(I,:), XPropSetsCol, 'XPropSets', 'XPropSets ID and values ', ErrStat2, ErrMsg2, UnEc ); if(Failed()) return +CALL AllocAry(Init%PropSetsX, Init%NPropSetsX, PropSetsXCol, 'XPropSets', ErrStat2, ErrMsg2); if(Failed()) return +DO I = 1, Init%NPropSetsX + CALL ReadAry( UnIn, SDInputFile, Init%PropSetsX(I,:), PropSetsXCol, 'XPropSets', 'XPropSets ID and values ', ErrStat2, ErrMsg2, UnEc ); if(Failed()) return ENDDO -IF (Check( Init%NXPropSets < 0, 'NXPropSets must be >=0')) return +IF (Check( Init%NPropSetsX < 0, 'NXPropSets must be >=0')) return + +if (.not. LegacyFormat) then + !-------------------------- CABLE PROPERTIES ------------------------------------- + CALL ReadCom ( UnIn, SDInputFile, 'Cable properties' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return + CALL ReadIVar ( UnIn, SDInputFile, Init%NPropSetsC, 'NPropSetsC', 'Number of cable properties' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return + CALL ReadCom ( UnIn, SDInputFile, 'Cable properties Header' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return + CALL ReadCom ( UnIn, SDInputFile, 'Cable properties Unit ' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return + IF (Check( Init%NPropSetsC < 0, 'NPropSetsCable must be >=0')) return + CALL AllocAry(Init%PropSetsC, Init%NPropSetsC, PropSetsCCol, 'PropSetsC', ErrStat2, ErrMsg2); if(Failed()) return + DO I = 1, Init%NPropSetsC + !CALL ReadAry( UnIn, SDInputFile, Init%PropSetsC(I,:), PropSetsCCol, 'PropSetsC', 'PropSetsC ID and values ', ErrStat2, ErrMsg2, UnEc ); if(Failed()) return + READ(UnIn, FMT='(A)', IOSTAT=ErrStat2) Line; ErrMsg2='Error reading cable property line'; if (Failed()) return + call ReadFAryFromStr(Line, Init%PropSetsC(I,:), PropSetsCCol, nColValid, nColNumeric); + if ((nColValid/=nColNumeric).or.((nColNumeric/=4).and.(nColNumeric/=PropSetsCCol)) ) then + CALL Fatal(' Error in file "'//TRIM(SDInputFile)//'": Cable property line must consist of 4 or 5 numerical values. Problematic line: "'//trim(Line)//'"') + return + endif + if (nColNumeric==4) then + call LegacyWarning('Using 4 values instead of 5 for cable properties. Cable will have constant properties and wont be controllable.') + Init%PropSetsC(:,5:PropSetsCCol)=0 ! No CtrlChannel + endif + ENDDO + !----------------------- RIGID LINK PROPERTIES ------------------------------------ + CALL ReadCom ( UnIn, SDInputFile, 'Rigid link properties' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return + CALL ReadIVar ( UnIn, SDInputFile, Init%NPropSetsR, 'NPropSetsR', 'Number of rigid link properties' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return + CALL ReadCom ( UnIn, SDInputFile, 'Rigid link properties Header' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return + CALL ReadCom ( UnIn, SDInputFile, 'Rigid link properties Unit ' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return + CALL AllocAry(Init%PropSetsR, Init%NPropSetsR, PropSetsRCol, 'RigidPropSets', ErrStat2, ErrMsg2); if(Failed()) return + DO I = 1, Init%NPropSetsR + CALL ReadAry( UnIn, SDInputFile, Init%PropSetsR(I,:), PropSetsRCol, 'RigidPropSets', 'RigidPropSets ID and values ', ErrStat2, ErrMsg2, UnEc ); if(Failed()) return + ENDDO + IF (Check( Init%NPropSetsR < 0, 'NPropSetsRigid must be >=0')) return +else + Init%NPropSetsC=0 + Init%NPropSetsR=0 + CALL AllocAry(Init%PropSetsC, Init%NPropSetsC, PropSetsCCol, 'PropSetsC', ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(Init%PropSetsR, Init%NPropSetsR, PropSetsRCol, 'RigidPropSets', ErrStat2, ErrMsg2); if(Failed()) return +endif !---------------------- MEMBER COSINE MATRICES COSM(i,j) ------------------------ CALL ReadCom ( UnIn, SDInputFile, 'Member direction cosine matrices ' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return @@ -942,15 +1158,28 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) !------------------------ JOINT ADDITIONAL CONCENTRATED MASSES-------------------------- CALL ReadCom ( UnIn, SDInputFile, 'Additional concentrated masses at joints ' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return -CALL ReadIVar ( UnIn, SDInputFile, Init%NCMass, 'NCMass', 'Number of joints that have concentrated masses',ErrStat2, ErrMsg2, UnEc); if(Failed()) return +CALL ReadIVar ( UnIn, SDInputFile, Init%nCMass, 'nCMass', 'Number of joints that have concentrated masses',ErrStat2, ErrMsg2, UnEc); if(Failed()) return CALL ReadCom ( UnIn, SDInputFile, 'Concentrated Mass Headers' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL ReadCom ( UnIn, SDInputFile, 'Concentrated Mass Units' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return -CALL AllocAry(Init%CMass, Init%NCMass, CMassCol, 'CMass', ErrStat2, ErrMsg2); if(Failed()) return -Init%CMass = 0.0 -DO I = 1, Init%NCMass - CALL ReadAry( UnIn, SDInputFile, Init%CMass(I,:), CMassCol, 'CMass', 'Joint number and mass values ', ErrStat2, ErrMsg2, UnEc ); if(Failed()) return +CALL AllocAry(Init%CMass, Init%nCMass, CMassCol, 'CMass', ErrStat2, ErrMsg2); if(Failed()) return +Init%CMass = 0.0 ! Important init since we allow user to only provide diagonal terms +DO I = 1, Init%nCMass + ! CALL ReadAry( UnIn, SDInputFile, Init%CMass(I,:), CMassCol, 'CMass', 'Joint number and mass values ', ErrStat2, ErrMsg2, UnEc ); if(Failed()) return + READ(UnIn, FMT='(A)', IOSTAT=ErrStat2) Line; ErrMsg2='Error reading concentrated mass line'; if (Failed()) return + call ReadFAryFromStr(Line, Init%CMass(I,:), CMassCol, nColValid, nColNumeric); + if ((nColValid/=nColNumeric).or.((nColNumeric/=5).and.(nColNumeric/=11)) ) then + CALL Fatal(' Error in file "'//TRIM(SDInputFile)//'": Interface line must consist of 5 or 11 numerical values. Problematic line: "'//trim(Line)//'"') + return + endif + if (Init%CMass(I,1)<=0) then ! Further checks in JointIDs are done in SD_FEM + CALL Fatal(' Error in file "'//TRIM(SDInputFile)//'": Invalid concentrated mass JointID. Problematic line: "'//trim(Line)//'"') + return + endif + if (nColNumeric==5) then + call LegacyWarning('Using 5 values instead of 11 for concentrated mass. Off-diagonal terms will be assumed 0.') + endif ENDDO -IF (Check( Init%NCMass < 0 , 'NCMass must be >=0')) return +IF (Check( Init%nCMass < 0 , 'NCMass must be >=0')) return !---------------------------- OUTPUT: SUMMARY & OUTFILE ------------------------------ CALL ReadCom (UnIn, SDInputFile, 'OUTPUT' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return @@ -1032,7 +1261,7 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) ENDIF ENDIF ENDDO - IF (Check (flg .EQ. 0 , ' MemberID is not in the Members list. ')) return + IF (Check (flg .EQ. 0 , ' MemberID '//trim(Num2LStr(p%MOutLst(I)%MemberID))//' requested for output is not in the list of Members. ')) return IF ( Echo ) THEN WRITE( UnEc, '(A)' ) TRIM(Line) @@ -1046,14 +1275,20 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) ALLOCATE(Init%SSOutList(MaxOutChs), 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 ReadOutputList ( UnIn, SDInputFile, Init%SSOutList, p%NumOuts, 'SSOutList', 'List of outputs requested', ErrStat2, ErrMsg2, UnEc ); if(Failed()) return CALL CleanUp() CONTAINS + subroutine LegacyWarning(Message) + character(len=*), intent(in) :: Message + call WrScr('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') + call WrScr('Warning: the SubDyn input file is not at the latest format!' ) + call WrScr(' Visit: https://openfast.readthedocs.io/en/dev/source/user/api_change.html') + call WrScr('> Issue: '//trim(Message)) + call WrScr('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') + end subroutine LegacyWarning + LOGICAL FUNCTION Check(Condition, ErrMsg_in) logical, intent(in) :: Condition character(len=*), intent(in) :: ErrMsg_in @@ -1075,11 +1310,105 @@ END SUBROUTINE Fatal SUBROUTINE CleanUp() CLOSE( UnIn ) + if(allocated(StrArray)) deallocate(StrArray) IF (Echo) CLOSE( UnEc ) END SUBROUTINE - END SUBROUTINE SD_Input +!> Extract integers from a string (space delimited substrings) +!! If StrArrayOut is present, non numeric strings are also returned +!! Example Str="1 2 not_a_int 3" -> IntArray = (/1,2,3/) StrArrayOut=(/"not_a_int"/) +!! No need for error handling, the caller will check how many valid inputs were on the line +!! TODO, place me in NWTC LIb +SUBROUTINE ReadIAryFromStr(Str, IntArray, nColMax, nColValid, nColNumeric, StrArrayOut) + character(len=*), intent(in) :: Str !< + integer(IntKi), dimension(:), intent(inout) :: IntArray !< NOTE: inout, to allow for init values + integer(IntKi), intent(in) :: nColMax + integer(IntKi), intent(out) :: nColValid, nColNumeric !< + character(len=*), dimension(:), intent(out), optional :: StrArrayOut(:) !< Array of strings that are non numeric + character(255), allocatable :: StrArray(:) ! Array of strings extracted from line + real(ReKi) :: DummyFloat + integer(IntKi) :: J, nColStr + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + nColValid = 0 ; + nColNumeric = 0 ; + nColStr = 0 ; + ! --- First extract the different sub strings + CALL AllocAry(StrArray, nColMax, 'StrArray', ErrStat2, ErrMsg2); + if (ErrStat2/=ErrID_None) then + return ! User should notice that there is 0 valid columns + endif + StrArray(:)=''; + CALL ReadCAryFromStr(Str, StrArray, nColMax, 'StrArray', 'StrArray', ErrStat2, ErrMsg2)! NOTE:No Error handling! + ! --- Then look for numerical values + do J = 1, nColMax + if (len(trim(StrArray(J)))>0) then + nColValid=nColValid+1 + if (is_numeric(StrArray(J), DummyFloat) ) then !< TODO we should check for int here! + nColNumeric=nColNumeric+1 + if (nColNumeric<=size(IntArray)) then + IntArray(nColNumeric) = int(DummyFloat) + endif + else + nColStr = nColStr+1 + if (present(StrArrayOut)) then + if (nColStr <=size(StrArrayOut) )then + StrArrayOut(nColStr) = StrArray(J) + endif + endif + endif + endif + enddo + if(allocated(StrArray)) deallocate(StrArray) +END SUBROUTINE ReadIAryFromStr + +!> See ReadIAryFromStr, same but for floats +SUBROUTINE ReadFAryFromStr(Str, FloatArray, nColMax, nColValid, nColNumeric, StrArrayOut) + character(len=*), intent(in) :: Str !< + real(ReKi), dimension(:), intent(inout) :: FloatArray !< NOTE: inout, to allow for init values + integer(IntKi), intent(in) :: nColMax + integer(IntKi), intent(out) :: nColValid, nColNumeric !< + character(len=*), dimension(:), intent(out), optional :: StrArrayOut(:) !< Array of strings that are non numeric + character(255), allocatable :: StrArray(:) ! Array of strings extracted from line + real(ReKi) :: DummyFloat + integer(IntKi) :: J, nColStr + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + nColValid = 0 ; + nColNumeric = 0 ; + nColStr = 0 ; + ! --- First extract the different sub strings + CALL AllocAry(StrArray, nColMax, 'StrArray', ErrStat2, ErrMsg2); + if (ErrStat2/=ErrID_None) then + return ! User should notice that there is 0 valid columns + endif + StrArray(:)=''; + CALL ReadCAryFromStr(Str, StrArray, nColMax, 'StrArray', 'StrArray', ErrStat2, ErrMsg2)! NOTE:No Error handling! + ! --- Then look for numerical values + do J = 1, nColMax + if (len(trim(StrArray(J)))>0) then + nColValid=nColValid+1 + if (is_numeric(StrArray(J), DummyFloat) ) then !< TODO we should check for int here! + nColNumeric=nColNumeric+1 + if (nColNumeric<=size(FloatArray)) then + FloatArray(nColNumeric) = DummyFloat + endif + else + nColStr = nColStr+1 + if (present(StrArrayOut)) then + if (nColStr <=size(StrArrayOut) )then + StrArrayOut(nColStr) = StrArray(J) + endif + endif + endif + endif + enddo + if(allocated(StrArray)) deallocate(StrArray) +END SUBROUTINE ReadFAryFromStr + + + !---------------------------------------------------------------------------------------------------------------------------------- !> Rotate the joint coordinates with respect to global z @@ -1356,8 +1685,6 @@ SUBROUTINE SD_RK4( t, n, u, utimes, p, x, xd, z, OtherState, m, ErrStat, ErrMsg SUBROUTINE CleanUp() INTEGER(IntKi) :: ErrStat3 ! The error identifier (ErrStat) CHARACTER(ErrMsgLen) :: ErrMsg3 ! The error message (ErrMsg) - - CALL SD_DestroyContState( xdot, ErrStat3, ErrMsg3 ) CALL SD_DestroyContState( k1, ErrStat3, ErrMsg3 ) CALL SD_DestroyContState( k2, ErrStat3, ErrMsg3 ) @@ -1386,6 +1713,7 @@ END SUBROUTINE SD_RK4 !! Thus x_n+1 = x_n - J^-1 *dt/2 * (2*A*x_n + B *(u_n + u_n+1) +2*Fx) !! or J*( x_n - x_n+1 ) = dt * ( A*x_n + B *(u_n + u_n+1)/2 + Fx) SUBROUTINE SD_AM2( t, n, u, utimes, p, x, xd, z, OtherState, m, ErrStat, ErrMsg ) + USE NWTC_LAPACK, only: LAPACK_getrs REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds INTEGER(IntKi), INTENT(IN ) :: n !< time step number TYPE(SD_InputType), INTENT(INOUT) :: u(:) !< Inputs at t @@ -1400,9 +1728,9 @@ SUBROUTINE SD_AM2( t, n, u, utimes, p, x, xd, z, OtherState, m, ErrStat, ErrMsg CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None ! local variables TYPE(SD_InputType) :: u_interp ! interpolated value of inputs - REAL(ReKi) :: junk2(2*p%qml) !temporary states (qm and qmdot only) + REAL(ReKi) :: xq(2*p%nDOFM) !temporary states (qm and qmdot only) REAL(ReKi) :: udotdot_TP2(6) ! temporary copy of udotdot_TP - REAL(ReKi) :: UFL2(p%DOFL) ! temporary copy of UFL + REAL(ReKi) :: F_L2(p%nDOF__L) ! temporary copy of F_L INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 @@ -1415,180 +1743,550 @@ SUBROUTINE SD_AM2( t, n, u, utimes, p, x, xd, z, OtherState, m, ErrStat, ErrMsg !Start by getting u_n and u_n+1 ! interpolate u to find u_interp = u(t) = u_n CALL SD_Input_ExtrapInterp( u, utimes, u_interp, t, ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SD_AM2') + CALL GetExtForceOnInternalDOF(u_interp, p, x, m, m%F_L, ErrStat2, ErrMsg2, GuyanLoadCorrection=(p%GuyanLoadCorrection.and..not.p%Floating), RotateLoads=(p%GuyanLoadCorrection.and.p%Floating)) m%udotdot_TP = (/u_interp%TPMesh%TranslationAcc(:,1), u_interp%TPMesh%RotationAcc(:,1)/) - CALL ConstructUFL( u_interp, p, m%UFL ) + if (p%GuyanLoadCorrection.and.p%Floating) then + ! >>> Rotate All - udotdot_TP to body coordinates + m%udotdot_TP(1:3) = matmul(u_interp%TPMesh%Orientation(:,:,1), m%udotdot_TP(1:3)) + m%udotdot_TP(4:6) = matmul(u_interp%TPMesh%Orientation(:,:,1), m%udotdot_TP(4:6)) + endif ! extrapolate u to find u_interp = u(t + dt)=u_n+1 CALL SD_Input_ExtrapInterp(u, utimes, u_interp, t+p%SDDeltaT, ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SD_AM2') + CALL GetExtForceOnInternalDOF(u_interp, p, x, m, F_L2, ErrStat2, ErrMsg2, GuyanLoadCorrection=(p%GuyanLoadCorrection.and..not.p%Floating), RotateLoads=(p%GuyanLoadCorrection.and.p%Floating)) udotdot_TP2 = (/u_interp%TPMesh%TranslationAcc(:,1), u_interp%TPMesh%RotationAcc(:,1)/) - CALL ConstructUFL( u_interp, p, UFL2 ) + if (p%GuyanLoadCorrection.and.p%Floating) then + ! >>> Rotate All - udotdot_TP to body coordinates + udotdot_TP2(1:3) = matmul(u_interp%TPMesh%Orientation(:,:,1), udotdot_TP2(1:3)) + udotdot_TP2(4:6) = matmul(u_interp%TPMesh%Orientation(:,:,1), udotdot_TP2(4:6)) + endif ! calculate (u_n + u_n+1)/2 udotdot_TP2 = 0.5_ReKi * ( udotdot_TP2 + m%udotdot_TP ) - UFL2 = 0.5_ReKi * ( UFL2 + m%UFL ) + F_L2 = 0.5_ReKi * ( F_L2 + m%F_L ) - ! set junk2 = dt * ( A*x_n + B *(u_n + u_n+1)/2 + Fx) - junk2( 1: p%qml)=p%SDDeltaT * x%qmdot !upper portion of array - junk2(1+p%qml:2*p%qml)=p%SDDeltaT * (p%NOmegaM2*x%qm + p%N2OmegaMJDamp*x%qmdot - matmul(p%MMB, udotdot_TP2) + matmul(UFL2,p%PhiM ) + p%FX) !lower portion of array - ! note: matmul(UFL2,p%PhiM ) = matmul(p%PhiM_T,UFL2) because UFL2 is 1-D + ! set xq = dt * ( A*x_n + B *(u_n + u_n+1)/2 + Fx) + xq( 1: p%nDOFM)=p%SDDeltaT * x%qmdot !upper portion of array + xq(1+p%nDOFM:2*p%nDOFM)=p%SDDeltaT * (-p%KMMDiag*x%qm - p%CMMDiag*x%qmdot - matmul(p%MMB, udotdot_TP2) + matmul(F_L2,p%PhiM )) !lower portion of array + ! note: matmul(F_L2,p%PhiM ) = matmul(p%PhiM_T,F_L2) because F_L2 is 1-D !.................................................... - ! Solve for junk2: (equivalent to junk2= matmul(p%AM2InvJac,junk2) + ! Solve for xq: (equivalent to xq= matmul(p%AM2InvJac,xq) ! J*( x_n - x_n+1 ) = dt * ( A*x_n + B *(u_n + u_n+1)/2 + Fx) !.................................................... - CALL LAPACK_getrs( TRANS='N',N=SIZE(p%AM2Jac,1),A=p%AM2Jac,IPIV=p%AM2JacPiv, B=junk2, ErrStat=ErrStat2, ErrMsg=ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SD_AM2') - !IF ( ErrStat >= AbortErrLev ) RETURN + CALL LAPACK_getrs( TRANS='N',N=SIZE(p%AM2Jac,1),A=p%AM2Jac,IPIV=p%AM2JacPiv, B=xq, ErrStat=ErrStat2, ErrMsg=ErrMsg2); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'SD_AM2') - ! after the LAPACK solve, junk2 = ( x_n - x_n+1 ); so now we can solve for x_n+1: - x%qm = x%qm - junk2( 1: p%qml) - x%qmdot = x%qmdot - junk2(p%qml+1:2*p%qml) + ! after the LAPACK solve, xq = ( x_n - x_n+1 ); so now we can solve for x_n+1: + x%qm = x%qm - xq( 1: p%nDOFM) + x%qmdot = x%qmdot - xq(p%nDOFM+1:2*p%nDOFM) ! clean up temporary variable(s) CALL SD_DestroyInput( u_interp, ErrStat, ErrMsg ) END SUBROUTINE SD_AM2 +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +! ###### The following four routines are Jacobian routines for linearization capabilities ####### +! If the module does not implement them, set ErrStat = ErrID_Fatal in SD_Init() when InitInp%Linearize is .true. +!---------------------------------------------------------------------------------------------------------------------------------- +!> Routine to compute the Jacobians of the output (Y), continuous- (X), discrete- (Xd), and constraint-state (Z) functions +!! with respect to the inputs (u). The partial derivatives dY/du, dX/du, dXd/du, and DZ/du are returned. +SUBROUTINE SD_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, dYdu, dXdu, dXddu, dZdu) + REAL(DbKi), INTENT(IN ) :: t !< Time in seconds at operating point + TYPE(SD_InputType), INTENT(INOUT) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) + TYPE(SD_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(SD_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point + TYPE(SD_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point + TYPE(SD_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point + TYPE(SD_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point + TYPE(SD_OutputType), INTENT(INOUT) :: y !< Output (change to inout if a mesh copy is required); Output fields are not used by this routine, but type is available here so that mesh parameter information (i.e., connectivity) does not have to be recalculated for dYdu. + TYPE(SD_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dYdu(:,:) !< Partial derivatives of output functions (Y) wrt the inputs (u) [intent in to avoid deallocation] + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXdu(:,:) !< Partial derivatives of continuous state functions (X) wrt the inputs (u) [intent in to avoid deallocation] + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXddu(:,:) !< Partial derivatives of discrete state functions (Xd) wrt the inputs (u) [intent in to avoid deallocation] + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dZdu(:,:) !< Partial derivatives of constraint state functions (Z) wrt the inputs (u) [intent in to avoid deallocation] + ! local variables + TYPE(SD_OutputType) :: y_m, y_p + TYPE(SD_ContinuousStateType) :: x_m, x_p + TYPE(SD_InputType) :: u_perturb + REAL(R8Ki) :: delta_p, delta_m ! delta change in input (plus, minus) + INTEGER(IntKi) :: i + integer(intKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + character(*), parameter :: RoutineName = 'SD_JacobianPInput' + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = '' + ! get OP values here: + call SD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat2, ErrMsg2 ); if(Failed()) return + ! make a copy of the inputs to perturb + call SD_CopyInput( u, u_perturb, MESH_NEWCOPY, ErrStat2, ErrMsg2); if(Failed()) return + IF ( PRESENT( dYdu ) ) THEN + ! Calculate the partial derivative of the output functions (Y) with respect to the inputs (u) here: + if (.not. allocated(dYdu) ) then + call AllocAry(dYdu,p%Jac_ny, size(p%Jac_u_indx,1),'dYdu', ErrStat2, ErrMsg2); if(Failed()) return + end if + ! make a copy of outputs because we will need two for the central difference computations (with orientations) + call SD_CopyOutput( y, y_p, MESH_NEWCOPY, ErrStat2, ErrMsg2); if(Failed()) return + call SD_CopyOutput( y, y_m, MESH_NEWCOPY, ErrStat2, ErrMsg2); if(Failed()) return + do i=1,size(p%Jac_u_indx,1) + ! get u_op + delta_p u + call SD_CopyInput( u, u_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call SD_Perturb_u( p, i, 1, u_perturb, delta_p ) + ! compute y at u_op + delta_p u + call SD_CalcOutput( t, u_perturb, p, x, xd, z, OtherState, y_p, m, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + ! get u_op - delta_m u + call SD_CopyInput( u, u_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call SD_Perturb_u( p, i, -1, u_perturb, delta_m ) + ! compute y at u_op - delta_m u + call SD_CalcOutput( t, u_perturb, p, x, xd, z, OtherState, y_m, m, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + ! get central difference: + call SD_Compute_dY( p, y_p, y_m, delta_p, dYdu(:,i) ) + end do + if(Failed()) return + END IF + IF ( PRESENT( dXdu ) ) THEN + ! Calculate the partial derivative of the continuous state functions (X) with respect to the inputs (u) here: + ! TODO: dXdu should be constant, in theory we dont' need to recompute it + !if(ANALYTICAL_LIN) then + ! Analytical lin cannot be used anymore with extra mom + ! call StateMatrices(p, ErrStat2, ErrMsg2, BB=dXdu); if(Failed()) return ! Allocation occurs in function + !else + if (.not. allocated(dXdu)) then + call AllocAry(dXdu, p%Jac_nx * 2, size(p%Jac_u_indx,1), 'dXdu', ErrStat2, ErrMsg2); if (Failed()) return + endif + do i=1,size(p%Jac_u_indx,1) + ! get u_op + delta u + call SD_CopyInput( u, u_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call SD_Perturb_u( p, i, 1, u_perturb, delta_p ) + ! compute x at u_op + delta u + call SD_CalcContStateDeriv( t, u_perturb, p, x, xd, z, OtherState, m, x_p, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + ! get u_op - delta u + call SD_CopyInput( u, u_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call SD_Perturb_u( p, i, -1, u_perturb, delta_m ) + ! compute x at u_op - delta u + call SD_CalcContStateDeriv( t, u_perturb, p, x, xd, z, OtherState, m, x_m, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + ! get central difference: + ! we may have had an error allocating memory, so we'll check + if(Failed()) return + ! get central difference: + call SD_Compute_dX( p, x_p, x_m, delta_p, dXdu(:,i) ) + end do + !endif ! analytical or numerical + END IF ! dXdu + IF ( PRESENT( dXddu ) ) THEN + if (allocated(dXddu)) deallocate(dXddu) + END IF + IF ( PRESENT( dZdu ) ) THEN + if (allocated(dZdu)) deallocate(dZdu) + END IF + call CleanUp() +contains + + logical function Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + Failed = ErrStat >= AbortErrLev + if (Failed) call CleanUp() + end function Failed + + subroutine CleanUp() + call SD_DestroyContState( x_p, ErrStat2, ErrMsg2 ) ! we don't need this any more + call SD_DestroyContState( x_m, ErrStat2, ErrMsg2 ) ! we don't need this any more + call SD_DestroyOutput( y_p, ErrStat2, ErrMsg2 ) + call SD_DestroyOutput( y_m, ErrStat2, ErrMsg2 ) + call SD_DestroyInput(u_perturb, ErrStat2, ErrMsg2 ) + end subroutine cleanup + +END SUBROUTINE SD_JacobianPInput +!---------------------------------------------------------------------------------------------------------------------------------- +!> Routine to compute the Jacobians of the output (Y), continuous- (X), discrete- (Xd), and constraint-state (Z) functions +!! with respect to the continuous states (x). The partial derivatives dY/dx, dX/dx, dXd/dx, and dZ/dx are returned. +SUBROUTINE SD_JacobianPContState( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, dYdx, dXdx, dXddx, dZdx) + REAL(DbKi), INTENT(IN ) :: t !< Time in seconds at operating point + TYPE(SD_InputType), INTENT(INOUT) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) + TYPE(SD_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(SD_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point + TYPE(SD_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point + TYPE(SD_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point + TYPE(SD_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point + TYPE(SD_OutputType), INTENT(INOUT) :: y !< Output (change to inout if a mesh copy is required); Output fields are not used by this routine, but type is available here so that mesh parameter information (i.e., connectivity) does not have to be recalculated for dYdx. + TYPE(SD_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dYdx(:,:) !< Partial derivatives of output functions wrt the continuous states (x) [intent in to avoid deallocation] + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXdx(:,:) !< Partial derivatives of continuous state functions (X) wrt the continuous states (x) [intent in to avoid deallocation] + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXddx(:,:) !< Partial derivatives of discrete state functions (Xd) wrt the continuous states (x) [intent in to avoid deallocation] + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dZdx(:,:) !< Partial derivatives of constraint state functions (Z) wrt the continuous states (x) [intent in to avoid deallocation] + ! local variables + TYPE(SD_OutputType) :: y_p, y_m + TYPE(SD_ContinuousStateType) :: x_p, x_m + TYPE(SD_ContinuousStateType) :: x_perturb + REAL(R8Ki) :: delta ! delta change in input or state + INTEGER(IntKi) :: i, k + INTEGER(IntKi) :: idx + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_JacobianPContState' + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = '' + ! make a copy of the continuous states to perturb NOTE: MESH_NEWCOPY + call SD_CopyContState( x, x_perturb, MESH_NEWCOPY, ErrStat2, ErrMsg2); if(Failed()) return + IF ( PRESENT( dYdx ) ) THEN + ! Calculate the partial derivative of the output functions (Y) with respect to the continuous states (x) here: + if (.not. allocated(dYdx)) then + call AllocAry(dYdx, p%Jac_ny, p%Jac_nx*2, 'dYdx', ErrStat2, ErrMsg2); if(Failed()) return + end if + ! make a copy of outputs because we will need two for the central difference computations (with orientations) + call SD_CopyOutput( y, y_p, MESH_NEWCOPY, ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call SD_CopyOutput( y, y_m, MESH_NEWCOPY, ErrStat2, ErrMsg2); if(Failed()) return + idx = 1 + do k=1,2 ! 1=disp, 2=veloc + do i=1,p%Jac_nx ! CB mode + ! get x_op + delta x + call SD_CopyContState( x, x_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call SD_perturb_x(p, k, i, 1, x_perturb, delta ) + ! compute y at x_op + delta x + call SD_CalcOutput( t, u, p, x_perturb, xd, z, OtherState, y_p, m, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + ! get x_op - delta x + call SD_CopyContState( x, x_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call SD_perturb_x(p, k, i, -1, x_perturb, delta ) + ! compute y at x_op - delta x + call SD_CalcOutput( t, u, p, x_perturb, xd, z, OtherState, y_m, m, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + ! get central difference: + call SD_Compute_dY( p, y_p, y_m, delta, dYdx(:,idx) ) + idx = idx+1 + end do + end do + if(Failed()) return + END IF + IF ( PRESENT( dXdx ) ) THEN + ! Calculate the partial derivative of the continuous state functions (X) with respect to the continuous states (x) here: + ! TODO: dXdx should be constant, in theory we don't need to recompute it + if(ANALYTICAL_LIN) then + call StateMatrices(p, ErrStat2, ErrMsg2, AA=dXdx); if(Failed()) return ! Allocation occurs in function + else + if (.not. allocated(dXdx)) then + call AllocAry(dXdx, p%Jac_nx * 2, p%Jac_nx * 2, 'dXdx', ErrStat2, ErrMsg2); if(Failed()) return + end if + idx = 1 ! counter into dXdx + do k=1,2 ! 1=positions (x_perturb%q); 2=velocities (x_perturb%dqdt) + do i=1,p%Jac_nx + ! get x_op + delta x + call SD_CopyContState( x, x_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call SD_perturb_x(p, k, i, 1, x_perturb, delta ) + ! compute x at x_op + delta x + call SD_CalcContStateDeriv( t, u, p, x_perturb, xd, z, OtherState, m, x_p, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + ! get x_op - delta x + call SD_CopyContState( x, x_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call SD_perturb_x(p, k, i, -1, x_perturb, delta ) + ! compute x at x_op - delta x + call SD_CalcContStateDeriv( t, u, p, x_perturb, xd, z, OtherState, m, x_m, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + if(Failed()) return + ! get central difference: + call SD_Compute_dX( p, x_p, x_m, delta, dXdx(:,idx) ) + idx = idx+1 + end do + end do + endif ! analytical or numerical + END IF + IF ( PRESENT( dXddx ) ) THEN + if (allocated(dXddx)) deallocate(dXddx) + END IF + IF ( PRESENT( dZdx ) ) THEN + if (allocated(dZdx)) deallocate(dZdx) + END IF + call CleanUp() + +contains + + logical function Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SD_JacobianPContState') + Failed = ErrStat >= AbortErrLev + if (Failed) call CleanUp() + end function Failed + + subroutine CleanUp() + call SD_DestroyOutput( y_p, ErrStat2, ErrMsg2 ) + call SD_DestroyOutput( y_m, ErrStat2, ErrMsg2 ) + call SD_DestroyContState( x_p, ErrStat2, ErrMsg2 ) + call SD_DestroyContState( x_m, ErrStat2, ErrMsg2 ) + call SD_DestroyContState(x_perturb, ErrStat2, ErrMsg2 ) + end subroutine cleanup + +END SUBROUTINE SD_JacobianPContState + +!---------------------------------------------------------------------------------------------------------------------------------- +!> Routine to compute the Jacobians of the output (Y), continuous- (X), discrete- (Xd), and constraint-state (Z) functions +!! with respect to the discrete states (xd). The partial derivatives dY/dxd, dX/dxd, dXd/dxd, and DZ/dxd are returned. +SUBROUTINE SD_JacobianPDiscState( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, dYdxd, dXdxd, dXddxd, dZdxd ) + REAL(DbKi), INTENT(IN ) :: t !< Time in seconds at operating point + TYPE(SD_InputType), INTENT(INOUT) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) + TYPE(SD_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(SD_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point + TYPE(SD_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point + TYPE(SD_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point + TYPE(SD_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point + TYPE(SD_OutputType), INTENT(INOUT) :: y !< Output (change to inout if a mesh copy is required); Output fields are not used by this routine, but type is available here so that mesh parameter information (i.e., connectivity) does not have to be recalculated for dYdx. + TYPE(SD_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dYdxd(:,:) !< Partial derivatives of output functions (Y) wrt the discrete states (xd) [intent in to avoid deallocation] + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXdxd(:,:) !< Partial derivatives of continuous state functions (X) wrt the discrete states (xd) [intent in to avoid deallocation] + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXddxd(:,:)!< Partial derivatives of discrete state functions (Xd) wrt the discrete states (xd) [intent in to avoid deallocation] + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dZdxd(:,:) !< Partial derivatives of constraint state functions (Z) wrt discrete states (xd) [intent in to avoid deallocation] + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = '' + IF ( PRESENT( dYdxd ) ) THEN + END IF + IF ( PRESENT( dXdxd ) ) THEN + END IF + IF ( PRESENT( dXddxd ) ) THEN + END IF + IF ( PRESENT( dZdxd ) ) THEN + END IF +END SUBROUTINE SD_JacobianPDiscState +!---------------------------------------------------------------------------------------------------------------------------------- +!> Routine to compute the Jacobians of the output (Y), continuous- (X), discrete- (Xd), and constraint-state (Z) functions +!! with respect to the constraint states (z). The partial derivatives dY/dz, dX/dz, dXd/dz, and DZ/dz are returned. +SUBROUTINE SD_JacobianPConstrState( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, dYdz, dXdz, dXddz, dZdz ) + REAL(DbKi), INTENT(IN ) :: t !< Time in seconds at operating point + TYPE(SD_InputType), INTENT(INOUT) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) + TYPE(SD_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(SD_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point + TYPE(SD_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point + TYPE(SD_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point + TYPE(SD_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point + TYPE(SD_OutputType), INTENT(INOUT) :: y !< Output (change to inout if a mesh copy is required); Output fields are not used by this routine, but type is available here so that mesh parameter information (i.e., connectivity) does not have to be recalculated for dYdx. + TYPE(SD_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dYdz(:,:) !< Partial derivatives of output functions (Y) with respect to the constraint states (z) [intent in to avoid deallocation] + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXdz(:,:) !< Partial derivatives of continuous state functions (X) with respect to the constraint states (z) [intent in to avoid deallocation] + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXddz(:,:) !< Partial derivatives of discrete state functions (Xd) with respect to the constraint states (z) [intent in to avoid deallocation] + REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dZdz(:,:) !< Partial derivatives of constraint state functions (Z) with respect to the constraint states (z) [intent in to avoid deallocation] + ! local variables + character(*), parameter :: RoutineName = 'SD_JacobianPConstrState' + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = '' + IF ( PRESENT( dYdz ) ) THEN + END IF + IF ( PRESENT( dXdz ) ) THEN + if (allocated(dXdz)) deallocate(dXdz) + END IF + IF ( PRESENT( dXddz ) ) THEN + if (allocated(dXddz)) deallocate(dXddz) + END IF + IF ( PRESENT(dZdz) ) THEN + END IF +END SUBROUTINE SD_JacobianPConstrState +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +!> Routine to pack the data structures representing the operating points into arrays for linearization. +SUBROUTINE SD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, y_op, x_op, dx_op, xd_op, z_op ) + REAL(DbKi), INTENT(IN ) :: t !< Time in seconds at operating point + TYPE(SD_InputType), INTENT(INOUT) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) + TYPE(SD_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(SD_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point + TYPE(SD_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point + TYPE(SD_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point + TYPE(SD_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point + TYPE(SD_OutputType), INTENT(IN ) :: y !< Output at operating point + TYPE(SD_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + REAL(ReKi), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: u_op(:) !< values of linearized inputs + REAL(ReKi), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: y_op(:) !< values of linearized outputs + REAL(ReKi), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: x_op(:) !< values of linearized continuous states + REAL(ReKi), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dx_op(:) !< values of first time derivatives of linearized continuous states + REAL(ReKi), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: xd_op(:) !< values of linearized discrete states + REAL(ReKi), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: z_op(:) !< values of linearized constraint states + ! Local + INTEGER(IntKi) :: idx, i + INTEGER(IntKi) :: nu + INTEGER(IntKi) :: ny + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_GetOP' + LOGICAL :: FieldMask(FIELDMASK_SIZE) + TYPE(SD_ContinuousStateType) :: dx ! derivative of continuous states at operating point + ErrStat = ErrID_None + ErrMsg = '' + IF ( PRESENT( u_op ) ) THEN + nu = size(p%Jac_u_indx,1) + u%TPMesh%NNodes * 6 ! Jac_u_indx has 3 orientation angles, but the OP needs the full 9 elements of the DCM (thus 6 more per node) + if (.not. allocated(u_op)) then + call AllocAry(u_op, nu, 'u_op', ErrStat2, ErrMsg2); if(Failed()) return + end if + idx = 1 + FieldMask = .false. + FieldMask(MASKID_TranslationDisp) = .true. + FieldMask(MASKID_Orientation) = .true. + FieldMask(MASKID_TranslationVel) = .true. + FieldMask(MASKID_RotationVel) = .true. + FieldMask(MASKID_TranslationAcc) = .true. + FieldMask(MASKID_RotationAcc) = .true. + call PackMotionMesh(u%TPMesh, u_op, idx, FieldMask=FieldMask) + call PackLoadMesh(u%LMesh, u_op, idx) + END IF + IF ( PRESENT( y_op ) ) THEN + ny = p%Jac_ny + y%Y2Mesh%NNodes * 6 ! Jac_ny has 3 orientation angles, but the OP needs the full 9 elements of the DCM (thus 6 more per node) + if (.not. allocated(y_op)) then + call AllocAry(y_op, ny, 'y_op', ErrStat2, ErrMsg2); if(Failed()) return + end if + idx = 1 + call PackLoadMesh(y%Y1Mesh, y_op, idx) + FieldMask = .false. + FieldMask(MASKID_TranslationDisp) = .true. + FieldMask(MASKID_Orientation) = .true. + FieldMask(MASKID_TranslationVel) = .true. + FieldMask(MASKID_RotationVel) = .true. + FieldMask(MASKID_TranslationAcc) = .true. + FieldMask(MASKID_RotationAcc) = .true. + call PackMotionMesh(y%Y2Mesh, y_op, idx, FieldMask=FieldMask) + idx = idx - 1 + do i=1,p%NumOuts + y_op(i+idx) = y%WriteOutput(i) + end do + END IF + IF ( PRESENT( x_op ) ) THEN + if (.not. allocated(x_op)) then + call AllocAry(x_op, p%Jac_nx*2,'x_op',ErrStat2,ErrMsg2); if (Failed()) return + end if + do i=1, p%Jac_nx + x_op(i) = x%qm(i) + end do + do i=1, p%Jac_nx + x_op(i+p%nDOFM) = x%qmdot(i) + end do + END IF + IF ( PRESENT( dx_op ) ) THEN + if (.not. allocated(dx_op)) then + call AllocAry(dx_op, p%Jac_nx * 2,'dx_op',ErrStat2,ErrMsg2); if(failed()) return + end if + call SD_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dx, ErrStat2, ErrMsg2 ) ; if(Failed()) return + idx = 1 + do i=1, p%Jac_nx + dx_op(i) = dx%qm(i) + end do + do i=1, p%Jac_nx + dx_op(i+p%nDOFM) = dx%qmdot(i) + end do + END IF + IF ( PRESENT( xd_op ) ) THEN + ! pass + END IF + IF ( PRESENT( z_op ) ) THEN + ! pass + END IF + call CleanUp() +contains + logical function Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') + Failed = ErrStat >= AbortErrLev + if (Failed) call CleanUp() + end function Failed + + subroutine CleanUp() + call SD_DestroyContState(dx, ErrStat2, ErrMsg2); + end subroutine +END SUBROUTINE SD_GetOP +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ !------------------------------------------------------------------------------------------------------ -!> Perform Craig Bampton reduction -SUBROUTINE Craig_Bampton(Init, p, CBparams, ErrStat, ErrMsg) +!> Perform Craig Bampton (CB) reduction and set parameters needed for States and Ouputs equations +!! Sets the following values, as documented in the SubDyn Theory Guide: +!! CB%OmegaL (omega) and CB%PhiL from Eq. 2 +!! p%PhiL_T and p%PhiLInvOmgL2 for static improvement +!! CB%PhiR from Eq. 3 +!! CB%MBB, CB%MBM, and CB%KBB from Eq. 4. +SUBROUTINE SD_Craig_Bampton(Init, p, CB, ErrStat, ErrMsg) TYPE(SD_InitType), INTENT(INOUT) :: Init ! Input data for initialization routine - TYPE(SD_ParameterType),INTENT(INOUT) :: p ! Parameters - TYPE(CB_MatArrays), INTENT(INOUT) :: CBparams ! CB parameters that will be passed out for summary file use + TYPE(SD_ParameterType),INTENT(INOUT),target::p ! Parameters + TYPE(CB_MatArrays), INTENT(INOUT) :: CB ! CB parameters that will be passed out for summary file use INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None ! local variables - REAL(ReKi), ALLOCATABLE :: MRR(:, :) - REAL(ReKi), ALLOCATABLE :: MLL(:, :) - REAL(ReKi), ALLOCATABLE :: MRL(:, :) - REAL(ReKi), ALLOCATABLE :: KRR(:, :) - REAL(ReKi), ALLOCATABLE :: KLL(:, :) - REAL(ReKi), ALLOCATABLE :: KRL(:, :) - REAL(ReKi), ALLOCATABLE :: FGR(:) - REAL(ReKi), ALLOCATABLE :: FGL(:) - REAL(ReKi), ALLOCATABLE :: MBBb(:, :) - REAL(ReKi), ALLOCATABLE :: MBMb(:, :) - REAL(ReKi), ALLOCATABLE :: KBBb(:, :) - REAL(ReKi), ALLOCATABLE :: PhiRb(:, :) - REAL(ReKi), ALLOCATABLE :: FGRb(:) + REAL(FEKi), ALLOCATABLE :: PhiRb(:, :) ! Purely to avoid loosing these modes for output ! TODO, kept for backward compatibility of Summary file REAL(ReKi) :: JDamping1 ! temporary storage for first element of JDamping array + INTEGER(IntKi) :: nR !< Dimension of R DOFs (to switch between __R and R__) + INTEGER(IntKi) :: nL, nM, nM_out + INTEGER(IntKi), pointer :: IDR(:) !< Alias to switch between IDR__ and ID__Rb INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - + character(*), parameter :: RoutineName = 'SD_Craig_Bampton' ErrStat = ErrID_None ErrMsg = "" - ! number of nodes: - p%NNodes_I = Init%NInterf ! Number of interface nodes - p%NNodes_L = Init%NNode - p%NReact - p%NNodes_I ! Number of Interior nodes =(TDOF-DOFC-DOFI)/6 = (6*Init%NNode - (p%NReact+p%NNodes_I)*6 ) / 6 = Init%NNode - p%NReact -p%NNodes_I - - !DOFS of interface - !BJJ: TODO: are these 6's actually TPdofL? - p%DOFI = p%NNodes_I*6 - p%DOFC = p%NReact*6 - p%DOFR = (p%NReact+p%NNodes_I)*6 ! = p%DOFC + p%DOFI - p%DOFL = p%NNodes_L*6 ! = Init%TDOF - p%DOFR - - IF(Init%CBMod) THEN ! C-B reduction ! check number of internal modes - IF(p%Nmodes > p%DOFL) THEN - CALL SetErrStat(ErrID_Fatal,'Number of internal modes is larger than maximum. ',ErrStat,ErrMsg,'Craig_Bampton') - CALL CleanupCB() - RETURN + IF(p%nDOFM > p%nDOFL_L) THEN + CALL Fatal('Number of internal modes is larger than number of internal DOFs.') + return ENDIF - ELSE ! full FEM - p%Nmodes = p%DOFL - !Jdampings need to be reallocated here because DOFL not known during Init + p%nDOFM = p%nDOFL_L + !Jdampings need to be reallocated here because nDOFL not known during Init !So assign value to one temporary variable JDamping1=Init%Jdampings(1) DEALLOCATE(Init%JDampings) - CALL AllocAry( Init%JDampings, p%DOFL, 'Init%JDampings', ErrStat2, ErrMsg2 ) ; if(Failed()) return + CALL AllocAry( Init%JDampings, p%nDOFL_L, 'Init%JDampings', ErrStat2, ErrMsg2 ) ; if(Failed()) return Init%JDampings = JDamping1 ! set default values for all modes - ENDIF - - CBparams%DOFM = p%Nmodes ! retained modes (all if no C-B reduction) - - ! matrix dimension paramters - p%qmL = p%Nmodes ! Length of 1/2 x array, x1 that is (note, do this after check if CBMod is true [Nmodes modified if CMBod is false]) - p%URbarL = p%DOFI !=p%NNodes_I*6 ! Length of URbar array, subarray of Y2 : THIS MAY CHANGE IF SOME DOFS ARE NOT CONSTRAINED - - - CALL AllocParameters(p, CBparams%DOFM, ErrStat2, ErrMsg2); ; if (Failed()) return - - CALL AllocAry( MRR, p%DOFR, p%DOFR, 'matrix MRR', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') - CALL AllocAry( MLL, p%DOFL, p%DOFL, 'matrix MLL', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') - CALL AllocAry( MRL, p%DOFR, p%DOFL, 'matrix MRL', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') - CALL AllocAry( KRR, p%DOFR, p%DOFR, 'matrix KRR', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') - CALL AllocAry( KLL, p%DOFL, p%DOFL, 'matrix KLL', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') - CALL AllocAry( KRL, p%DOFR, p%DOFL, 'matrix KRL', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') - CALL AllocAry( FGL, p%DOFL, 'array FGL', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') - CALL AllocAry( FGR, p%DOFR, 'array FGR', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') - - CALL AllocAry( CBparams%MBB, p%DOFR, p%DOFR, 'CBparams%MBB', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') - CALL AllocAry( CBparams%MBM, p%DOFR, CBparams%DOFM,'CBparams%MBM', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') - CALL AllocAry( CBparams%KBB, p%DOFR, p%DOFR, 'CBparams%KBB', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') - CALL AllocAry( CBparams%PhiL, p%DOFL, p%DOFL, 'CBparams%PhiL', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') - CALL AllocAry( CBparams%PhiR, p%DOFL, p%DOFR, 'CBparams%PhiR', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') - CALL AllocAry( CBparams%OmegaL, p%DOFL, 'CBparams%OmegaL', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') - CALL AllocAry( CBparams%TI2, p%DOFR, 6, 'CBparams%TI2', ErrStat2, ErrMsg2 ); if(Failed()) return - - ! Set the index arrays p%IDI, p%IDR, p%IDL, p%IDC, and p%IDY. - CALL SetIndexArrays(Init, p, ErrStat2, ErrMsg2) ; if(Failed()) return - - ! Set MRR, MLL, MRL, KRR, KLL, KRL, FGR, FGL, based on - ! Init%M, Init%K, and Init%FG data and indices p%IDR and p%IDL: - CALL BreakSysMtrx(Init, p, MRR, MLL, MRL, KRR, KLL, KRL, FGR, FGL) - ! Set p%TI and CBparams%TI2 - CALL TrnsfTI(Init, p%TI, p%DOFI, p%IDI, CBparams%TI2, p%DOFR, p%IDR, ErrStat2, ErrMsg2); if(Failed()) return - - !................................ - ! Sets the following values, as documented in the SubDyn Theory Guide: - ! CBparams%OmegaL (omega) and CBparams%PhiL from Eq. 2 - ! p%PhiL_T and p%PhiLInvOmgL2 for static improvement - ! CBparams%PhiR from Eq. 3 - ! CBparams%MBB, CBparams%MBM, and CBparams%KBB from Eq. 4. - !................................ - CALL CBMatrix(MRR, MLL, MRL, KRR, KLL, KRL, CBparams%DOFM, Init, & ! < inputs - CBparams%MBB, CBparams%MBM, CBparams%KBB, CBparams%PhiL, CBparams%PhiR, CBparams%OmegaL, ErrStat2, ErrMsg2, p) ! <- outputs (p is also input ) + CALL AllocParameters(p, p%nDOFM, ErrStat2, ErrMsg2); ; if (Failed()) return + ! Switch between BC before or after CB, KEEP ME + if(BC_Before_CB) then + !print*,' > Boundary conditions will be applied before Craig-Bampton (New)' + nR = p%nDOF__Rb ! we remove the Fixed BC before performing the CB-reduction + IDR => p%ID__Rb + else + !print*,' > Craig-Bampton will be applied before boundary conditions (Legacy)' + nR = p%nDOFR__ ! Old way, applying CB on full unconstrained system + IDR => p%IDR__ + endif + + IF (p%SttcSolve/=idSIM_None) THEN ! STATIC TREATMENT IMPROVEMENT + nM_out=p%nDOF__L ! Selecting all CB modes for outputs to the function below + ELSE + nM_out=p%nDOFM ! Selecting only the requrested number of CB modes + ENDIF + nL = p%nDOF__L + nM = p%nDOFM + + CALL WrScr(' Performing Craig-Bampton reduction '//trim(Num2LStr(p%nDOF_red))//' DOFs -> '//trim(Num2LStr(p%nDOFM))//' modes + '//trim(Num2LStr(p%nDOF__Rb))//' DOFs') + CALL AllocAry( CB%MBB, nR, nR, 'CB%MBB', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry( CB%MBM, nR, nM, 'CB%MBM', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry( CB%KBB, nR, nR, 'CB%KBB', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry( CB%PhiL, nL, nM_out,'CB%PhiL', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry( CB%PhiR, nL, nR, 'CB%PhiR', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry( CB%OmegaL, nM_out, 'CB%OmegaL', ErrStat2, ErrMsg2 ); if(Failed()) return + + CALL CraigBamptonReduction(Init%M, Init%K, IDR, nR, p%ID__L, nL, nM, nM_out, CB%MBB, CB%MBM, CB%KBB, CB%PhiL, CB%PhiR, CB%OmegaL, ErrStat2, ErrMsg2) if(Failed()) return - - ! to use a little less space, let's deallocate these arrays that we don't need anymore, then allocate the next set of temporary arrays: - IF(ALLOCATED(MRR) ) DEALLOCATE(MRR) - IF(ALLOCATED(MLL) ) DEALLOCATE(MLL) - IF(ALLOCATED(MRL) ) DEALLOCATE(MRL) - IF(ALLOCATED(KRR) ) DEALLOCATE(KRR) - IF(ALLOCATED(KLL) ) DEALLOCATE(KLL) - IF(ALLOCATED(KRL) ) DEALLOCATE(KRL) - - ! "b" stands for "bar"; "t" stands for "tilde" - CALL AllocAry( MBBb, p%DOFI, p%DOFI, 'matrix MBBb', ErrStat2, ErrMsg2 ); if (Failed()) return - CALL AllocAry( MBmb, p%DOFI, CBparams%DOFM,'matrix MBmb', ErrStat2, ErrMsg2 ); if (Failed()) return - CALL AllocAry( KBBb, p%DOFI, p%DOFI, 'matrix KBBb', ErrStat2, ErrMsg2 ); if (Failed()) return - CALL AllocAry( PhiRb, p%DOFL, p%DOFI, 'matrix PhiRb', ErrStat2, ErrMsg2 ); if (Failed()) return - CALL AllocAry( FGRb, p%DOFI, 'array FGRb', ErrStat2, ErrMsg2 ); if (Failed()) return - - !................................ - ! Convert CBparams%MBB , CBparams%MBM , CBparams%KBB , CBparams%PhiR , FGR to - ! MBBb, MBMb, KBBb, PHiRb, FGRb - ! (throw out rows/columns of first matrices to create second matrices) - !................................ - CALL CBApplyConstr(p%DOFI, p%DOFR, CBparams%DOFM, p%DOFL, & - CBparams%MBB , CBparams%MBM , CBparams%KBB , CBparams%PhiR , FGR , & - MBBb, MBMb, KBBb, PHiRb, FGRb) - !................................ - ! set values needed to calculate outputs and update states: - !................................ - CALL SetParameters(Init, p, MBBb, MBmb, KBBb, FGRb, PhiRb, CBparams%OmegaL, FGL, CBparams%PhiL, ErrStat2, ErrMsg2) + + CALL AllocAry(PhiRb, nL, nR, 'PhiRb', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if(.not.BC_Before_CB) then + ! We apply the BC now, removing unwanted DOFs + call applyConstr(CB, PhiRb) ! Reduces size of CB%MBB, CB%KBB, CB%MBM, NOTE: "L" unaffected + else + PhiRb=CB%PhiR ! Remove me in the future + endif + ! TODO, right now using PhiRb instead of CB%PhiR, keeping PhiR in harmony with OmegaL for SummaryFile + CALL SetParameters(Init, p, CB%MBB, CB%MBM, CB%KBB, PhiRb, nM_out, CB%OmegaL, CB%PhiL, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'Craig_Bampton') CALL CleanUpCB() contains + SUBROUTINE Fatal(ErrMsg_in) + character(len=*), intent(in) :: ErrMsg_in + CALL SetErrStat(ErrID_Fatal, ErrMsg_in, ErrStat, ErrMsg, 'Craig_Bampton'); + CALL CleanUpCB() + END SUBROUTINE Fatal + logical function Failed() call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') Failed = ErrStat >= AbortErrLev @@ -1596,584 +2294,159 @@ logical function Failed() end function Failed subroutine CleanUpCB() - IF(ALLOCATED(MRR) ) DEALLOCATE(MRR) - IF(ALLOCATED(MLL) ) DEALLOCATE(MLL) - IF(ALLOCATED(MRL) ) DEALLOCATE(MRL) - IF(ALLOCATED(KRR) ) DEALLOCATE(KRR) - IF(ALLOCATED(KLL) ) DEALLOCATE(KLL) - IF(ALLOCATED(KRL) ) DEALLOCATE(KRL) - IF(ALLOCATED(FGL) ) DEALLOCATE(FGL) - IF(ALLOCATED(FGR) ) DEALLOCATE(FGR) - IF(ALLOCATED(MBBb) ) DEALLOCATE(MBBb) - IF(ALLOCATED(MBmb) ) DEALLOCATE(MBmb) - IF(ALLOCATED(KBBb) ) DEALLOCATE(KBBb) IF(ALLOCATED(PhiRb)) DEALLOCATE(PhiRb) - IF(ALLOCATED(FGRb) ) DEALLOCATE(FGRb) end subroutine CleanUpCB -END SUBROUTINE Craig_Bampton + !> Remove fixed DOF from system, this is in case the CB was done on an unconstrained system + !! NOTE: PhiL and OmegaL are not modified + subroutine applyConstr(CBParams, PhiRb) + TYPE(CB_MatArrays), INTENT(INOUT) :: CBparams !< NOTE: data will be reduced (andw hence reallocated) + REAL(FEKi),ALLOCATABLE,INTENT(INOUT) :: PhiRb(:,:)!< NOTE: data will be reduced (andw hence reallocated) + !REAL(ReKi), ALLOCATABLE :: PhiRb(:, :) + REAL(FEKi), ALLOCATABLE :: MBBb(:, :) + REAL(FEKi), ALLOCATABLE :: MBMb(:, :) + REAL(FEKi), ALLOCATABLE :: KBBb(:, :) + ! "b" stands for "bar" + CALL AllocAry( MBBb, p%nDOF__Rb, p%nDOF__Rb, 'matrix MBBb', ErrStat2, ErrMsg2 ); + CALL AllocAry( MBmb, p%nDOF__Rb, p%nDOFM, 'matrix MBmb', ErrStat2, ErrMsg2 ); + CALL AllocAry( KBBb, p%nDOF__Rb, p%nDOF__Rb, 'matrix KBBb', ErrStat2, ErrMsg2 ); + !CALL AllocAry( PhiRb, p%nDOF__L , p%nDOF__Rb, 'matrix PhiRb', ErrStat2, ErrMsg2 ); + !................................ + ! Convert CBparams%MBB , CBparams%MBM , CBparams%KBB , CBparams%PhiR , to + ! MBBb, MBMb, KBBb, PHiRb, + ! (throw out rows/columns of first matrices to create second matrices) + !................................ + ! TODO avoid this all together + MBBb = CBparams%MBB(p%nDOFR__-p%nDOFI__+1:p%nDOFR__, p%nDOFR__-p%nDOFI__+1:p%nDOFR__) + KBBb = CBparams%KBB(p%nDOFR__-p%nDOFI__+1:p%nDOFR__, p%nDOFR__-p%nDOFI__+1:p%nDOFR__) + IF (p%nDOFM > 0) THEN + MBMb = CBparams%MBM(p%nDOFR__-p%nDOFI__+1:p%nDOFR__, : ) + END IF + PhiRb = CBparams%PhiR( :, p%nDOFR__-p%nDOFI__+1:p%nDOFR__) + deallocate(CBparams%MBB) + deallocate(CBparams%KBB) + deallocate(CBparams%MBM) + !deallocate(CBparams%PhiR) + call move_alloc(MBBb, CBparams%MBB) + call move_alloc(KBBb, CBparams%KBB) + call move_alloc(MBMb, CBparams%MBM) + !call move_alloc(PhiRb, CBparams%PhiR) + end subroutine applyConstr + +END SUBROUTINE SD_Craig_Bampton + +!> Extract rigid body mass without SSI +!! NOTE: performs a Guyan reduction +SUBROUTINE SD_Guyan_RigidBodyMass(Init, p, MBB, ErrStat, ErrMsg) + type(SD_InitType), intent(inout) :: Init ! NOTE: Mass and Stiffness are modified but then set back to original + type(SD_ParameterType), intent(in ) :: p ! Parameters + real(FEKi), allocatable, intent(out) :: MBB(:,:) !< MBB + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< error message if errstat /= errid_none + integer(IntKi) :: nM, nR, nL, nM_out + real(FEKi), allocatable :: MBM(:, :) + real(FEKi), allocatable :: KBB(:, :) + real(FEKi), allocatable :: PhiL(:, :) + real(FEKi), allocatable :: PhiR(:, :) + real(FEKi), allocatable :: OmegaL(:) + character(*), parameter :: RoutineName = 'SD_Guyan_RigidBodyMass' + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ! --- Remove SSI from Mass and stiffness matrix (NOTE: use NodesDOFred, reduced matrix) + CALL InsertSoilMatrices(Init%M, Init%K, p%NodesDOFred, Init, p, ErrStat2, ErrMsg2, Substract=.True.); + + ! --- Perform Guyan reduction to get MBB + nR = p%nDOFR__ ! Using interface + reaction nodes + nL = p%nDOF__L + nM = 0 ! No CB modes (Guyan) + nM_out = 0 + if(allocated(MBB)) deallocate(MBB) + CALL AllocAry( MBB, nR, nR, 'MBB', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry( MBM, nR, nM, 'MBM', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry( KBB, nR, nR, 'KBB', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry( PhiL, nL, nL, 'PhiL', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry( PhiR, nL, nR, 'PhiR', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AllocAry( OmegaL, nL, 'OmegaL', ErrStat2, ErrMsg2 ); if(Failed()) return + + CALL CraigBamptonReduction(Init%M, Init%K, p%IDR__, nR, p%ID__L, nL, nM, nM_Out, MBB, MBM, KBB, PhiL, PhiR, OmegaL, ErrStat2, ErrMsg2) + if(Failed()) return -!------------------------------------------------------------------------------------------------------ -!> -SUBROUTINE BreakSysMtrx(Init, p, MRR, MLL, MRL, KRR, KLL, KRL, FGR, FGL ) - TYPE(SD_InitType), INTENT(IN ) :: Init ! Input data for initialization routine - TYPE(SD_ParameterType), INTENT(IN ) :: p - REAL(ReKi), INTENT( OUT) :: MRR(p%DOFR, p%DOFR) - REAL(ReKi), INTENT( OUT) :: MLL(p%DOFL, p%DOFL) - REAL(ReKi), INTENT( OUT) :: MRL(p%DOFR, p%DOFL) - REAL(ReKi), INTENT( OUT) :: KRR(p%DOFR, p%DOFR) - REAL(ReKi), INTENT( OUT) :: KLL(p%DOFL, p%DOFL) - REAL(ReKi), INTENT( OUT) :: KRL(p%DOFR, p%DOFL) - REAL(ReKi), INTENT( OUT) :: FGR(p%DOFR) - REAL(ReKi), INTENT( OUT) :: FGL(p%DOFL) - ! local variables - INTEGER(IntKi) :: I, J, II, JJ - - DO I = 1, p%DOFR !Boundary DOFs - II = p%IDR(I) - FGR(I) = Init%FG(II) - DO J = 1, p%DOFR - JJ = p%IDR(J) - MRR(I, J) = Init%M(II, JJ) - KRR(I, J) = Init%K(II, JJ) - ENDDO - ENDDO - - DO I = 1, p%DOFL - II = p%IDL(I) - FGL(I) = Init%FG(II) - DO J = 1, p%DOFL - JJ = p%IDL(J) - MLL(I, J) = Init%M(II, JJ) - KLL(I, J) = Init%K(II, JJ) - ENDDO - ENDDO - - DO I = 1, p%DOFR - II = p%IDR(I) - DO J = 1, p%DOFL - JJ = p%IDL(J) - MRL(I, J) = Init%M(II, JJ) - KRL(I, J) = Init%K(II, JJ) !Note KRL and MRL are getting data from a constraint-applied formatted M and K (i.e. Mbar and Kbar) this may not be legit!! RRD - ENDDO !I think this is fixed now since the constraint application occurs later - ENDDO - -END SUBROUTINE BreakSysMtrx + if(allocated(KBB) ) deallocate(KBB) + if(allocated(MBM) ) deallocate(MBM) + if(allocated(PhiR) ) deallocate(PhiR) + if(allocated(PhiL) ) deallocate(PhiL) + if(allocated(OmegaL)) deallocate(OmegaL) + + ! --- Insert SSI from Mass and stiffness matrix again + CALL InsertSoilMatrices(Init%M, Init%K, p%NodesDOFred, Init, p, ErrStat2, ErrMsg2, Substract=.False.); if(Failed()) return +contains + logical function Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + Failed = ErrStat >= AbortErrLev + end function Failed +END SUBROUTINE SD_Guyan_RigidBodyMass !------------------------------------------------------------------------------------------------------ -!> Sets the CB values, as documented in the SubDyn Theory Guide: -! OmegaL (omega) and PhiL from Eq. 2 -! p%PhiL_T and p%PhiLInvOmgL2 for static improvement (will be added to theory guide later?) -! PhiR from Eq. 3 -! MBB, MBM, and KBB from Eq. 4. -!................................ -SUBROUTINE CBMatrix( MRR, MLL, MRL, KRR, KLL, KRL, DOFM, Init, & - MBB, MBM, KBB, PhiL, PhiR, OmegaL, ErrStat, ErrMsg,p) - TYPE(SD_InitType), INTENT(IN) :: Init - TYPE(SD_ParameterType), INTENT(INOUT) :: p - INTEGER(IntKi), INTENT( in) :: DOFM - REAL(ReKi), INTENT( IN) :: MRR( p%DOFR, p%DOFR) - REAL(ReKi), INTENT( IN) :: MLL( p%DOFL, p%DOFL) - REAL(ReKi), INTENT( IN) :: MRL( p%DOFR, p%DOFL) - REAL(ReKi), INTENT( IN) :: KRR( p%DOFR, p%DOFR) - REAL(ReKi), INTENT(INOUT) :: KLL( p%DOFL, p%DOFL) ! on exit, it has been factored (otherwise not changed) - REAL(ReKi), INTENT( IN) :: KRL( p%DOFR, p%DOFL) - REAL(ReKi), INTENT(INOUT) :: MBB( p%DOFR, p%DOFR) - REAL(ReKi), INTENT(INOUT) :: MBM( p%DOFR, DOFM) - REAL(ReKi), INTENT(INOUT) :: KBB( p%DOFR, p%DOFR) - REAL(ReKi), INTENT(INOUT) :: PhiR(p%DOFL, p%DOFR) - REAL(ReKi), INTENT(INOUT) :: PhiL(p%DOFL, p%DOFL) !used to be PhiM(DOFL,DOFM), now it is more generic - REAL(ReKi), INTENT(INOUT) :: OmegaL(p%DOFL) !used to be omegaM only ! Eigenvalues - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - ! LOCAL VARIABLES - REAL(ReKi) , allocatable :: Mu(:, :) ! matrix for normalization Mu(p%DOFL, p%DOFL) [bjj: made allocatable to try to avoid stack issues] - REAL(ReKi) , allocatable :: Temp(:, :) ! temp matrix for intermediate steps [bjj: made allocatable to try to avoid stack issues] - REAL(ReKi) , allocatable :: PhiR_T_MLL(:,:) ! PhiR_T_MLL(p%DOFR,p%DOFL) = transpose of PhiR * MLL (temporary storage) - INTEGER :: I !, lwork !counter, and varibales for inversion routines - INTEGER :: DOFvar !placeholder used to get both PhiL or PhiM into 1 process - INTEGER :: ipiv(p%DOFL) !the integer vector ipvt of length min(m,n), containing the pivot indices. - !Returned as: a one-dimensional array of (at least) length min(m,n), containing integers, - !where 1 <= less than or equal to ipvt(i) <= less than or equal to m. - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'CBMatrix' - - ErrStat = ErrID_None - ErrMsg = '' - - CALL WrScr(' Calculating Internal Modal Eigenvectors') - - IF (p%SttcSolve) THEN ! STATIC TREATMENT IMPROVEMENT - DOFvar=p%DOFL - ELSE - DOFvar=DOFM !Initialize for normal cases, dynamic only - ENDIF - - !.................................................... - ! Set OmegaL and PhiL from Eq. 2 - !.................................................... - IF ( DOFvar > 0 ) THEN ! Only time this wouldn't happen is if no modes retained and no static improvement... - CALL EigenSolve(KLL, MLL, p%DOFL, DOFvar, .False.,Init,p, PhiL(:,1:DOFvar), OmegaL(1:DOFvar), ErrStat2, ErrMsg2); if(Failed()) return - - ! --- Normalize PhiL - ! bjj: break up this equation to avoid as many tenporary variables on the stack - ! MU = MATMUL ( MATMUL( TRANSPOSE(PhiL), MLL ), PhiL ) - CALL AllocAry( Temp , p%DOFL , p%DOFL , 'Temp' , ErrStat2 , ErrMsg2); if(Failed()) return - CALL AllocAry( MU , p%DOFL , p%DOFL , 'Mu' , ErrStat2 , ErrMsg2); if(Failed()) return - MU = TRANSPOSE(PhiL) - Temp = MATMUL( MU, MLL ) - MU = MATMUL( Temp, PhiL ) - DEALLOCATE(Temp) - ! PhiL = MATMUL( PhiL, MU2 ) !this is the nondimensionalization (MU2 is diagonal) - DO I = 1, DOFvar - PhiL(:,I) = PhiL(:,I) / SQRT( MU(I, I) ) - ENDDO - DO I=DOFvar+1, p%DOFL !loop done only if .not. p%SttcSolve .and. DOFM < p%DOFL (and actually, in that case, these values aren't used anywhere anyway) - PhiL(:,I) = 0.0_ReKi - OmegaL(I) = 0.0_ReKi - END DO - DEALLOCATE(MU) - - !.................................................... - ! Set p%PhiL_T and p%PhiLInvOmgL2 for static improvement - !.................................................... - IF (p%SttcSolve) THEN - p%PhiL_T=TRANSPOSE(PhiL) !transpose of PhiL for static improvement - DO I = 1, p%DOFL - p%PhiLInvOmgL2(:,I) = PhiL(:,I)* (1./OmegaL(I)**2) - ENDDO - END IF - - ! ELSE .not. p%SttcSolve .and. DOFM < p%DOFL (in this case, PhiL, OmegaL aren't used) - END IF - - - !.................................................... - ! Set PhiR from Eq. 3: - !.................................................... - ! now factor KLL to compute PhiR: KLL*PhiR=-TRANSPOSE(KRL) - ! ** note this must be done after EigenSolve() because it modifies KLL ** - CALL LAPACK_getrf( p%DOFL, p%DOFL, KLL, ipiv, ErrStat2, ErrMsg2); if(Failed()) return - - PhiR = -1.0_ReKi * TRANSPOSE(KRL) !set "b" in Ax=b (solve KLL * PhiR = - TRANSPOSE( KRL ) for PhiR) - CALL LAPACK_getrs( TRANS='N',N=p%DOFL,A=KLL,IPIV=ipiv, B=PhiR, ErrStat=ErrStat2, ErrMsg=ErrMsg2); if(Failed()) return - - !.................................................... - ! Set MBB, MBM, and KBB from Eq. 4: - !.................................................... - CALL AllocAry( PhiR_T_MLL, p%DOFR, p%DOFL, 'PhiR_T_MLL', ErrStat2, ErrMsg2); if(Failed()) return - - PhiR_T_MLL = TRANSPOSE(PhiR) - PhiR_T_MLL = MATMUL(PhiR_T_MLL, MLL) - MBB = MATMUL(MRL, PhiR) - MBB = MRR + MBB + TRANSPOSE( MBB ) + MATMUL( PhiR_T_MLL, PhiR ) - - - IF ( DOFM .EQ. 0) THEN - MBM = 0.0_ReKi - ELSE - MBM = MATMUL( PhiR_T_MLL, PhiL(:,1:DOFM)) ! last half of operation - MBM = MATMUL( MRL, PhiL(:,1:DOFM) ) + MBM !This had PhiM - ENDIF - DEALLOCATE( PhiR_T_MLL ) - - KBB = MATMUL(KRL, PhiR) - KBB = KBB + KRR - -CONTAINS - - logical function Failed() - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'CBMatrix') - Failed = ErrStat >= AbortErrLev - if (Failed) call CleanUp() - end function Failed - - subroutine CleanUp() - if (allocated(Mu )) DEALLOCATE(Mu ) - if (allocated(Temp )) DEALLOCATE(Temp ) - if (allocated(PhiR_T_MLL)) DEALLOCATE(PhiR_T_MLL) - end subroutine -END SUBROUTINE CBMatrix - -!------------------------------------------------------------------------------------------------------ -!> -SUBROUTINE TrnsfTI(Init, TI, DOFI, IDI, TI2, DOFR, IDR, ErrStat, ErrMsg) - TYPE(SD_InitType), INTENT(IN ) :: Init ! Input data for initialization routine - INTEGER(IntKi), INTENT(IN ) :: DOFI ! # of DOFS of interface nodes - INTEGER(IntKi), INTENT(IN ) :: DOFR ! # of DOFS of restrained nodes (restraints and interface) - INTEGER(IntKi), INTENT(IN ) :: IDI(DOFI) - INTEGER(IntKi), INTENT(IN ) :: IDR(DOFR) - REAL(ReKi), INTENT(INOUT) :: TI( DOFI,6) ! matrix TI that relates the reduced matrix to the TP, - REAL(ReKi), INTENT(INOUT) :: TI2(DOFR,6) ! matrix TI2 that relates to (0,0,0) the overall substructure mass - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - ! local variables - INTEGER :: I, di - INTEGER :: rmndr, n - REAL(ReKi) :: dx, dy, dz - - ErrStat = ErrID_None - ErrMsg = "" - - TI(:,:) = 0. !Initialize - DO I = 1, DOFI - di = IDI(I) - rmndr = MOD(di, 6) - n = CEILING(di/6.0) - - dx = Init%Nodes(n, 2) - Init%TP_RefPoint(1) - dy = Init%Nodes(n, 3) - Init%TP_RefPoint(2) - dz = Init%Nodes(n, 4) - Init%TP_RefPoint(3) - - SELECT CASE (rmndr) - CASE (1); TI(I, 1:6) = (/1.0_ReKi, 0.0_ReKi, 0.0_ReKi, 0.0_ReKi, dz, -dy/) - CASE (2); TI(I, 1:6) = (/0.0_ReKi, 1.0_ReKi, 0.0_ReKi, -dz, 0.0_ReKi, dx/) - CASE (3); TI(I, 1:6) = (/0.0_ReKi, 0.0_ReKi, 1.0_ReKi, dy, -dx, 0.0_ReKi/) - CASE (4); TI(I, 1:6) = (/0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 1.0_ReKi, 0.0_ReKi, 0.0_ReKi/) - CASE (5); TI(I, 1:6) = (/0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 1.0_ReKi, 0.0_ReKi/) - CASE (0); TI(I, 1:6) = (/0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 1.0_ReKi/) - CASE DEFAULT - ErrStat = ErrID_Fatal - ErrMsg = 'Error calculating transformation matrix TI ' - RETURN - END SELECT - - ENDDO - - !Augment with TI2 - TI2(:,:) = 0. !Initialize - DO I = 1, DOFR - di = IDR(I) - rmndr = MOD(di, 6) - n = CEILING(di/6.0) - - dx = Init%Nodes(n, 2) - dy = Init%Nodes(n, 3) - dz = Init%Nodes(n, 4) - SELECT CASE (rmndr) - CASE (1); TI2(I, 1:6) = (/1.0_ReKi, 0.0_ReKi, 0.0_ReKi, 0.0_ReKi, dz, -dy/) - CASE (2); TI2(I, 1:6) = (/0.0_ReKi, 1.0_ReKi, 0.0_ReKi, -dz, 0.0_ReKi, dx/) - CASE (3); TI2(I, 1:6) = (/0.0_ReKi, 0.0_ReKi, 1.0_ReKi, dy, -dx, 0.0_ReKi/) - CASE (4); TI2(I, 1:6) = (/0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 1.0_ReKi, 0.0_ReKi, 0.0_ReKi/) - CASE (5); TI2(I, 1:6) = (/0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 1.0_ReKi, 0.0_ReKi/) - CASE (0); TI2(I, 1:6) = (/0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 0.0_ReKi, 1.0_ReKi/) - CASE DEFAULT - ErrStat = ErrID_Fatal - ErrMsg = 'Error calculating transformation matrix TI2 ' - RETURN - END SELECT - ENDDO - -END SUBROUTINE TrnsfTI - -!------------------------------------------------------------------------------------------------------ -!> Return eigenvalues, Omega, and eigenvectors, Phi, -SUBROUTINE EigenSolve(K, M, nDOF, NOmega, Reduced, Init,p, Phi, Omega, ErrStat, ErrMsg ) - USE NWTC_ScaLAPACK, only: ScaLAPACK_LASRT - INTEGER, INTENT(IN ) :: nDOF ! Total degrees of freedom of the incoming system - REAL(ReKi), INTENT(IN ) :: K(nDOF, nDOF) ! stiffness matrix - REAL(ReKi), INTENT(IN ) :: M(nDOF, nDOF) ! mass matrix - INTEGER, INTENT(IN ) :: NOmega ! RRD: no. of requested eigenvalues - LOGICAL, INTENT(IN ) :: Reduced ! Whether or not to reduce matrices, this will be removed altogether later, when reduction will be done apriori - TYPE(SD_InitType), INTENT(IN ) :: Init - TYPE(SD_ParameterType), INTENT(IN ) :: p - REAL(ReKi), INTENT( OUT) :: Phi(nDOF, NOmega) ! RRD: Returned Eigenvectors - REAL(ReKi), INTENT( OUT) :: Omega(NOmega) ! RRD: Returned Eigenvalues - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - ! LOCALS - REAL(LAKi), ALLOCATABLE :: Omega2(:) !RRD: Eigen-values new system -! note: SGGEV seems to have memory issues in certain cases. The eigenvalues seem to be okay, but the eigenvectors vary wildly with different compiling options. -! DGGEV seems to work better, so I'm making these variables LAKi (which is set to R8Ki for now) - bjj 4/25/2014 - REAL(LAKi), ALLOCATABLE :: Kred(:,:), Mred(:,:) - REAL(LAKi), ALLOCATABLE :: WORK (:), VL(:,:), VR(:,:), ALPHAR(:), ALPHAI(:), BETA(:) ! eigensolver variables - INTEGER :: i - INTEGER :: N, LWORK !variables for the eigensolver - INTEGER, ALLOCATABLE :: KEY(:) - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - - ErrStat = ErrID_None - ErrMsg = '' - - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! - IF (Reduced) THEN !bjj: i.e., We need to reduce; it's not reduced yet - ! First I need to remove constrained nodes DOFs - ! This is actually done when we are printing out the 'full' set of eigenvalues - CALL ReduceKMdofs(Kred,K,nDOF, Init,p, ErrStat2, ErrMsg2 ); if(Failed()) return - CALL ReduceKMdofs(Mred,M,nDOF, Init,p, ErrStat2, ErrMsg2 ); if(Failed()) return - N=SIZE(Kred,1) - ELSE - ! This is actually done whe we are generating the CB-reduced set of eigenvalues, so the the variable 'Reduced' can be a bit confusing. GJH 8/1/13 - N=SIZE(K,1) - CALL AllocAry( Kred, n, n, 'Kred', ErrStat2, ErrMsg2 ); if(Failed()) return - CALL AllocAry( Mred, n, n, 'Mred', ErrStat2, ErrMsg2 ); if(Failed()) return - Kred=REAL( K, LAKi ) - Mred=REAL( M, LAKi ) - ENDIF - ! Note: NOmega must be <= N, which is the length of Omega2, Phi! - IF ( NOmega > N ) THEN - CALL SetErrStat(ErrID_Fatal,"NOmega must be less than or equal to N",ErrStat,ErrMsg,'EigenSolve') - CALL CleanupEigen() - RETURN - END IF - - ! allocate working arrays and return arrays for the eigensolver - LWORK=8*N + 16 !this is what the eigensolver wants >> bjj: +16 because of MKL ?ggev documenation ( "lwork >= max(1, 8n+16) for real flavors"), though LAPACK documenation says 8n is fine - !bjj: there seems to be a memory problem in *GGEV, so I'm making the WORK array larger to see if I can figure it out - CALL AllocAry( Work, lwork, 'Work', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'EigenSolve') - CALL AllocAry( Omega2, n, 'Omega2', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'EigenSolve') - CALL AllocAry( ALPHAR, n, 'ALPHAR', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'EigenSolve') - CALL AllocAry( ALPHAI, n, 'ALPHAI', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'EigenSolve') - CALL AllocAry( BETA, n, 'BETA', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'EigenSolve') - CALL AllocAry( VR, n, n, 'VR', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'EigenSolve') - CALL AllocAry( VL, n, n, 'VR', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,'EigenSolve') - CALL AllocAry( KEY, n, 'KEY', ErrStat2, ErrMsg2 ); if(Failed()) return - - CALL LAPACK_ggev('N','V',N ,Kred, Mred, ALPHAR, ALPHAI, BETA, VL, VR, work, lwork, ErrStat2, ErrMsg2) - if(Failed()) return - !if (.not. reduced) call wrmatrix(REAL(VR,ReKi),77,'ES15.8e2') - ! bjj: This comes from the LAPACK documentation: - ! Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j) may easily over- or underflow, and BETA(j) may even be zero. - ! Thus, the user should avoid naively computing the ratio alpha/beta. However, ALPHAR and ALPHAI will be always less - ! than and usually comparable with norm(A) in magnitude, and BETA always less than and usually comparable with norm(B). - ! Omega2=ALPHAR/BETA !Note this may not be correct if ALPHAI<>0 and/or BETA=0 TO INCLUDE ERROR CHECK, also they need to be sorted - DO I=1,N !Initialize the key and calculate Omega2 - KEY(I)=I - IF ( EqualRealNos(Beta(I),0.0_LAKi) ) THEN - Omega2(I) = HUGE(Omega2) ! bjj: should this be an error? - ELSE - Omega2(I) = REAL( ALPHAR(I)/BETA(I), ReKi ) - END IF - ENDDO - CALL ScaLAPACK_LASRT('I',N,Omega2,key,ErrStat2,ErrMsg2); if(Failed()) return - - !we need to rearrange eigenvectors based on sorting of Omega2 - !Now rearrange VR based on the new key, also I might have to scale the eigenvectors following generalized mass =idnetity criterion, also if i reduced the matrix I will need to re-expand the eigenvector - ! ALLOCATE(normcoeff(N,N), STAT = ErrStat ) - ! result1 = matmul(Mred2,VR) - ! result2 = matmul(transpose(VR),result1) - ! normcoeff=sqrt(result2) !This should be a diagonal matrix which contains the normalization factors - !normcoeff=sqrt(matmul(transpose(VR),matmul(Mred2,VR))) !This should be a diagonal matrix which contains the normalization factors - VL=VR !temporary storage for sorting VR - DO I=1,N - !VR(:,I)=VL(:,KEY(I))/normcoeff(KEY(I),KEY(I)) !reordered and normalized - VR(:,I)=VL(:,KEY(I)) !just reordered as Huimin had a normalization outside of this one - ENDDO - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! - - ! --- Finish EigenSolve - ! Note: NOmega must be <= N, which is the length of Omega2, Phi! - Omega=SQRT( Omega2(1:NOmega) ) !Assign my new Omega and below my new Phi (eigenvectors) [eigenvalues are actually the square of omega] - IF ( Reduced ) THEN ! this is called for the full system Eigenvalues: - !Need to expand eigenvectors for removed DOFs, setting Phi - CALL UnReduceVRdofs(VR(:,1:NOmega),Phi,N,NOmega, Init,p, ErrStat2, ErrMsg2 ) ; if(Failed()) return - ELSE ! IF (.NOT.(Reduced)) THEN !For the time being Phi gets updated only when CB eigensolver is requested. I need to fix it for the other case (full fem) and then get rid of the other eigensolver, this implies "unreducing" the VR - ! This is done as part of the CB-reduced eigensolve - Phi=REAL( VR(:,1:NOmega), ReKi ) ! eigenvectors - ENDIF - - CALL CleanupEigen() - RETURN - -CONTAINS - LOGICAL FUNCTION Failed() - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'EigenSolve') - Failed = ErrStat >= AbortErrLev - if (Failed) call CleanUpEigen() - END FUNCTION Failed - - SUBROUTINE CleanupEigen() - IF (ALLOCATED(Work) ) DEALLOCATE(Work) - IF (ALLOCATED(Omega2)) DEALLOCATE(Omega2) !bjj: break in Debug_Doub - IF (ALLOCATED(ALPHAR)) DEALLOCATE(ALPHAR) - IF (ALLOCATED(ALPHAI)) DEALLOCATE(ALPHAI) - IF (ALLOCATED(BETA) ) DEALLOCATE(BETA) - IF (ALLOCATED(VR) ) DEALLOCATE(VR) - IF (ALLOCATED(VL) ) DEALLOCATE(VL) - IF (ALLOCATED(KEY) ) DEALLOCATE(KEY) - IF (ALLOCATED(Kred) ) DEALLOCATE(Kred) - IF (ALLOCATED(Mred) ) DEALLOCATE(Mred) - END SUBROUTINE CleanupEigen - -END SUBROUTINE EigenSolve - -!------------------------------------------------------------------------------------------------------ -!> Calculate Kred from K after removing consstrained node DOFs from the full M and K matrices -!!Note it works for constrained nodes, still to see how to make it work for interface nodes if needed -SUBROUTINE ReduceKMdofs(Kred,K,TDOF, Init,p, ErrStat, ErrMsg ) - TYPE(SD_InitType), INTENT( in) :: Init - TYPE(SD_ParameterType), INTENT( in) :: p - INTEGER, INTENT(IN ) :: TDOF ! Size of matrix K (total DOFs) - REAL(ReKi), INTENT(IN ) :: K(TDOF, TDOF) ! full matrix - REAL(LAKi),ALLOCATABLE, INTENT( OUT) :: Kred(:,:) ! reduced matrix - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - !locals - INTEGER :: I, J ! counters into full or reduced matrix - INTEGER :: L ! number of DOFs to eliminate - INTEGER, ALLOCATABLE :: idx(:) ! vector to map reduced matrix to full matrix - INTEGER :: NReactDOFs - INTEGER :: DOF_reduced - INTEGER :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - - ErrStat = ErrID_None - ErrMsg = '' - - NReactDOFs = p%NReact*6 !p%DOFC - IF (NReactDOFs > TDOF) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'ReduceKMdofs:invalid matrix sizes.' - RETURN - END IF - - CALL AllocAry(idx, TDOF, 'idx', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,'ReduceKMdofs') - IF (ErrStat >= AbortErrLev) THEN - RETURN - END IF - - ! Calculate how many rows/columns need to be eliminated: - DO I = 1, TDOF - idx(I) = I - END DO - - L = 0 - DO I = 1, NReactDOFs !Cycle on reaction DOFs - IF (Init%BCs(I, 2) == 1) THEN - L=L+1 !number of DOFs to eliminate - idx( Init%BCs(I, 1) ) = 0 ! Eliminate this one - END IF - END DO - - ! Allocate the output matrix and the index mapping array - DOF_reduced = TDOF-L - CALL AllocAry(Kred, DOF_reduced, DOF_reduced, 'Kred', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,'ReduceKMdofs') - IF (ErrStat >= AbortErrLev) THEN - CALL CleanUp() - RETURN - END IF - - ! set the indices we want to keep (i.e., a mapping from reduced to full matrix) - J = 1 - DO I=1,TDOF - idx(J) = idx(I) - IF ( idx(J) /= 0 ) J = J + 1 - END DO - - ! Remove rows and columns from every row/column in full matrix where Init%BC(:,2) == 1, - ! using the mapping created above. (This is a symmetric matrix.) - DO J = 1, DOF_reduced !Cycle on reaction DOFs - DO I = 1, DOF_reduced !Cycle on reaction DOFs - Kred(I,J) = REAL( K( idx(I), idx(J) ), LAKi ) - END DO - END DO - ! clean up local variables: - CALL CleanUp() -CONTAINS - subroutine CleanUp() - IF (ALLOCATED(idx)) DEALLOCATE(idx) - end subroutine -END SUBROUTINE ReduceKMdofs - -!------------------------------------------------------------------------------------------------------ -!> Augments VRred to VR for the constrained DOFs, somehow reversing what ReducedKM did for matrices -!Note it works for constrained nodes, still to see how to make it work for interface nodes if needed -SUBROUTINE UnReduceVRdofs(VRred,VR,rDOF,rModes, Init,p, ErrStat, ErrMsg ) - TYPE(SD_InitType), INTENT(in ) :: Init - TYPE(SD_ParameterType), INTENT(in ) :: p - INTEGER, INTENT(IN ) :: rDOF ,RModes !retained DOFs after removing restrained DOFs and retained modes - REAL(LAKi), INTENT(IN ) :: VRred(rDOF, rModes) !eigenvector matrix with restrained DOFs removed - REAL(ReKi), INTENT(INOUT) :: VR(:,:) !eigenvalues including the previously removed DOFs - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - !locals - INTEGER, ALLOCATABLE :: idx(:) - INTEGER :: I, I2, L !counters; I,I2 should be long, L short - - ErrStat = ErrID_None - ErrMsg = '' - - ALLOCATE(idx(p%NReact*6), STAT = ErrStat ) !it contains row/col index that was originally eliminated when applying restraints - idx=0 !initialize - L=0 !initialize - DO I = 1, p%NReact*6 !Cycle on reaction DOFs - IF (Init%BCs(I, 2) == 1) THEN - idx(I)=Init%BCs(I, 1) !row/col index that was originally eliminated when applying restraints - L=L+1 !number of DOFs to eliminate - ENDIF - ENDDO -! PRINT *, ' rDOF+L=',rDOF+L, 'SIZE(Phi2)=',SIZE(VR,1) -! ALLOCATE(VR(rDOF+L,rModes), STAT = ErrStat ) !Restored eigenvectors with restrained node DOFs included - VR=0.!Initialize - - I2=1 !Initialize - DO I=1,rDOF+L !This loop inserts Vred in VR in all but the removed DOFs - IF (ALL((idx-I).NE.0)) THEN - VR(I,:)=REAL( VRred(I2,:), ReKi ) ! potentially change of precision - I2=I2+1 !Note this counter gets updated only if we insert Vred rows into VR - ENDIF - ENDDO -END SUBROUTINE UnReduceVRdofs - -!------------------------------------------------------------------------------------------------------ -SUBROUTINE CBApplyConstr(DOFI, DOFR, DOFM, DOFL, & - MBB , MBM , KBB , PHiR , FGR , & - MBBb, MBMb, KBBb, PHiRb, FGRb) - INTEGER(IntKi), INTENT(IN ) :: DOFR, DOFI, DOFM, DOFL - REAL(ReKi), INTENT(IN ) :: FGR(DOFR) - REAL(ReKi), INTENT(IN ) :: MBB(DOFR, DOFR) - REAL(ReKi), INTENT(IN ) :: MBM(DOFR, DOFM) - REAL(ReKi), INTENT(IN ) :: KBB(DOFR, DOFR) - REAL(ReKi), INTENT(IN ) :: PhiR(DOFL, DOFR) - REAL(ReKi), INTENT( OUT) :: MBBb(DOFI, DOFI) - REAL(ReKi), INTENT( OUT) :: KBBb(DOFI, DOFI) - REAL(ReKi), INTENT( OUT) :: MBMb(DOFI, DOFM) - REAL(ReKi), INTENT( OUT) :: FGRb(DOFI) - REAL(ReKi), INTENT( OUT) :: PhiRb(DOFL, DOFI) - - MBBb = MBB(DOFR-DOFI+1:DOFR, DOFR-DOFI+1:DOFR) - KBBb = KBB(DOFR-DOFI+1:DOFR, DOFR-DOFI+1:DOFR) -IF (DOFM > 0) THEN - MBMb = MBM(DOFR-DOFI+1:DOFR, : ) -END IF - FGRb = FGR(DOFR-DOFI+1:DOFR ) - PhiRb = PhiR( :, DOFR-DOFI+1:DOFR) - -END SUBROUTINE CBApplyConstr - -!------------------------------------------------------------------------------------------------------ -SUBROUTINE SetParameters(Init, p, MBBb, MBmb, KBBb, FGRb, PhiRb, OmegaL, FGL, PhiL, ErrStat, ErrMsg) +!> Set parameters to compute state and output equations +!! NOTE: this function converst from FEKi to ReKi +SUBROUTINE SetParameters(Init, p, MBBb, MBmb, KBBb, PhiRb, nM_out, OmegaL, PhiL, ErrStat, ErrMsg) + use NWTC_LAPACK, only: LAPACK_GEMM, LAPACK_getrf TYPE(SD_InitType), INTENT(IN ) :: Init ! Input data for initialization routine TYPE(SD_ParameterType), INTENT(INOUT) :: p ! Parameters - REAL(ReKi), INTENT(IN ) :: MBBb( p%DOFI, p%DOFI) - REAL(ReKi), INTENT(IN ) :: MBMb( p%DOFI, p%Nmodes) - REAL(ReKi), INTENT(IN ) :: KBBb( p%DOFI, p%DOFI) - REAL(ReKi), INTENT(IN ) :: PhiL ( p%DOFL, p%DOFL) - REAL(ReKi), INTENT(IN ) :: PhiRb( p%DOFL, p%DOFI) - REAL(ReKi), INTENT(IN ) :: OmegaL(p%DOFL) - REAL(ReKi), INTENT(IN ) :: FGRb(p%DOFI) - REAL(ReKi), INTENT(IN ) :: FGL(p%DOFL) + REAL(FEKi), INTENT(IN ) :: MBBb( p%nDOF__Rb, p%nDOF__Rb) ! Guyan mass matrix + REAL(FEKi), INTENT(IN ) :: MBMb( p%nDOF__Rb, p%nDOFM) + REAL(FEKi), INTENT(IN ) :: KBBb( p%nDOF__Rb, p%nDOF__Rb) ! Guyan stiffness matrix + integer(IntKi), INTENT(IN ) :: nM_out + REAL(FEKi), INTENT(IN ) :: PhiL ( p%nDOF__L, nM_out) + REAL(FEKi), INTENT(IN ) :: PhiRb( p%nDOF__L, p%nDOF__Rb) + REAL(FEKi), INTENT(IN ) :: OmegaL(nM_out) INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None ! local variables - REAL(ReKi) :: TI_transpose(TPdofL,p%DOFI) !bjj: added this so we don't have to take the transpose 5+ times - INTEGER(IntKi) :: I + real(FEKi), allocatable :: Temp(:,:) + real(ReKi) :: TI_transpose(nDOFL_TP,p%nDOFI__) !bjj: added this so we don't have to take the transpose 5+ times + integer(IntKi) :: I integer(IntKi) :: n ! size of jacobian in AM2 calculation INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'SetParameters' - + real(ReKi) :: dt_max, freq_max + character(ErrMsgLen) :: Info ErrStat = ErrID_None ErrMsg = '' - + + if (p%nDOFI__/=p%nDOF__Rb) then + ! Limitation due to the TI matrix, on the input U_R to the module for now + ErrMsg2='For now number of leader DOF has to be the same a Rb DOF' + ErrStat2=ErrID_Fatal + if(Failed()) return + endif + + ! Set TI, transformation matrix from interface DOFs to TP ref point (Note: TI allocated in AllocParameters) + CALL RigidTrnsf(Init, p, Init%TP_RefPoint, p%IDI__, p%nDOFI__, p%TI, ErrStat2, ErrMsg2); if(Failed()) return TI_transpose = TRANSPOSE(p%TI) - ! Store FGL for later processes - IF (p%SttcSolve) THEN - p%FGL = FGL - ENDIF + ! Store Static Improvement Method constants + if (p%SttcSolve /= idSIM_None) then + if (p%SttcSolve == idSIM_Full) then + CALL WrScr(' Using static improvement method for gravity and ext. loads') + else + CALL WrScr(' Using static improvement method for gravity only') + endif + ! Allocations - NOTE: type conversion belows from FEKi to ReKi + CALL AllocAry( p%PhiL_T, p%nDOF__L, p%nDOF__L, 'p%PhiL_T', ErrStat2, ErrMsg2 ); if(Failed())return + CALL AllocAry( p%PhiLInvOmgL2, p%nDOF__L, p%nDOF__L, 'p%PhiLInvOmgL2', ErrStat2, ErrMsg2 ); if(Failed())return + CALL AllocAry( p%KLLm1 , p%nDOF__L, p%nDOF__L, 'p%KLLm1', ErrStat2, ErrMsg2 ); if(Failed())return + ! TODO PhiL_T and PhiLInvOmgL2 may not be needed if KLLm1 is stored. + p%PhiL_T=TRANSPOSE(PhiL) !transpose of PhiL for static improvement + do I = 1, nM_out + p%PhiLInvOmgL2(:,I) = PhiL(:,I)* (1./OmegaL(I)**2) + enddo + ! KLL^-1 = [PhiL] x [OmegaL^2]^-1 x [PhiL]^t + !p%KLLm1 = MATMUL(p%PhiLInvOmgL2, p%PhiL_T) ! Inverse of KLL: KLL^-1 = [PhiL] x [OmegaL^2]^-1 x [PhiL]^t + CALL LAPACK_gemm( 'N', 'N', 1.0_ReKi, p%PhiLInvOmgL2, p%PhiL_T, 0.0_ReKi, p%KLLm1, ErrStat2, ErrMsg2); if(Failed()) return + endif ! block element of D2 matrix (D2_21, D2_42, & part of D2_62) p%PhiRb_TI = MATMUL(PhiRb, p%TI) @@ -2184,103 +2457,105 @@ SUBROUTINE SetParameters(Init, p, MBBb, MBmb, KBBb, FGRb, PhiRb, OmegaL, FGL, Ph p%MBB = MATMUL( MATMUL( TI_transpose, MBBb ), p%TI) != MBBt p%KBB = MATMUL( MATMUL( TI_transpose, KBBb ), p%TI) != KBBt + ! 6x6 Guyan Damping matrix + if (Init%GuyanDampMod == idGuyanDamp_None) then + ! No Damping + p%CBB = 0.0_ReKi + elseif (Init%GuyanDampMod == idGuyanDamp_Rayleigh) then + ! Rayleigh Damping + p%CBB = Init%RayleighDamp(1) * p%MBB + Init%RayleighDamp(2) * p%KBB + elseif (Init%GuyanDampMod == idGuyanDamp_66) then + ! User 6x6 matrix + if (size(p%CBB,1)/=6) then + ErrMsg='Cannot use 6x6 Guyan Damping matrix, number of interface DOFs is'//num2lstr(size(p%CBB,1)); ErrStat=ErrID_Fatal; + return + endif + p%CBB = Init%GuyanDampMat + endif + !p%D1_15=-TI_transpose !this is 6x6NIN - IF ( p%NModes > 0 ) THEN ! These values don't exist for DOFM=0; i.e., p%NModes == 0 - ! p%MBM = MATMUL( TRANSPOSE(p%TI), MBmb ) != MBMt - CALL LAPACK_gemm( 'T', 'N', 1.0_ReKi, p%TI, MBmb, 0.0_ReKi, p%MBM, ErrStat2, ErrMsg2) != MBMt - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//'p%MBM') + IF ( p%nDOFM > 0 ) THEN ! These values don't exist for nDOFM=0; i.e., p%nDOFM == 0 + ! TODO cant use LAPACK due to type conversions FEKi->ReKi + p%MBM = MATMUL( TI_transpose, MBmb ) ! NOTE: type conversion + !CALL LAPACK_gemm( 'T', 'N', 1.0_ReKi, p%TI, MBmb, 0.0_ReKi, p%MBM, ErrStat2, ErrMsg2); if(Failed()) return p%MMB = TRANSPOSE( p%MBM ) != MMBt - p%PhiM = PhiL(:,1:p%Nmodes) + + p%PhiM = real( PhiL(:,1:p%nDOFM), ReKi) - ! A_21, A_22 (these are diagonal matrices. bjj: I am storing them as arrays instead of full matrices) - p%NOmegaM2 = -1.0_ReKi * OmegaL(1:p%Nmodes) * OmegaL(1:p%Nmodes) ! OmegaM is a one-dimensional array - p%N2OmegaMJDamp = -2.0_ReKi * OmegaL(1:p%Nmodes) * Init%JDampings(1:p%Nmodes) ! Init%JDampings is also a one-dimensional array - - ! B_23, B_24 - !p%PhiM_T = TRANSPOSE( p%PhiM ) - - ! FX - ! p%FX = MATMUL( p%PhiM_T, FGL ) != MATMUL( TRANSPOSE(PhiM), FGL ) - p%FX = MATMUL( FGL, p%PhiM ) != MATMUL( TRANSPOSE(PhiM), FGL ) because FGL is 1-D - + ! A_21=-Kmm (diagonal), A_22=-Cmm (approximated as diagonal) + p%KMMDiag= OmegaL(1:p%nDOFM) * OmegaL(1:p%nDOFM) ! OmegaM is a one-dimensional array + p%CMMDiag = 2.0_ReKi * OmegaL(1:p%nDOFM) * Init%JDampings(1:p%nDOFM) ! Init%JDampings is also a one-dimensional array + ! C1_11, C1_12 ( see eq 15 [multiply columns by diagonal matrix entries for diagonal multiply on the left]) - DO I = 1, p%Nmodes ! if (p%NModes=p%qmL=DOFM == 0), this loop is skipped - p%C1_11(:, I) = p%MBM(:, I)*p%NOmegaM2(I) - p%C1_12(:, I) = p%MBM(:, I)*p%N2OmegaMJDamp(I) + DO I = 1, p%nDOFM ! if (p%nDOFM=p%nDOFM=nDOFM == 0), this loop is skipped + p%C1_11(:, I) = -p%MBM(:, I)*p%KMMDiag(I) + p%C1_12(:, I) = -p%MBM(:, I)*p%CMMDiag(I) ENDDO - ! D1_13, D1_14 (with retained modes) - !p%D1_13 = p%MBB - MATMUL( p%MBM, p%MMB ) - CALL LAPACK_GEMM( 'N', 'T', 1.0_ReKi, p%MBM, p%MBM, 0.0_ReKi, p%D1_13, ErrStat2, ErrMsg2 ) ! p%D1_13 = MATMUL( p%MBM, p%MMB ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - p%D1_13 = p%MBB - p%D1_13 - - !p%D1_14 = MATMUL( p%MBM, p%PhiM_T ) - MATMUL( TI_transpose, TRANSPOSE(PHiRb)) - CALL LAPACK_GEMM( 'T', 'T', 1.0_ReKi, p%TI, PHiRb, 0.0_ReKi, p%D1_14, ErrStat2, ErrMsg2 ) ! p%D1_14 = MATMUL( TRANSPOSE(TI), TRANSPOSE(PHiRb)) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - CALL LAPACK_GEMM( 'N', 'T', 1.0_ReKi, p%MBM, p%PhiM, -1.0_ReKi, p%D1_14, ErrStat2, ErrMsg2 ) ! p%D1_14 = MATMUL( p%MBM, TRANSPOSE(p%PhiM) ) - p%D1_14 - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + ! D1 Matrices + ! MBmt*MmBt + CALL LAPACK_GEMM( 'N', 'T', 1.0_ReKi, p%MBM, p%MBM, 0.0_ReKi, p%MBmmB, ErrStat2, ErrMsg2 ); if(Failed()) return ! MATMUL( p%MBM, p%MMB ) + + ! --- Intermediates D1_14 = D1_141 + D1_142 + !p%D1_141 = MATMUL(p%MBM, TRANSPOSE(p%PhiM)) + CALL LAPACK_GEMM( 'N', 'T', 1.0_ReKi, p%MBM, p%PhiM, 0.0_ReKi, p%D1_141, ErrStat2, ErrMsg2 ); if(Failed()) return + ! NOTE: cant use LAPACK due to type conversions FEKi->ReKi + p%D1_142 =- MATMUL(TI_transpose, TRANSPOSE(PhiRb)) - - ! FY (with retained modes) - p%FY = MATMUL( p%MBM, p%FX ) & - - MATMUL( TI_transpose, ( FGRb + MATMUL( TRANSPOSE(PhiRb), FGL) ) ) ! C2_21, C2_42 ! C2_61, C2_62 - DO I = 1, p%Nmodes ! if (p%NModes=p%qmL=DOFM == 0), this loop is skipped - p%C2_61(:, i) = p%PhiM(:, i)*p%NOmegaM2(i) - p%C2_62(:, i) = p%PhiM(:, i)*p%N2OmegaMJDamp(i) + DO I = 1, p%nDOFM ! if (p%nDOFM=p%nDOFM=nDOFM == 0), this loop is skipped + p%C2_61(:, i) = -p%PhiM(:, i)*p%KMMDiag(i) + p%C2_62(:, i) = -p%PhiM(:, i)*p%CMMDiag(i) ENDDO ! D2_53, D2_63, D2_64 - p%D2_63 = MATMUL( p%PhiM, p%MMB ) - p%D2_63 = p%PhiRb_TI - p%D2_63 + !p%D2_63 = p%PhiRb_TI - MATMUL( p%PhiM, p%MMB ) + CALL LAPACK_GEMM( 'N', 'N', 1.0_ReKi, p%PhiM, p%MMB, 0.0_ReKi, p%D2_63, ErrStat2, ErrMsg2 ); if(Failed()) return; + p%D2_63 = - p%D2_63 ! NOTE: removed Guyan acceleration - !p%D2_64 = MATMUL( p%PhiM, p%PhiM_T ) !bjj: why does this use stack space? - CALL LAPACK_GEMM( 'N', 'T', 1.0_ReKi, p%PhiM, p%PhiM, 0.0_ReKi, p%D2_64, ErrStat2, ErrMsg2 ) !bjj: replaced MATMUL with this routine to avoid issues with stack size - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - ! F2_61 - p%F2_61 = MATMUL( p%D2_64, FGL ) + !p%D2_64 = MATMUL( p%PhiM, p%PhiM_T ) + CALL LAPACK_GEMM( 'N', 'T', 1.0_ReKi, p%PhiM, p%PhiM, 0.0_ReKi, p%D2_64, ErrStat2, ErrMsg2 ); if(Failed()) return; !Now calculate a Jacobian used when AM2 is called and store in parameters - IF (p%IntMethod .EQ. 4) THEN ! Allocate Jacobian if AM2 is requested & if there are states (p%qmL > 0) - n=2*p%qmL + IF (p%IntMethod .EQ. 4) THEN ! Allocate Jacobian if AM2 is requested & if there are states (p%nDOFM > 0) + n=2*p%nDOFM CALL AllocAry( p%AM2Jac, n, n, 'p%AM2InvJac', ErrStat2, ErrMsg2 ); if(Failed()) return CALL AllocAry( p%AM2JacPiv, n, 'p%AM2JacPiv', ErrStat2, ErrMsg2 ); if(Failed()) return ! First we calculate the Jacobian: ! (note the Jacobian is first stored as p%AM2InvJac) p%AM2Jac=0. - DO i=1,p%qmL - p%AM2Jac(i+p%qmL,i )=p%SDdeltaT/2.*p%NOmegaM2(i) !J21 - p%AM2Jac(i+p%qmL,i+p%qmL)=p%SDdeltaT/2.*p%N2OmegaMJDamp(i) !J22 -initialize + DO i=1,p%nDOFM + p%AM2Jac(i+p%nDOFM,i ) =-p%SDdeltaT/2.*p%KMMDiag(i) !J21 + p%AM2Jac(i+p%nDOFM,i+p%nDOFM)=-p%SDdeltaT/2.*p%CMMDiag(i) !J22 -initialize END DO - DO I=1,p%qmL + DO I=1,p%nDOFM p%AM2Jac(I,I)=-1. !J11 - p%AM2Jac(I,p%qmL+I)=p%SDdeltaT/2. !J12 - p%AM2Jac(p%qmL+I,p%qmL+I)=p%AM2Jac(p%qmL+I,p%qmL+I)-1 !J22 complete + p%AM2Jac(I,p%nDOFM+I)=p%SDdeltaT/2. !J12 + p%AM2Jac(p%nDOFM+I,p%nDOFM+I)=p%AM2Jac(p%nDOFM+I,p%nDOFM+I)-1 !J22 complete ENDDO ! Now need to factor it: !I think it could be improved and made more efficient if we can say the matrix is positive definite CALL LAPACK_getrf( n, n, p%AM2Jac, p%AM2JacPiv, ErrStat2, ErrMsg2); if(Failed()) return END IF + freq_max =maxval(OmegaL(1:p%nDOFM))/TwoPi + dt_max = 1/(20*freq_max) + !if (p%SDDeltaT>dt_max) then + ! print*,'info: time step may be too large compared to max SubDyn frequency.' + !endif + write(Info,'(3x,A,F8.5,A,F8.5,A,F8.5)') 'SubDyn recommended dt:',dt_max, ' - Current dt:', p%SDDeltaT,' - Max frequency:', freq_max + call WrScr(Info) ELSE ! no retained modes, so - ! OmegaM, JDampings, PhiM, MBM, MMB, FX , x don't exist in this case - ! p%F2_61, p%D2_64 are zero in this case so we simplify the equations in the code, omitting these variables + ! OmegaM, JDampings, PhiM, MBM, MMB, x don't exist in this case + ! p%D2_64 are zero in this case so we simplify the equations in the code, omitting these variables ! p%D2_63 = p%PhiRb_TI in this case so we simplify the equations in the code, omitting storage of this variable - ! p%D1_13 = p%MBB in this case so we simplify the equations in the code, omitting storage of this variable - - ! D1_14 (with 0 retained modes) - p%D1_14 = - MATMUL( TI_transpose, TRANSPOSE(PHiRb)) - - ! FY (with 0 retained modes) - p%FY = - MATMUL( TI_transpose, ( FGRb + MATMUL( TRANSPOSE(PhiRb), FGL) ) ) - + p%D1_141 = 0.0_ReKi + p%D1_142 = - MATMUL(TI_transpose, TRANSPOSE(PhiRb)) END IF CONTAINS @@ -2292,11 +2567,10 @@ END FUNCTION Failed END SUBROUTINE SetParameters !------------------------------------------------------------------------------------------------------ - !> Allocate parameter arrays, based on the dimensions already set in the parameter data type. -SUBROUTINE AllocParameters(p, DOFM, ErrStat, ErrMsg) +SUBROUTINE AllocParameters(p, nDOFM, ErrStat, ErrMsg) TYPE(SD_ParameterType), INTENT(INOUT) :: p ! Parameters - INTEGER(IntKi), INTENT( in) :: DOFM + INTEGER(IntKi), INTENT( in) :: nDOFM INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None ! local variables @@ -2306,44 +2580,30 @@ SUBROUTINE AllocParameters(p, DOFM, ErrStat, ErrMsg) ErrStat = ErrID_None ErrMsg = "" - ! for readability, we're going to keep track of the max ErrStat through SetErrStat() and not return until the end of this routine. - - CALL AllocAry( p%KBB, TPdofL, TPdofL, 'p%KBB', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%MBB, TPdofL, TPdofL, 'p%MBB', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%TI, p%DOFI, 6, 'p%TI', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%D1_14, TPdofL, p%DOFL, 'p%D1_14', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%FY, TPdofL, 'p%FY', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%PhiRb_TI, p%DOFL, TPdofL, 'p%PhiRb_TI', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - -if (p%Nmodes > 0 ) THEN - CALL AllocAry( p%MBM, TPdofL, DOFM, 'p%MBM', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%MMB, DOFM, TPdofL, 'p%MMB', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%NOmegaM2, DOFM, 'p%NOmegaM2', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%N2OmegaMJDamp, DOFM, 'p%N2OmegaMJDamp', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%FX, DOFM, 'p%FX', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%C1_11, TPdofL, DOFM, 'p%C1_11', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%C1_12, TPdofL, DOFM, 'p%C1_12', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%PhiM, p%DOFL, DOFM, 'p%PhiM', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%C2_61, p%DOFL, DOFM, 'p%C2_61', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%C2_62, p%DOFL, DOFM, 'p%C2_62', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%D1_13, TPdofL, TPdofL, 'p%D1_13', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') ! is p%MBB when p%NModes == 0 - CALL AllocAry( p%D2_63, p%DOFL, TPdofL, 'p%D2_63', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') ! is p%PhiRb_TI when p%NModes == 0 - CALL AllocAry( p%D2_64, p%DOFL, p%DOFL, 'p%D2_64', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') ! is zero when p%NModes == 0 - CALL AllocAry( p%F2_61, p%DOFL, 'p%F2_61', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') ! is zero when p%NModes == 0 + CALL AllocAry( p%KBB, nDOFL_TP, nDOFL_TP, 'p%KBB', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + CALL AllocAry( p%CBB, nDOFL_TP, nDOFL_TP, 'p%CBB', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + CALL AllocAry( p%MBB, nDOFL_TP, nDOFL_TP, 'p%MBB', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + CALL AllocAry( p%TI, p%nDOFI__, 6, 'p%TI', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + CALL AllocAry( p%D1_141, nDOFL_TP, p%nDOF__L,'p%D1_141', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + CALL AllocAry( p%D1_142, nDOFL_TP, p%nDOF__L,'p%D1_142', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + CALL AllocAry( p%PhiRb_TI, p%nDOF__L, nDOFL_TP,'p%PhiRb_TI', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + + +if (p%nDOFM > 0 ) THEN + CALL AllocAry( p%MBM, nDOFL_TP, nDOFM, 'p%MBM', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + CALL AllocAry( p%MMB, nDOFM, nDOFL_TP, 'p%MMB', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + CALL AllocAry( p%KMMDiag, nDOFM, 'p%KMMDiag', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + CALL AllocAry( p%CMMDiag, nDOFM, 'p%CMMDiag', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + CALL AllocAry( p%C1_11, nDOFL_TP, nDOFM, 'p%C1_11', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + CALL AllocAry( p%C1_12, nDOFL_TP, nDOFM, 'p%C1_12', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + CALL AllocAry( p%PhiM, p%nDOF__L, nDOFM, 'p%PhiM', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + CALL AllocAry( p%C2_61, p%nDOF__L, nDOFM, 'p%C2_61', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + CALL AllocAry( p%C2_62, p%nDOF__L, nDOFM, 'p%C2_62', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') + CALL AllocAry( p%MBmmB, nDOFL_TP, nDOFL_TP , 'p%MBmmB', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') ! is p%MBB when p%nDOFM == 0 + CALL AllocAry( p%D2_63, p%nDOF__L, nDOFL_TP, 'p%D2_63', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') ! is p%PhiRb_TI when p%nDOFM == 0 + CALL AllocAry( p%D2_64, p%nDOF__L, p%nDOF__L,'p%D2_64', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') ! is zero when p%nDOFM == 0 end if - - CALL AllocAry( p%IDI, p%DOFI, 'p%IDI', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%IDR, p%DOFR, 'p%IDR', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%IDL, p%DOFL, 'p%IDL', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%IDC, p%DOFC, 'p%IDC', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%IDY, p%DOFC+p%DOFI+p%DOFL, 'p%IDY', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') -if ( p%SttcSolve ) THEN - CALL AllocAry( p%PhiL_T, p%DOFL, p%DOFL, 'p%PhiL_T', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%PhiLInvOmgL2, p%DOFL, p%DOFL, 'p%PhiLInvOmgL2', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') - CALL AllocAry( p%FGL, p%DOFL, 'p%FGL', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocParameters') -end if - END SUBROUTINE AllocParameters !------------------------------------------------------------------------------------------------------ @@ -2361,157 +2621,515 @@ SUBROUTINE AllocMiscVars(p, Misc, ErrStat, ErrMsg) ErrMsg = "" ! for readability, we're going to keep track of the max ErrStat through SetErrStat() and not return until the end of this routine. - CALL AllocAry( Misc%UFL, p%DOFL, 'UFL', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') - CALL AllocAry( Misc%UR_bar, p%URbarL, 'UR_bar', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') - CALL AllocAry( Misc%UR_bar_dot, p%URbarL, 'UR_bar_dot', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') - CALL AllocAry( Misc%UR_bar_dotdot,p%URbarL, 'UR_bar_dotdot', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') - CALL AllocAry( Misc%UL, p%DOFL, 'UL', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') - CALL AllocAry( Misc%UL_dot, p%DOFL, 'UL_dot', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') - CALL AllocAry( Misc%UL_dotdot, p%DOFL, 'UL_dotdot', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + CALL AllocAry( Misc%F_L, p%nDOF__L, 'F_L', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + CALL AllocAry( Misc%UR_bar, p%nDOFI__, 'UR_bar', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') !TODO Rb + CALL AllocAry( Misc%UR_bar_dot, p%nDOFI__, 'UR_bar_dot', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') !TODO Rb + CALL AllocAry( Misc%UR_bar_dotdot,p%nDOFI__, 'UR_bar_dotdot', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') !TODO Rb + CALL AllocAry( Misc%UL, p%nDOF__L, 'UL', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + CALL AllocAry( Misc%UL_dot, p%nDOF__L, 'UL_dot', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + CALL AllocAry( Misc%UL_dotdot, p%nDOF__L, 'UL_dotdot', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + CALL AllocAry( Misc%DU_full, p%nDOF, 'DU_full', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + CALL AllocAry( Misc%U_full, p%nDOF, 'U_full', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + CALL AllocAry( Misc%U_full_elast, p%nDOF, 'U_full_elast', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + CALL AllocAry( Misc%U_full_dot, p%nDOF, 'U_full_dot', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + CALL AllocAry( Misc%U_full_dotdot,p%nDOF, 'U_full_dotdot', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + CALL AllocAry( Misc%U_red, p%nDOF_red, 'U_red', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + CALL AllocAry( Misc%U_red_dot, p%nDOF_red, 'U_red_dot', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + CALL AllocAry( Misc%U_red_dotdot, p%nDOF_red, 'U_red_dotdot', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + + CALL AllocAry( Misc%Fext, p%nDOF , 'm%Fext ', ErrStat2, ErrMsg2 );CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + CALL AllocAry( Misc%Fext_red, p%nDOF_red , 'm%Fext_red', ErrStat2, ErrMsg2 );CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') END SUBROUTINE AllocMiscVars !------------------------------------------------------------------------------------------------------ -!> Set the index arrays IDI, IDR, IDL, IDC, and IDY. -SUBROUTINE SetIndexArrays(Init, p, ErrStat, ErrMsg) - USE qsort_c_module, only: QsortC - - TYPE(SD_InitType), INTENT( IN) :: Init ! Input data for initialization routine - TYPE(SD_ParameterType), INTENT(INOUT) :: p ! Parameters - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None +!> Partition DOFs and Nodes into sets: +!! Nodes are partitioned into the I,C,L (and R) sets, Nodes_I, Nodes_C, Nodes_L, with: +!! I="Interface" nodes +!! C="Reaction" nodes +!! L=Interior nodes +!! R=I+C +!! DOFs indices are partitioned into B, F, L +!! B=Leader DOFs (Rbar in SubDyn documentation) +!! F=Fixed DOFS +!! L=Interior DOFs +!! Subpartitions of both categories use the convention: "NodePartition_DOFPartition" +!! e.g. C_F : "reaction" nodes DOFs that are fixed +!! C_L : "reaction" nodes DOFs that will be counted as internal +!! I_B : "interface" nodes DOFs that are leader DOFs +SUBROUTINE PartitionDOFNodes(Init, m, p, ErrStat, ErrMsg) + use IntegerList, only: len, concatenate_lists, lists_difference, concatenate_3lists, sort_in_place + type(SD_Inittype), intent( in) :: Init !< Input data for initialization routine + type(SD_MiscVartype), intent( in) :: m !< Misc + type(SD_Parametertype), intent(inout) :: p !< Parameters + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None ! local variables - INTEGER(IntKi) :: TempIDY(p%DOFC+p%DOFI+p%DOFL, 2) - INTEGER(IntKi) :: IDT(Init%TDOF) - INTEGER(IntKi) :: I, K ! counters + integer(IntKi) :: I, J, c_B, c_F, c_L, c__ ! counters + integer(IntKi) :: iNode, iiNode + integer(IntKi) :: nNodes_R + integer(IntKi), allocatable :: IDAll(:) + integer(IntKi), allocatable :: INodesAll(:) + integer(IntKi), allocatable :: Nodes_R(:) + integer(IntKi) :: ErrStat2 ! < Error status of the operation + character(ErrMsgLen) :: ErrMsg2 ErrStat = ErrID_None ErrMsg = "" - - ! Index IDI for interface DOFs - p%IDI = Init%IntFc(1:p%DOFI, 1) !RRD interface DOFs - - ! Index IDC for constraint DOFs - p%IDC = Init%BCs(1:p%DOFC, 1) !Constraint DOFs - - ! Index IDR for IDR DOFs - p%IDR( 1:p%DOFC ) = p%IDC ! Constraint DOFs again - p%IDR(p%DOFC+1:p%DOFR) = p%IDI ! IDR contains DOFs ofboundaries, constraints first then interface - - ! --- Index IDL for IDL DOFs - ! first set the total DOFs: - DO I = 1, Init%TDOF !Total DOFs - IDT(I) = I - ENDDO - ! remove DOFs on the boundaries: - DO I = 1, p%DOFR !Boundary DOFs (Interface + Constraints) - IDT(p%IDR(I)) = 0 !Set 0 wherever DOFs belong to boundaries - ENDDO - ! That leaves the internal DOFs: - K = 0 - DO I = 1, Init%TDOF - IF ( IDT(I) .NE. 0 ) THEN - K = K+1 - p%IDL(K) = IDT(I) !Internal DOFs - ENDIF - ENDDO - IF ( K /= p%DOFL ) THEN - ErrStat = ErrID_Fatal - ErrMsg = "SetIndexArrays: IDL or p%DOFL are the incorrect size." - RETURN - END IF - - ! --- Index IDY for all DOFs: - ! set the second column of the temp array - DO I = 1, SIZE(TempIDY,1) - TempIDY(I, 2) = I ! this column will become the returned "key" (i.e., the original location in the array) - ENDDO - ! set the first column of the temp array - TempIDY(1:p%DOFI, 1) = p%IDI - TempIDY(p%DOFI+1 : p%DOFI+p%DOFL, 1) = p%IDL - TempIDY(p%DOFI+p%DOFL+1: p%DOFI+p%DOFL+p%DOFC, 1) = p%IDC - ! sort based on the first column - CALL QsortC( TempIDY ) - ! the second column is the key: - p%IDY = TempIDY(:, 2) + ! --- Count nodes per types + p%nNodes_I = p%nNodes_I ! Number of interface nodes + nNodes_R = p%nNodes_I+p%nNodes_C ! I+C nodes + p%nNodes_L = p%nNodes - nNodes_R ! Number of Interior nodes + ! NOTE: some of the interior nodes may have no DOF if they are involved in a rigid assembly.. + + CALL AllocAry( p%Nodes_L, p%nNodes_L, 1, 'p%Nodes_L', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'PartitionDOFNodes') + CALL AllocAry( Nodes_R , nNodes_R , 'Nodes_R' , ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'PartitionDOFNodes') + + ! -------------------------------------------------------------------------------- + ! --- Partition Nodes: Nodes_L = IAll - NodesR + ! -------------------------------------------------------------------------------- + allocate(INodesAll(1:p%nNodes)); + do iNode=1,p%nNodes + INodesAll(iNode)=iNode + enddo + ! Nodes_R = [Nodes_C Nodes_I] + call concatenate_lists(p%Nodes_C(:,1), p%Nodes_I(:,1), Nodes_R, ErrStat2, ErrMsg2); if(Failed()) return + ! Nodes_L = IAll - Nodes_R + call lists_difference(INodesAll, Nodes_R, p%Nodes_L(:,1), ErrStat2, ErrMsg2); if(Failed()) return + + ! -------------------------------------------------------------------------------- + ! --- Count DOFs - NOTE: we count node by node + ! -------------------------------------------------------------------------------- + ! DOFs of interface nodes + p%nDOFI__ =0 ! Total + p%nDOFI_Rb=0 ! Leader + p%nDOFI_F =0 ! Fixed + do iiNode= 1,p%nNodes_I + p%nDOFI__ = p%nDOFI__ + len(p%NodesDOFred( p%Nodes_I(iiNode,1) )) + p%nDOFI_Rb= p%nDOFI_Rb+ count(p%Nodes_I(iiNode, 2:7)==idBC_Leader) ! assumes 6 DOFs + p%nDOFI_F = p%nDOFI_F + count(p%Nodes_I(iiNode, 2:7)==idBC_Fixed) ! assumes 6 DOFs + enddo + if (p%nDOFI__/=p%nDOFI_Rb+p%nDOFI_F) then + call Fatal('Error in distributing interface DOFs, total number of interface DOF('//num2lstr(p%nDOFI__)//') does not equal sum of: leader ('//num2lstr(p%nDOFI_Rb)//'), fixed ('//num2lstr(p%nDOFI_F)//')'); return + endif + + ! DOFs of reaction nodes + p%nDOFC__ =0 ! Total + p%nDOFC_Rb=0 ! Leader + p%nDOFC_F =0 ! Fixed + p%nDOFC_L =0 ! Internal + do iiNode= 1,p%nNodes_C + p%nDOFC__ = p%nDOFC__ + len(p%NodesDOFred( p%Nodes_C(iiNode,1) )) + p%nDOFC_Rb= p%nDOFC_Rb+ count(p%Nodes_C(iiNode, 2:7)==idBC_Leader) ! assumes 6 DOFs + p%nDOFC_F = p%nDOFC_F + count(p%Nodes_C(iiNode, 2:7)==idBC_Fixed ) ! assumes 6 DOFs + p%nDOFC_L = p%nDOFC_L + count(p%Nodes_C(iiNode, 2:7)==idBC_Internal) ! assumes 6 DOFs + enddo + if (p%nDOFC__/=p%nDOFC_Rb+p%nDOFC_F+p%nDOFC_L) then + call Fatal('Error in distributing reaction DOFs, total number of reaction DOF('//num2lstr(p%nDOFC__)//') does not equal sum of: leader ('//num2lstr(p%nDOFC_Rb)//'), fixed ('//num2lstr(p%nDOFC_F)//'), internal ('//num2lstr(p%nDOFC_L)//')'); return + endif + ! DOFs of reaction + interface nodes + p%nDOFR__ = p%nDOFI__ + p%nDOFC__ ! Total number, used to be called "nDOFR" + + ! DOFs of internal nodes + p%nDOFL_L=0 + do iiNode= 1,p%nNodes_L + p%nDOFL_L = p%nDOFL_L + len(p%NodesDOFred( p%Nodes_L(iiNode,1) )) + enddo + if (p%nDOFL_L/=p%nDOF_red-p%nDOFR__) then + call Fatal('Error in distributing internal DOFs, total number of internal DOF('//num2lstr(p%nDOFL_L)//') does not equal total number of DOF('//num2lstr(p%nDOF_red)//') minus interface and reaction ('//num2lstr(p%nDOFR__)//')'); return + endif + + ! Total number of DOFs in each category: + p%nDOF__Rb = p%nDOFC_Rb + p%nDOFI_Rb ! OK, generic + p%nDOF__F = p%nDOFC_F + p%nDOFI_F ! OK, generic + p%nDOF__L = p%nDOFC_L + p%nDOFL_L ! OK, generic + + ! --- Safety checks ! TODO: these checks are temporary! + if (p%nDOFI_Rb /= p%nNodes_I*6) then + call Fatal('Wrong number of DOF for interface nodes, likely some interface nodes are special joints or are fixed'); return + endif + + ! Set the index arrays + CALL AllocAry( p%IDI__, p%nDOFI__, 'p%IDI__', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'PartitionDOFNodes') + CALL AllocAry( p%IDI_Rb,p%nDOFI_Rb, 'p%IDI_Rb',ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'PartitionDOFNodes') + CALL AllocAry( p%IDI_F, p%nDOFI_F, 'p%IDI_F', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'PartitionDOFNodes') + CALL AllocAry( p%IDC__, p%nDOFC__, 'p%IDC__', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'PartitionDOFNodes') + CALL AllocAry( p%IDC_Rb,p%nDOFC_Rb, 'p%IDC_Rb',ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'PartitionDOFNodes') + CALL AllocAry( p%IDC_F, p%nDOFC_F, 'p%IDC_F', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'PartitionDOFNodes') + CALL AllocAry( p%IDC_L, p%nDOFC_L, 'p%IDC_L', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'PartitionDOFNodes') + CALL AllocAry( p%IDL_L, p%nDOFL_L, 'p%IDL_L', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'PartitionDOFNodes') + CALL AllocAry( p%IDR__, p%nDOFR__, 'p%IDR__', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'PartitionDOFNodes') + CALL AllocAry( p%ID__Rb,p%nDOF__Rb, 'p%ID__Rb',ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'PartitionDOFNodes') + CALL AllocAry( p%ID__F, p%nDOF__F, 'p%ID__F', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'PartitionDOFNodes') + CALL AllocAry( p%ID__L, p%nDOF__L, 'p%ID__L', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'PartitionDOFNodes') ! TODO TODO + if(Failed()) return + + ! -------------------------------------------------------------------------------- + ! --- Distibutes the I, L, C nodal DOFs into B, F, L sub-categories + ! -------------------------------------------------------------------------------- + + ! Distribute the interface DOFs into R,F + c__=0; c_B=0; c_F=0 ! Counters over R and F dofs + do iiNode= 1,p%nNodes_I !Loop on interface nodes + iNode = p%Nodes_I(iiNode,1) + do J = 1, 6 ! DOFs: ItfTDXss ItfTDYss ItfTDZss ItfRDXss ItfRDYss ItfRDZss + c__=c__+1 + p%IDI__(c__) = p%NodesDOFred(iNode)%List(J) ! DOF number + if (p%Nodes_I(iiNode, J+1)==idBC_Leader) then + c_B=c_B+1 + p%IDI_Rb(c_B) = p%NodesDOFred(iNode)%List(J) ! DOF number + + elseif (p%Nodes_I(iiNode, J+1)==idBC_Fixed) then ! + c_F=c_F+1 + p%IDI_F(c_F) = p%NodesDOFred(iNode)%List(J) ! DOF number + endif + enddo + enddo + ! Indices IDI__ = [IDI_B, IDI_F], interface + !call concatenate_lists(p%IDI_Rb, p%IDI_F, p%IDI__, ErrStat2, ErrMsg2); if(Failed()) return + + ! Distribute the reaction DOFs into R,F,L + c__=0; c_B=0; c_F=0; c_L=0; ! Counters over R, F, L dofs + do iiNode= 1,p%nNodes_C !Loop on interface nodes + iNode = p%Nodes_C(iiNode,1) + do J = 1, 6 ! DOFs + c__=c__+1 + p%IDC__(c__) = p%NodesDOFred(iNode)%List(J) ! DOF number + if (p%Nodes_C(iiNode, J+1)==idBC_Leader) then + c_B=c_B+1 + p%IDC_Rb(c_B) = p%NodesDOFred(iNode)%List(J) ! DOF number + + elseif (p%Nodes_C(iiNode, J+1)==idBC_Fixed) then ! + c_F=c_F+1 + p%IDC_F(c_F) = p%NodesDOFred(iNode)%List(J) ! DOF number + + elseif (p%Nodes_C(iiNode, J+1)==idBC_Internal) then ! + c_L=c_L+1 + p%IDC_L(c_L) = p%NodesDOFred(iNode)%List(J) ! DOF number + endif + enddo + enddo + ! Indices IDC__ = [IDC_B, IDC_F, IDC_L], interface + !call concatenate_3lists(p%IDC_Rb, p%IDC_F, p%IDC_L, p%IDC__, ErrStat2, ErrMsg2); if(Failed()) return + !call sort_in_place(p%IDC__) + + + ! Indices IDR__ = [IDI__, IDC__], interface + !call concatenate_lists(p%IDI__, p%IDC__, p%IDR__, ErrStat2, ErrMsg2); if(Failed()) return + ! TODO, NOTE: Backward compatibility [IDC, IDI] + call concatenate_lists(p%IDC__, p%IDI__, p%IDR__, ErrStat2, ErrMsg2); if(Failed()) return + + ! Distribute the internal DOFs + c_L=0; ! Counters over L dofs + do iiNode= 1,p%nNodes_L !Loop on interface nodes + iNode = p%Nodes_L(iiNode,1) + do J = 1, size(p%NodesDOFred(iNode)%List) ! DOFs + c_L=c_L+1 + p%IDL_L(c_L) = p%NodesDOFred(iNode)%List(J) ! DOF number + enddo + enddo + + ! -------------------------------------------------------------------------------- + ! --- Total indices per partition B, F, L + ! -------------------------------------------------------------------------------- + ! Indices ID__Rb = [IDC_B, IDI_B], retained/leader DOFs + call concatenate_lists(p%IDC_Rb, p%IDI_Rb, p%ID__Rb, ErrStat2, ErrMsg2); if(Failed()) return + ! Indices ID__F = [IDC_F, IDI_F], fixed DOFs + call concatenate_lists(p%IDC_F, p%IDI_F, p%ID__F, ErrStat2, ErrMsg2); if(Failed()) return + ! Indices ID__L = [IDL_L, IDC_L], internal DOFs + call concatenate_lists(p%IDL_L, p%IDC_L, p%ID__L, ErrStat2, ErrMsg2); if(Failed()) return + + ! --- Check that partition is complete + if (any(p%ID__Rb<=0)) then + call Fatal('R - Partioning incorrect.'); return + elseif (any(p%ID__F<=0)) then + call Fatal('F - Partioning incorrect.'); return + elseif (any(p%ID__L<=0)) then + call Fatal('L - Partioning incorrect.'); return + endif + allocate(IDAll(1:p%nDOF_red)) + call concatenate_3lists(p%ID__Rb, p%ID__L, p%ID__F, IDAll, ErrStat2, ErrMsg2); if(Failed()) return + call sort_in_place(IDAll) + do I = 1, p%nDOF_red + if (IDAll(I)/=I) then + call Fatal('DOF '//trim(Num2LStr(I))//' missing, problem in R, L F partitioning'); return + endif + enddo + + if(DEV_VERSION) then + write(*,'(A,I0)')'Number of DOFs: "interface" (I__): ',p%nDOFI__ + write(*,'(A,I0)')'Number of DOFs: "interface" retained (I_B): ',p%nDOFI_Rb + write(*,'(A,I0)')'Number of DOFs: "interface" fixed (I_F): ',p%nDOFI_F + write(*,'(A,I0)')'Number of DOFs: "reactions" (C__): ',p%nDOFC__ + write(*,'(A,I0)')'Number of DOFs: "reactions" retained (C_B): ',p%nDOFC_Rb + write(*,'(A,I0)')'Number of DOFs: "reactions" internal (C_L): ',p%nDOFC_L + write(*,'(A,I0)')'Number of DOFs: "reactions" fixed (C_F): ',p%nDOFC_F + write(*,'(A,I0)')'Number of DOFs: "intf+react" (__R): ',p%nDOFR__ + write(*,'(A,I0)')'Number of DOFs: "internal" internal (L_L): ',p%nDOFL_L + write(*,'(A,I0)')'Number of DOFs: retained (__B): ',p%nDOF__Rb + write(*,'(A,I0)')'Number of DOFs: internal (__L): ',p%nDOF__L + write(*,'(A,I0)')'Number of DOFs: fixed (__F): ',p%nDOF__F + write(*,'(A,I0)')'Number of DOFs: total : ',p%nDOF_red + write(*,'(A,I0)')'Number of Nodes: "interface" (I): ',p%nNodes_I + write(*,'(A,I0)')'Number of Nodes: "reactions" (C): ',p%nNodes_C + write(*,'(A,I0)')'Number of Nodes: "internal" (L): ',p%nNodes_L + write(*,'(A,I0)')'Number of Nodes: total (I+C+L): ',p%nNodes + endif + + call CleanUp() + +contains + LOGICAL FUNCTION Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'PartitionDOFNodes') + Failed = ErrStat >= AbortErrLev + if (Failed) call CleanUp() + END FUNCTION Failed + SUBROUTINE Fatal(ErrMsg_in) + character(len=*), intent(in) :: ErrMsg_in + CALL SetErrStat(ErrID_Fatal, ErrMsg_in, ErrStat, ErrMsg, 'PartitionDOFNodes'); + CALL CleanUp() + END SUBROUTINE Fatal + SUBROUTINE CleanUp() + if(allocated(INodesAll)) deallocate(INodesAll) + if(allocated(IDAll)) deallocate(IDAll) + if(allocated(Nodes_R)) deallocate(Nodes_R) + END SUBROUTINE CleanUp -END SUBROUTINE SetIndexArrays +END SUBROUTINE PartitionDOFNodes + +!> Compute displacements of all nodes in global system (Guyan + Rotated CB) +!! +SUBROUTINE LeverArm(u, p, x, m, DU_full, bGuyan, bElastic, U_full) + TYPE(SD_InputType), INTENT(IN ) :: u !< Inputs at t + TYPE(SD_ParameterType),target,INTENT(IN ) :: p !< Parameters + TYPE(SD_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at t + TYPE(SD_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables + LOGICAL, INTENT(IN ) :: bGuyan !< include Guyan Contribution + LOGICAL, INTENT(IN ) :: bElastic !< include Elastic contribution + REAL(ReKi), DIMENSION(:), INTENT( OUT) :: DU_full !< LeverArm in full system + REAL(ReKi), DIMENSION(:), OPTIONAL, INTENT(IN ) :: U_full !< Displacements in full system + !locals + INTEGER(IntKi) :: iSDNode + REAL(ReKi) :: rotations(3) + INTEGER(IntKi), pointer :: DOFList(:) + ! Variables for Guyan rigid body motion + real(ReKi), dimension(3) :: rIP ! Vector from TP to rotated Node + real(ReKi), dimension(3) :: rIP0 ! Vector from TP to Node (undeflected) + real(ReKi), dimension(3) :: duP ! Displacement of node due to rigid rotation + real(R8Ki), dimension(3,3) :: Rb2g ! Rotation matrix body 2 global coordinates + INTEGER(IntKi) :: ErrStat2 ! Error status of the operation (occurs after initial error) + CHARACTER(ErrMsgLen) :: ErrMsg2 ! Error message if ErrStat2 /= ErrID_None + ! --- Convert inputs to FEM DOFs and convenient 6-vector storage + ! Compute the small rotation angles given the input direction cosine matrix + rotations = GetSmllRotAngs(u%TPMesh%Orientation(:,:,1), ErrStat2, Errmsg2); + m%u_TP = (/REAL(u%TPMesh%TranslationDisp(:,1),ReKi), rotations/) + + if (present(U_full)) then + ! Then we use it directly, U_full may contain Static improvement + DU_full=U_full + ! We remove u_TP for floating + if (p%Floating) then + do iSDNode = 1,p%nNodes + DOFList => p%NodesDOF(iSDNode)%List ! Alias to shorten notations + DU_full(DOFList(1:3)) = DU_full(DOFList(1:3)) - m%u_TP(1:3) + enddo + endif + else + ! --- CB modes contribution to motion (L-DOF only), NO STATIC IMPROVEMENT + if (bElastic .and. p%nDOFM > 0) then + m%UL = matmul( p%PhiM, x%qm ) + else + m%UL = 0.0_ReKi + end if + ! --- Adding Guyan contribution to R and L DOFs + if (bGuyan .and. .not.p%Floating) then + m%UR_bar = matmul( p%TI , m%u_TP ) + m%UL = m%UL + matmul( p%PhiRb_TI, m%u_TP ) + else + ! Guyan modes are rigid body modes, we will add them in the "Full system" later + m%UR_bar = 0.0_ReKi + endif + ! --- Build original DOF vectors (DOF before the CB reduction) + m%U_red(p%IDI__) = m%UR_bar + m%U_red(p%ID__L) = m%UL + m%U_red(p%IDC_Rb)= 0 ! NOTE: for now we don't have leader DOF at "C" (bottom) + m%U_red(p%ID__F) = 0 + if (p%reduced) then + DU_full = matmul(p%T_red, m%U_red) + else + DU_full = m%U_red + endif + ! --- Adding Guyan contribution for rigid body + if (bGuyan .and. p%Floating) then + ! For floating, we compute the Guyan motion directly (rigid body motion with TP as origin) + ! This introduce non-linear "rotations" effects, where the bottom node should "go up", and not just translate horizontally + Rb2g(1:3,1:3) = transpose(u%TPMesh%Orientation(:,:,1)) + do iSDNode = 1,p%nNodes + DOFList => p%NodesDOF(iSDNode)%List ! Alias to shorten notations + ! --- Guyan (rigid body) motion in global coordinates + rIP0(1:3) = p%DP0(1:3, iSDNode) + rIP(1:3) = matmul(Rb2g, rIP0) + duP(1:3) = rIP - rIP0 ! NOTE: without m%u_TP(1:3) + ! Full diplacements Guyan + rotated CB (if asked) >>> Rotate All + if (p%GuyanLoadCorrection) then + DU_full(DOFList(1:3)) = matmul(Rb2g, DU_full(DOFList(1:3))) + duP(1:3) + DU_full(DOFList(4:6)) = matmul(Rb2g, DU_full(DOFList(4:6))) + rotations(1:3) + else + DU_full(DOFList(1:3)) = DU_full(DOFList(1:3)) + duP(1:3) + DU_full(DOFList(4:6)) = DU_full(DOFList(4:6)) + rotations(1:3) + endif + enddo + endif + endif ! U_full no provided +END SUBROUTINE LeverArm !------------------------------------------------------------------------------------------------------ -!> -SUBROUTINE Test_CB_Results(MBBt, MBMt, KBBt, OmegaM, DOFTP, DOFM, ErrStat, ErrMsg,Init,p) - TYPE(SD_InitType), INTENT( in) :: Init ! Input data for initialization routine - TYPE(SD_ParameterType), INTENT(inout) :: p ! Parameters - INTEGER(IntKi) :: DOFTP, DOFM - REAL(ReKi) :: MBBt(DOFTP, DOFTP) - REAL(ReKi) :: MBmt(DOFTP, DOFM) - REAL(ReKi) :: KBBt(DOFTP, DOFTP) - REAL(ReKi) :: OmegaM(DOFM) - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - ! local variables - INTEGER(IntKi) :: DOFT, NM, i - REAL(ReKi), Allocatable :: OmegaCB(:), PhiCB(:, :) - REAL(ReKi), Allocatable :: K(:, :) - REAL(ReKi), Allocatable :: M(:, :) - Character(1024) :: rootname - ErrStat = ErrID_None - ErrMsg = '' - - DOFT = DOFTP + DOFM - NM = DOFT - 3 - Allocate( OmegaCB(NM), K(DOFT, DOFT), M(DOFT, DOFT), PhiCB(DOFT, NM) ) - K = 0.0 - M = 0.0 - OmegaCB = 0.0 - PhiCB = 0.0 - - M(1:DOFTP, 1:DOFTP) = MBBt - M(1:DOFTP, (DOFTP+1):DOFT ) = MBMt - M((DOFTP+1):DOFT, 1:DOFTP ) = transpose(mbmt) +!> Construct force vector on internal DOF (L) from the values on the input mesh +!! First, the full vector of external forces is built on the non-reduced DOF +!! Then, the vector is reduced using the Tred matrix +SUBROUTINE GetExtForceOnInternalDOF(u, p, x, m, F_L, ErrStat, ErrMsg, GuyanLoadCorrection, RotateLoads, U_full) + type(SD_InputType), intent(in ) :: u ! Inputs + type(SD_ParameterType), intent(in ) :: p ! Parameters + type(SD_ContinuousStateType), intent(in ) :: x !< Continuous states at t + type(SD_MiscVarType), intent(inout) :: m ! Misc, for storage optimization of Fext and Fext_red + logical , intent(in ) :: GuyanLoadCorrection ! If true add extra moment + logical , intent(in ) :: RotateLoads ! If true, loads are rotated to body coordinate + real(Reki), optional, intent(in ) :: U_full(:) ! DOF displacements (Guyan + CB) + real(ReKi) , intent(out) :: F_L(p%nDOF__L) !< External force on internal nodes "L" + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + integer :: iNode ! indices of u-mesh nodes and SD nodes + integer :: nMembers + integer :: I + integer :: iCC, iElem, iChannel !< Index on control cables, element, Channel + integer(IntKi), dimension(12) :: IDOF ! 12 DOF indices in global unconstrained system + real(ReKi) :: CableTension ! Controllable Cable force + real(ReKi) :: rotations(3) + real(ReKi) :: du(3), Moment(3), Force(3) + real(ReKi) :: u_TP(6) + ! Variables for Guyan Rigid motion + real(ReKi), dimension(3) :: rIP ! Vector from TP to rotated Node + real(ReKi), dimension(3) :: rIP0 ! Vector from TP to Node (undeflected) + real(ReKi), dimension(3) :: duP ! Displacement of node due to rigid rotation + real(R8Ki), dimension(3,3) :: Rb2g ! Rotation matrix body 2 global + real(R8Ki), dimension(3,3) :: Rg2b ! Rotation matrix global 2 body coordinates + ! + real(ReKi), parameter :: myNaN = -9999998.989_ReKi + + if (GuyanLoadCorrection) then + ! Compute node displacements "DU_full" for lever arm + call LeverArm(u, p, x, m, m%DU_full, bGuyan=.True., bElastic=.False., U_full=U_full) + endif + + ! --- Build vector of external forces (including gravity) (Moment done below) + m%Fext= myNaN + if (RotateLoads) then ! Forces in body coordinates + Rg2b(1:3,1:3) = u%TPMesh%Orientation(:,:,1) ! global 2 body coordinates + do iNode = 1,p%nNodes + m%Fext( p%NodesDOF(iNode)%List(1:3) ) = matmul(Rg2b, u%LMesh%Force(:,iNode) + p%FG(p%NodesDOF(iNode)%List(1:3))) + enddo + else ! Forces in global + do iNode = 1,p%nNodes + m%Fext( p%NodesDOF(iNode)%List(1:3) ) = u%LMesh%Force(:,iNode) + p%FG(p%NodesDOF(iNode)%List(1:3)) + enddo + endif + + ! --- Adding controllable cable forces + if (size(p%CtrlElem2Channel,1) > 0) then + if (.not. allocated (u%CableDeltaL)) then + call Fatal('Cable tension input not allocated but controllable cables are present'); return + endif + if (size(u%CableDeltaL)< maxval(p%CtrlElem2Channel(:,2)) ) then + call Fatal('Cable tension input has length '//trim(num2lstr(size(u%CableDeltaL)))//' but controllable cables need to access channel '//trim(num2lstr(maxval(p%CtrlElem2Channel(:,2))))); return + endif + do iCC = 1, size(p%CtrlElem2Channel,1) ! Loop on controllable cables + iElem = p%CtrlElem2Channel(iCC,1) + iChannel = p%CtrlElem2Channel(iCC,2) + IDOF = p%ElemsDOF(1:12, iElem) + ! T(t) = - EA * DeltaL(t) /(Le + Delta L(t)) ! NOTE DeltaL<0 + CableTension = -p%ElemProps(iElem)%YoungE*p%ElemProps(iElem)%Area * u%CableDeltaL(iChannel) / (p%ElemProps(iElem)%Length + u%CableDeltaL(iChannel)) + print*,'TODO, Controllable pretension cable needs thinking for moment' + STOP + !if (RotateLoads) then ! in body coordinate + ! m%Fext(IDOF) = m%Fext(IDOF) + matmul(Rg2b,m%FC_unit( IDOF ) * (CableTension - p%ElemProps(iElem)%T0)) + !else ! in global + ! m%Fext(IDOF) = m%Fext(IDOF) + m%FC_unit( IDOF ) * (CableTension - p%ElemProps(iElem)%T0) + !endif + enddo + endif + + ! --- Build vector of external moment + do iNode = 1,p%nNodes + Force(1:3) = m%Fext(p%NodesDOF(iNode)%List(1:3) ) ! Controllable cable + External Forces on LMesh + ! Moment ext + gravity + if (RotateLoads) then + ! In body coordinates + Moment(1:3) = matmul(Rg2b, u%LMesh%Moment(1:3,iNode) + p%FG(p%NodesDOF(iNode)%List(4:6))) + else + Moment(1:3) = u%LMesh%Moment(1:3,iNode) + p%FG(p%NodesDOF(iNode)%List(4:6)) + endif - DO i = 1, DOFM - K(DOFTP+i, DOFTP+i) = OmegaM(i)*OmegaM(i) - M(DOFTP+i, DOFTP+i) = 1.0 - ENDDO - - K(1:DOFTP, 1:DOFTP) = KBBt + ! Extra moment dm = Delta u x (fe + fg) + if (GuyanLoadCorrection) then + du = m%DU_full(p%NodesDOF(iNode)%List(1:3)) ! Lever arm + Moment(1) = Moment(1) + du(2) * Force(3) - du(3) * Force(2) + Moment(2) = Moment(2) + du(3) * Force(1) - du(1) * Force(3) + Moment(3) = Moment(3) + du(1) * Force(2) - du(2) * Force(1) + endif - ! temporary rootname - rootname = './test_assemble_C-B_out' - - CALL EigenSolve(K, M, DOFT, NM,.False.,Init,p, PhiCB, OmegaCB, ErrStat, ErrMsg) - IF ( ErrStat /= 0 ) RETURN + ! Moment is spread equally across all rotational DOFs if more than 3 rotational DOFs + nMembers = (size(p%NodesDOF(iNode)%List)-3)/3 ! Number of members deducted from Node's DOFList + m%Fext( p%NodesDOF(iNode)%List(4::3)) = Moment(1)/nMembers + m%Fext( p%NodesDOF(iNode)%List(5::3)) = Moment(2)/nMembers + m%Fext( p%NodesDOF(iNode)%List(6::3)) = Moment(3)/nMembers + enddo + + ! TODO: remove test below in the future + if (DEV_VERSION) then + if (any(m%Fext == myNaN)) then + print*,'Error in setting up Fext' + STOP + endif + endif -END SUBROUTINE Test_CB_Results + ! --- Reduced vector of external force + if (p%reduced) then + m%Fext_red = matmul(p%T_red_T, m%Fext) + F_L= m%Fext_red(p%ID__L) + else + F_L= m%Fext(p%ID__L) + endif + +contains + subroutine Fatal(ErrMsg_in) + character(len=*), intent(in) :: ErrMsg_in + call SetErrStat(ErrID_Fatal, ErrMsg_in, ErrStat, ErrMsg, 'GetExtForce'); + end subroutine Fatal +END SUBROUTINE GetExtForceOnInternalDOF !------------------------------------------------------------------------------------------------------ -!> Take the input u LMesh and constructs the appropriate corresponding UFL vector -SUBROUTINE ConstructUFL( u, p, UFL ) - TYPE(SD_InputType), INTENT(IN ) :: u ! Inputs - TYPE(SD_ParameterType), INTENT(IN ) :: p ! Parameters - REAL(ReKi) :: UFL(p%DOFL) - INTEGER :: I, J, StartDOF ! integers for indexing into mesh and UFL - - ! note that p%DOFL = p%NNodes_L*6 - DO I = 1, p%NNodes_L !Only interior nodes here - ! starting index in the master arrays for the current node - startDOF = (I-1)*6 + 1 - ! index into the Y2Mesh - J = p%NNodes_I + I - ! Construct UFL array from the Force and Moment fields of the input mesh - UFL ( startDOF : startDOF + 2 ) = u%LMesh%Force (:,J) - UFL ( startDOF+3 : startDOF + 5 ) = u%LMesh%Moment(:,J) - END DO - -END SUBROUTINE +!> Construct force vector on interface DOF (I) +!! NOTE: This function should only be called after GetExtForceOnInternalDOF +SUBROUTINE GetExtForceOnInterfaceDOF( p, Fext, F_I) + type(SD_ParameterType), intent(in ) :: p ! Parameters + real(ReKi), dimension(:), intent(in ) :: Fext !< Vector of external forces on un-reduced DOF + real(ReKi) , intent(out ) :: F_I(6*p%nNodes_I) !< External force on interface DOF + integer :: iSDNode, startDOF, I + DO I = 1, p%nNodes_I + iSDNode = p%Nodes_I(I,1) + startDOF = (I-1)*6 + 1 ! NOTE: for now we have 6 DOF per interface nodes + F_I(startDOF:startDOF+5) = Fext(p%NodesDOF(iSDNode)%List(1:6)) !TODO try to use Fext_red + ENDDO +END SUBROUTINE GetExtForceOnInterfaceDOF !------------------------------------------------------------------------------------------------------ !> Output the summary file -SUBROUTINE OutSummary(Init, p, FEMparams,CBparams, ErrStat,ErrMsg) - TYPE(SD_InitType), INTENT(IN) :: Init ! Input data for initialization routine, this structure contains many variables needed for summary file - TYPE(SD_ParameterType), INTENT(IN) :: p ! Parameters,this structure contains many variables needed for summary file +SUBROUTINE OutSummary(Init, p, m, InitInput, CBparams, ErrStat,ErrMsg) + use Yaml + TYPE(SD_InitType), INTENT(INOUT) :: Init ! Input data for initialization routine + TYPE(SD_ParameterType), INTENT(IN) :: p ! Parameters + TYPE(SD_MiscVarType) , INTENT(IN) :: m ! Misc + TYPE(SD_InitInputType), INTENT(IN) :: InitInput !< Input data for initialization routine TYPE(CB_MatArrays), INTENT(IN) :: CBparams ! CB parameters that will be passed in for summary file use - TYPE(FEM_MatArrays), INTENT(IN) :: FEMparams ! FEM parameters that will be passed in for summary file use INTEGER(IntKi), INTENT(OUT) :: ErrStat ! Error status of the operation CHARACTER(*), INTENT(OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None !LOCALS @@ -2519,88 +3137,212 @@ SUBROUTINE OutSummary(Init, p, FEMparams,CBparams, ErrStat,ErrMsg) INTEGER(IntKi) :: ErrStat2 ! Temporary storage for local errors CHARACTER(ErrMsgLen) :: ErrMsg2 ! Temporary storage for local errors CHARACTER(1024) :: SummaryName ! name of the SubDyn summary file - INTEGER(IntKi) :: i, j, k, propids(2) !counter and temporary holders - INTEGER(IntKi) :: SDtoMeshIndx(Init%NNode) - REAL(ReKi) :: MRB(6,6) !REDUCED SYSTEM Kmatrix, equivalent mass matrix - REAL(ReKi) :: XYZ1(3),XYZ2(3), DirCos(3,3), mlength !temporary arrays, member i-th direction cosine matrix (global to local) and member length - CHARACTER(*),PARAMETER :: SectionDivide = '____________________________________________________________________________________________________' - CHARACTER(*),PARAMETER :: SubSectionDivide = '__________' - CHARACTER(2), DIMENSION(6), PARAMETER :: MatHds= (/'X ', 'Y ', 'Z ', 'XX', 'YY', 'ZZ'/) !Headers for the columns and rows of 6x6 matrices - + INTEGER(IntKi) :: i, j, k, propIDs(2), Iprop(2) !counter and temporary holders + INTEGER(IntKi) :: iNode1, iNode2 ! Node indices + INTEGER(IntKi) :: mType ! Member Type + Real(ReKi) :: mMass, mLength ! Member mass and length + REAL(ReKi) :: MRB(6,6) ! REDUCED SYSTEM Kmatrix, equivalent mass matrix + REAL(FEKi),allocatable :: MBB(:,:) ! Leader DOFs mass matrix + REAL(ReKi) :: XYZ1(3),XYZ2(3) !temporary arrays + REAL(FEKi) :: DirCos(3,3) ! direction cosine matrix (global to local) + CHARACTER(*),PARAMETER :: SectionDivide = '#____________________________________________________________________________________________________' + real(ReKi), dimension(:,:), allocatable :: TI2 ! For Equivalent mass matrix + real(FEKi) :: Ke(12,12), Me(12, 12), FCe(12), FGe(12) ! element stiffness and mass matrices gravity force vector + real(ReKi), dimension(:,:), allocatable :: DummyArray ! + ! Variables for Eigenvalue analysis + integer(IntKi) :: nOmega + real(FEKi), dimension(:,:), allocatable :: Modes + real(R8Ki), dimension(:,:), allocatable :: AA, BB, CC, DD ! Linearization matrices + real(FEKi), dimension(:) , allocatable :: Omega + logical, allocatable :: bDOF(:) ! Mask for DOF to keep (True), or reduce (False) + character(len=*),parameter :: ReFmt='ES15.6E2' + character(len=*),parameter :: SFmt='A15,1x' ! Need +1 for comma compared to ReFmt + character(len=*),parameter :: IFmt='I7' + ! ErrStat = ErrID_None ErrMsg = "" - - CALL SD_Y2Mesh_Mapping(p, SDtoMeshIndx ) + + ! --- Eigen values of full system (for summary file output only) + ! We call the EigenSolver here only so that we get a print-out the eigenvalues from the full system (minus Reaction DOF) + ! M and K are reduced matrices, but Boundary conditions are not applied + ! We set bDOF, which is true if not a fixed Boundary conditions + ! NOTE: we don't check for singularities/rigig body modes here + CALL WrScr(' Calculating Full System Modes for summary file') + CALL AllocAry(bDOF, p%nDOF_red, 'bDOF', ErrStat2, ErrMsg2); if(Failed()) return + bDOF(:) = .true. + bDOF(p%ID__F) = .false. + nOmega = count(bDOF) + CALL AllocAry(Omega, nOmega, 'Omega', ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(Modes, p%nDOF_red, nOmega, 'Modes', ErrStat2, ErrMsg2); if(Failed()) return + call EigenSolveWrap(Init%K, Init%M, p%nDOF_red, nOmega, .False., Modes, Omega, ErrStat2, ErrMsg2, bDOF); if(Failed()) return + IF (ALLOCATED(bDOF) ) DEALLOCATE(bDOF) !------------------------------------------------------------------------------------------------------------- ! open txt file !------------------------------------------------------------------------------------------------------------- - SummaryName = TRIM(Init%RootName)//'.sum' + SummaryName = TRIM(Init%RootName)//'.sum.yaml' UnSum = -1 ! we haven't opened the summary file, yet. - CALL SDOut_OpenSum( UnSum, SummaryName, SD_ProgDesc, ErrStat2, ErrMsg2 ) - CALL SetErrStat ( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SD_Init' ) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE(UnSum) - RETURN - END IF - + CALL SDOut_OpenSum( UnSum, SummaryName, SD_ProgDesc, ErrStat2, ErrMsg2 ); if(Failed()) return !------------------------------------------------------------------------------------------------------------- ! write discretized data to a txt file !------------------------------------------------------------------------------------------------------------- !bjj: for debugging, i recommend using the p% versions of all these variables whenever possible in this summary file: ! (it helps in debugging) - WRITE(UnSum, '(A)') 'Unless specified, units are consistent with Input units, [SI] system is advised.' + WRITE(UnSum, '(A)') '#Unless specified, units are consistent with Input units, [SI] system is advised.' WRITE(UnSum, '(A)') SectionDivide - - WRITE(UnSum, '()') - WRITE(UnSum, '(A,I6)') 'Number of nodes (NNodes):',Init%NNode - WRITE(UnSum, '(A8,1x,A11,3(1x,A15))') 'Node No.', 'Y2Mesh Node', 'X (m)', 'Y (m)', 'Z (m)' - WRITE(UnSum, '(A8,1x,A11,3(1x,A15))') '--------', '-----------', '---------------', '---------------', '---------------' -! WRITE(UnSum, '(I8.0, E15.6,E15.6,E15.6)') (INT(Init%Nodes(i, 1)),(Init%Nodes(i, j), j = 2, JointsCol), i = 1, Init%NNode) !do not group the format or it won't work 3(E15.6) does not work !bjj??? - WRITE(UnSum, '('//Num2LStr(Init%NNode)//'(I8,3x,I9,'//Num2lstr(JointsCol-1)//'(1x,F15.4),:,/))') & - (NINT(Init%Nodes(i, 1)), SDtoMeshIndx(i), (Init%Nodes(i, j), j = 2, JointsCol), i = 1, Init%NNode) + write(UnSum,'(A,3(E15.6))')'#TP reference point:',InitInput%TP_RefPoint(1:3) + + ! --- Internal FEM representation + WRITE(UnSum, '(A)') SectionDivide + WRITE(UnSum, '(A)') '# Internal FEM representation' + call yaml_write_var(UnSum, 'nNodes_I', p%nNodes_I,IFmt, ErrStat2, ErrMsg2, comment='Number of Nodes: "interface" (I)') + call yaml_write_var(UnSum, 'nNodes_C', p%nNodes_C,IFmt, ErrStat2, ErrMsg2, comment='Number of Nodes: "reactions" (C)') + call yaml_write_var(UnSum, 'nNodes_L', p%nNodes_L,IFmt, ErrStat2, ErrMsg2, comment='Number of Nodes: "internal" (L)') + call yaml_write_var(UnSum, 'nNodes ', p%nNodes ,IFmt, ErrStat2, ErrMsg2, comment='Number of Nodes: total (I+C+L)') + if(p%OutAll) then + call yaml_write_var(UnSum, 'nDOFI__ ', p%nDOFI__ ,IFmt, ErrStat2, ErrMsg2, comment='Number of DOFs: "interface" (I__)') + call yaml_write_var(UnSum, 'nDOFI_B ', p%nDOFI_Rb,IFmt, ErrStat2, ErrMsg2, comment='Number of DOFs: "interface" retained (I_B)') + call yaml_write_var(UnSum, 'nDOFI_F ', p%nDOFI_F ,IFmt, ErrStat2, ErrMsg2, comment='Number of DOFs: "interface" fixed (I_F)') + call yaml_write_var(UnSum, 'nDOFC__ ', p%nDOFC__ ,IFmt, ErrStat2, ErrMsg2, comment='Number of DOFs: "reactions" (C__)') + call yaml_write_var(UnSum, 'nDOFC_B ', p%nDOFC_Rb,IFmt, ErrStat2, ErrMsg2, comment='Number of DOFs: "reactions" retained (C_B)') + call yaml_write_var(UnSum, 'nDOFC_L ', p%nDOFC_L ,IFmt, ErrStat2, ErrMsg2, comment='Number of DOFs: "reactions" internal (C_L)') + call yaml_write_var(UnSum, 'nDOFC_F ', p%nDOFC_F ,IFmt, ErrStat2, ErrMsg2, comment='Number of DOFs: "reactions" fixed (C_F)') + call yaml_write_var(UnSum, 'nDOFR__ ', p%nDOFR__ ,IFmt, ErrStat2, ErrMsg2, comment='Number of DOFs: "intf+react" (__R)') + call yaml_write_var(UnSum, 'nDOFL_L ', p%nDOFL_L ,IFmt, ErrStat2, ErrMsg2, comment='Number of DOFs: "internal" internal (L_L)') + endif + call yaml_write_var(UnSum, 'nDOF__B ', p%nDOF__Rb,IFmt, ErrStat2, ErrMsg2, comment='Number of DOFs: retained (__B)') + call yaml_write_var(UnSum, 'nDOF__L ', p%nDOF__L ,IFmt, ErrStat2, ErrMsg2, comment='Number of DOFs: internal (__L)') + call yaml_write_var(UnSum, 'nDOF__F ', p%nDOF__F ,IFmt, ErrStat2, ErrMsg2, comment='Number of DOFs: fixed (__F)') + call yaml_write_var(UnSum, 'nDOF_red', p%nDOF_red,IFmt, ErrStat2, ErrMsg2, comment='Number of DOFs: total') + if(p%OutAll) then + call yaml_write_array(UnSum, 'Nodes_I', p%Nodes_I(:,1), IFmt, ErrStat2, ErrMsg2, comment='"interface" nodes"') + call yaml_write_array(UnSum, 'Nodes_C', p%Nodes_C(:,1), IFmt, ErrStat2, ErrMsg2, comment='"reaction" nodes"') + call yaml_write_array(UnSum, 'Nodes_L', p%Nodes_L(:,1), IFmt, ErrStat2, ErrMsg2, comment='"internal" nodes"') + call yaml_write_array(UnSum, 'DOF_I__', p%IDI__ , IFmt, ErrStat2, ErrMsg2, comment='"interface" DOFs"') + call yaml_write_array(UnSum, 'DOF_I_B', p%IDI_Rb, IFmt, ErrStat2, ErrMsg2, comment='"interface" retained DOFs') + call yaml_write_array(UnSum, 'DOF_I_F', p%IDI_F , IFmt, ErrStat2, ErrMsg2, comment='"interface" fixed DOFs') + call yaml_write_array(UnSum, 'DOF_C__', p%IDC__ , IFmt, ErrStat2, ErrMsg2, comment='"reaction" DOFs"') + call yaml_write_array(UnSum, 'DOF_C_B', p%IDC_Rb, IFmt, ErrStat2, ErrMsg2, comment='"reaction" retained DOFs') + call yaml_write_array(UnSum, 'DOF_C_L', p%IDC_L , IFmt, ErrStat2, ErrMsg2, comment='"reaction" internal DOFs') + call yaml_write_array(UnSum, 'DOF_C_F', p%IDC_F , IFmt, ErrStat2, ErrMsg2, comment='"reaction" fixed DOFs') + call yaml_write_array(UnSum, 'DOF_L_L', p%IDL_L , IFmt, ErrStat2, ErrMsg2, comment='"internal" internal DOFs') + call yaml_write_array(UnSum, 'DOF_R_', p%IDR__ , IFmt, ErrStat2, ErrMsg2, comment='"interface&reaction" DOFs') + endif + call yaml_write_array(UnSum, 'DOF___B', p%ID__Rb, IFmt, ErrStat2, ErrMsg2, comment='all retained DOFs') + call yaml_write_array(UnSum, 'DOF___F', p%ID__F , IFmt, ErrStat2, ErrMsg2, comment='all fixed DOFs') + call yaml_write_array(UnSum, 'DOF___L', p%ID__L , IFmt, ErrStat2, ErrMsg2, comment='all internal DOFs') WRITE(UnSum, '()') - WRITE(UnSum, '(A,I6)') 'Number of elements (NElems):',Init%NElem - WRITE(UnSum, '(A8,4(A10))') 'Elem No.', 'Node_I', 'Node_J', 'Prop_I', 'Prop_J' - WRITE(UnSum, '(I8,I10,I10,I10,I10)') ((p%Elems(i, j), j = 1, MembersCol), i = 1, Init%NElem) - + WRITE(UnSum, '(A)') '#Index map from DOF to nodes' + WRITE(UnSum, '(A)') '# Node No., DOF/Node, NodalDOF' + call yaml_write_array(UnSum, 'DOF2Nodes', p%DOFred2Nodes , IFmt, ErrStat2, ErrMsg2, comment='(nDOFRed x 3, for each constrained DOF, col1: node index, col2: number of DOF, col3: DOF starting from 1)',label=.true.) + + ! Nodes properties + write(UnSum, '("#",4x,1(A9),8('//trim(SFmt)//'))') 'Node_[#]', 'X_[m]','Y_[m]','Z_[m]', 'JType_[-]', 'JDirX_[-]','JDirY_[-]','JDirZ_[-]','JStff_[Nm/rad]' + call yaml_write_array(UnSum, 'Nodes', Init%Nodes, ReFmt, ErrStat2, ErrMsg2, AllFmt='1(F8.0,","),3(F15.3,","),(F15.0,","),4(E15.6,",")') !, comment='',label=.true.) + + ! Element properties + CALL AllocAry( DummyArray, size(p%ElemProps), 16, 'Elem', ErrStat2, ErrMsg2 ); if(Failed()) return + do i=1,size(p%ElemProps) + DummyArray(i,1) = p%Elems(i,1) ! Should be == i + DummyArray(i,2) = p%Elems(i,2) ! Node 1 + DummyArray(i,3) = p%Elems(i,3) ! Node 2 + DummyArray(i,4) = p%Elems(i,4) ! Prop 1 + DummyArray(i,5) = p%Elems(i,5) ! Prop 2 + DummyArray(i,6) = p%ElemProps(i)%eType ! Type + DummyArray(i,7) = p%ElemProps(i)%Length !Length + DummyArray(i,8) = p%ElemProps(i)%Area ! Area m^2 + DummyArray(i,9) = p%ElemProps(i)%Rho ! density kg/m^3 + DummyArray(i,10) = p%ElemProps(i)%YoungE ! Young modulus + DummyArray(i,11) = p%ElemProps(i)%ShearG ! G + DummyArray(i,12) = p%ElemProps(i)%Kappa ! Shear coefficient + DummyArray(i,13) = p%ElemProps(i)%Ixx ! Moment of inertia + DummyArray(i,14) = p%ElemProps(i)%Iyy ! Moment of inertia + DummyArray(i,15) = p%ElemProps(i)%Jzz ! Moment of inertia + DummyArray(i,16) = p%ElemProps(i)%T0 ! Pretension [N] + enddo + write(UnSum, '("#",4x,6(A9),10('//SFmt//'))') 'Elem_[#] ','Node_1','Node_2','Prop_1','Prop_2','Type','Length_[m]','Area_[m^2]','Dens._[kg/m^3]','E_[N/m2]','G_[N/m2]','shear_[-]','Ixx_[m^4]','Iyy_[m^4]','Jzz_[m^4]','T0_[N]' + call yaml_write_array(UnSum, 'Elements', DummyArray, ReFmt, ErrStat2, ErrMsg2, AllFmt='6(F8.0,","),3(F15.3,","),7(E15.6,",")') !, comment='',label=.true.) + deallocate(DummyArray) + + ! --- C + if(size(p%CtrlElem2Channel,1)>0) then + write(UnSum, '("#",2x,2(A11))') 'Elem_[#] ','Channel_[#]' + call yaml_write_array(UnSum, 'CtrlElem2Channel', p%CtrlElem2Channel, IFmt, ErrStat2, ErrMsg2, comment='') + endif + if (allocated(Init%Soil_K)) then + call yaml_write_array(UnSum, 'Soil_Nodes', Init%Soil_Nodes, IFmt, ErrStat2, ErrMsg2, comment='') + CALL AllocAry( DummyArray, 3, size(Init%Soil_Points,2), 'SoilP', ErrStat2, ErrMsg2 ); if(Failed()) return + do i=1,size(Init%Soil_K,3) + DummyArray(1:3,I) = Init%Nodes(Init%Soil_Nodes(I), 2:4) + call yaml_write_array(UnSum, 'Soil_K'//Num2LStr(I), Init%Soil_K(:,:,I), ReFmt, ErrStat2, ErrMsg2, comment='') + enddo + call yaml_write_array(UnSum, 'Soil_Points_SoilDyn', Init%Soil_Points, ReFmt, ErrStat2, ErrMsg2, comment='') + call yaml_write_array(UnSum, 'Soil_Points_SubDyn', DummyArray, ReFmt, ErrStat2, ErrMsg2, comment='') + deallocate(DummyArray) + endif + + ! --- User inputs (less interesting, repeat of input file) + WRITE(UnSum, '(A)') SectionDivide + WRITE(UnSum, '(A)') '#User inputs' WRITE(UnSum, '()') - WRITE(UnSum, '(A,I6)') 'Number of properties (NProps):',Init%NProp - WRITE(UnSum, '(A8,5(A15))') 'Prop No.', 'YoungE', 'ShearG', 'MatDens', 'XsecD', 'XsecT' - WRITE(UnSum, '(I8, E15.6,E15.6,E15.6,E15.6,E15.6 ) ') (NINT(Init%Props(i, 1)), (Init%Props(i, j), j = 2, 6), i = 1, Init%NProp) + WRITE(UnSum, '(A,I6)') '#Number of properties (NProps):',Init%NPropB + WRITE(UnSum, '(A8,5(A15))') '#Prop No.', 'YoungE', 'ShearG', 'MatDens', 'XsecD', 'XsecT' + WRITE(UnSum, '("#",I8, ES15.6E2,ES15.6E2,ES15.6E2,ES15.6E2,ES15.6E2 ) ') (NINT(Init%PropsB(i, 1)), (Init%PropsB(i, j), j = 2, 6), i = 1, Init%NPropB) WRITE(UnSum, '()') - WRITE(UnSum, '(A,I6)') 'No. of Reaction DOFs:',p%NReact*6 - WRITE(UnSum, '(A, A6)') 'Reaction DOF_ID', 'LOCK' - WRITE(UnSum, '(I10, I10)') ((Init%BCs(i, j), j = 1, 2), i = 1, p%NReact*6) + WRITE(UnSum, '(A,I6)') '#No. of Reaction DOFs:',p%nDOFC__ + WRITE(UnSum, '(A, A6)') '#React. DOF_ID', 'BC' + do i = 1, size(p%IDC_F ); WRITE(UnSum, '("#",I10, A10)') p%IDC_F(i) , ' Fixed' ; enddo + do i = 1, size(p%IDC_L ); WRITE(UnSum, '("#",I10, A10)') p%IDC_L(i) , ' Free' ; enddo + do i = 1, size(p%IDC_Rb); WRITE(UnSum, '("#",I10, A10)') p%IDC_Rb(i), ' Leader'; enddo WRITE(UnSum, '()') - WRITE(UnSum, '(A,I6)') 'No. of Interface DOFs:',p%DOFI - WRITE(UnSum, '(A,A6)') 'Interface DOF ID', 'LOCK' - WRITE(UnSum, '(I10, I10)') ((Init%IntFc(i, j), j = 1, 2), i = 1, p%DOFI) + WRITE(UnSum, '(A,I6)') '#No. of Interface DOFs:',p%nDOFI__ + WRITE(UnSum, '(A,A6)') '#Interf. DOF_ID', 'BC' + do i = 1, size(p%IDI_F ); WRITE(UnSum, '("#",I10, A10)') p%IDI_F(i) , ' Fixed' ; enddo + do i = 1, size(p%IDI_Rb); WRITE(UnSum, '("#",I10, A10)') p%IDI_Rb(i), ' Leader'; enddo WRITE(UnSum, '()') - WRITE(UnSum, '(A,I6)') 'Number of concentrated masses (NCMass):',Init%NCMass - WRITE(UnSum, '(A10,A15,A15,A15,A15)') 'JointCMass', 'Mass', 'JXX', 'JYY', 'JZZ' - WRITE(UnSum, '(F10.0, E15.6,E15.6,E15.6,E15.6)') ((Init%Cmass(i, j), j = 1, 5), i = 1, Init%NCMass) + WRITE(UnSum, '(A,I6)') '#Number of concentrated masses (NCMass):',Init%NCMass + WRITE(UnSum, '(A10,10(A15))') '#JointCMass', 'Mass', 'JXX', 'JYY', 'JZZ', 'JXY', 'JXZ', 'JYZ', 'MCGX', 'MCGY', 'MCGZ' + do i=1,Init%NCMass + WRITE(UnSum, '("#",F10.0, 10(E15.6))') (Init%Cmass(i, j), j = 1, CMassCol) + enddo WRITE(UnSum, '()') - WRITE(UnSum, '(A,I6)') 'Number of members',p%NMembers - WRITE(UnSum, '(A,I6)') 'Number of nodes per member:', Init%Ndiv+1 - WRITE(UnSum, '(A9,A10,A10,A15,A16)') 'Member ID', 'Joint1_ID', 'Joint2_ID', 'Mass', 'Node IDs...' - !WRITE(UnSum, '('//Num2LStr(Init%NDiv + 1 )//'(I6))') ((Init%MemberNodes(i, j), j = 1, Init%NDiv+1), i = 1, p%NMembers) + WRITE(UnSum, '(A,I6)') '#Number of members',p%NMembers + WRITE(UnSum, '(A,I6)') '#Number of nodes per member:', Init%Ndiv+1 + WRITE(UnSum, '(A9,A10,A10,A10,A10,A15,A15,A16)') '#Member ID', 'Joint1_ID', 'Joint2_ID','Prop_I','Prop_J', 'Mass','Length', 'Node IDs...' DO i=1,p%NMembers !Calculate member mass here; this should really be done somewhere else, yet it is not used anywhere else !IT WILL HAVE TO BE MODIFIED FOR OTHER THAN CIRCULAR PIPE ELEMENTS - propids=Init%Members(i,4:5) - mlength=MemberLength(Init%Members(i,1),Init,ErrStat,ErrMsg) + propIDs=Init%Members(i,iMProp:iMProp+1) + mLength=MemberLength(Init%Members(i,1),Init,ErrStat,ErrMsg) ! TODO double check mass and length IF (ErrStat .EQ. ErrID_None) THEN - WRITE(UnSum, '(I9,I10,I10, E15.6, A3,'//Num2LStr(Init%NDiv + 1 )//'(I6))') Init%Members(i,1:3), & - MemberMass(Init%PropSets(propids(1),4),Init%PropSets(propids(1),5),Init%PropSets(propids(1),6), & - Init%PropSets(propids(2),4),Init%PropSets(propids(2),5),Init%PropSets(propids(2),6), mlength, .TRUE.), & - ' ',(Init%MemberNodes(i, j), j = 1, Init%NDiv+1) + mType = Init%Members(I, iMType) ! + if (mType==idMemberBeam) then + iProp(1) = FINDLOCI(Init%PropSetsB(:,1), propIDs(1)) + iProp(2) = FINDLOCI(Init%PropSetsB(:,1), propIDs(2)) + mMass= BeamMass(Init%PropSetsB(iProp(1),4),Init%PropSetsB(iProp(1),5),Init%PropSetsB(iProp(1),6), & + Init%PropSetsB(iProp(2),4),Init%PropSetsB(iProp(2),5),Init%PropSetsB(iProp(2),6), mLength, .TRUE.) + + WRITE(UnSum, '("#",I9,I10,I10,I10,I10,ES15.6E2,ES15.6E2, A3,'//Num2LStr(Init%NDiv + 1 )//'(I6))') Init%Members(i,1:3),propIDs(1),propIDs(2),& + mMass,mLength,' ',(Init%MemberNodes(i, j), j = 1, Init%NDiv+1) + else if (mType==idMemberCable) then + iProp(1) = FINDLOCI(Init%PropSetsC(:,1), propIDs(1)) + mMass= Init%PropSetsC(iProp(1),3) * mLength ! rho [kg/m] * L + WRITE(UnSum, '("#",I9,I10,I10,I10,I10,ES15.6E2,ES15.6E2, A3,2(I6),A)') Init%Members(i,1:3),propIDs(1),propIDs(2),& + mMass,mLength,' ',(Init%MemberNodes(i, j), j = 1, 2), ' # Cable' + else if (mType==idMemberRigid) then + iProp(1) = FINDLOCI(Init%PropSetsR(:,1), propIDs(1)) + mMass= Init%PropSetsR(iProp(1),2) * mLength ! rho [kg/m] * L + WRITE(UnSum, '("#",I9,I10,I10,I10,I10,ES15.6E2,ES15.6E2, A3,2(I6),A)') Init%Members(i,1:3),propIDs(1),propIDs(2),& + mMass,mLength,' ',(Init%MemberNodes(i, j), j = 1, 2), ' # Rigid link' + else + WRITE(UnSum, '(A)') '#TODO, member unknown' + endif ELSE RETURN ENDIF @@ -2609,164 +3351,285 @@ SUBROUTINE OutSummary(Init, p, FEMparams,CBparams, ErrStat,ErrMsg) ! write Cosine matrix for all members to a txt file !------------------------------------------------------------------------------------------------------------- WRITE(UnSum, '(A)') SectionDivide - WRITE(UnSum, '(A, I6)') 'Direction Cosine Matrices for all Members: GLOBAL-2-LOCAL. No. of 3x3 matrices=', p%NMembers - WRITE(UnSum, '(A9,9(A15))') 'Member ID', 'DC(1,1)', 'DC(1,2)', 'DC(1,3)', 'DC(2,1)','DC(2,2)','DC(2,3)','DC(3,1)','DC(3,2)','DC(3,3)' + WRITE(UnSum, '(A, I6)') '#Direction Cosine Matrices for all Members: GLOBAL-2-LOCAL. No. of 3x3 matrices=', p%NMembers + WRITE(UnSum, '(A9,9(A15))') '#Member ID', 'DC(1,1)', 'DC(1,2)', 'DC(1,3)', 'DC(2,1)','DC(2,2)','DC(2,3)','DC(3,1)','DC(3,2)','DC(3,3)' DO i=1,p%NMembers - !Find the right index in the Nodes array for the selected JointID. This is horrible, but I do not know how to implement this search in a more efficient way - !The alternative would be to get an element that belongs to the member and use it with dircos - -!BJJ:TODO: DIDN'T we already calculate DirCos for each element? can't we use that here? - DO j=1,Init%NNode - IF ( NINT(Init%Nodes(j,1)) .EQ. Init%Members(i,2) )THEN - XYZ1=Init%Nodes(Init%Members(i,2),2:4) - ELSEIF ( NINT(Init%Nodes(j,1)) .EQ. Init%Members(i,3) ) THEN - XYZ2=Init%Nodes(Init%Members(i,3),2:4) - ENDIF - ENDDO - CALL GetDirCos(XYZ1(1), XYZ1(2), XYZ1(3), XYZ2(1), XYZ2(2), XYZ2(3), DirCos, mlength, ErrStat, ErrMsg) - DirCos=TRANSPOSE(DirCos) !This is now global to local - WRITE(UnSum, '(I9,9(E15.6))') Init%Members(i,1), ((DirCos(k,j),j=1,3),k=1,3) + iNode1 = FINDLOCI(Init%Joints(:,1), Init%Members(i,2)) ! index of joint 1 of member i + iNode2 = FINDLOCI(Init%Joints(:,1), Init%Members(i,3)) ! index of joint 2 of member i + XYZ1 = Init%Joints(iNode1,2:4) + XYZ2 = Init%Joints(iNode2,2:4) + CALL GetDirCos(XYZ1(1:3), XYZ2(1:3), DirCos, mLength, ErrStat, ErrMsg) + DirCos=TRANSPOSE(DirCos) !This is now global to local + WRITE(UnSum, '("#",I9,9(ES11.3E2))') Init%Members(i,1), ((DirCos(k,j),j=1,3),k=1,3) ENDDO !------------------------------------------------------------------------------------------------------------- ! write Eigenvalues of full SYstem and CB reduced System !------------------------------------------------------------------------------------------------------------- WRITE(UnSum, '(A)') SectionDivide - WRITE(UnSum, '(A)') 'Eigenvalues' - WRITE(UnSum, '(A)') SubSectionDivide - WRITE(UnSum, '(A, I6)') "FEM Eigenvalues [Hz]. Number of shown eigenvalues (total # of DOFs minus restrained nodes' DOFs):", FEMparams%NOmega - WRITE(UnSum, '(I6, e15.6)') ( i, FEMparams%Omega(i)/2.0/pi, i = 1, FEMparams%NOmega ) - - WRITE(UnSum, '(A)') SubSectionDivide - WRITE(UnSum, '(A, I6)') "CB Reduced Eigenvalues [Hz]. Number of retained modes' eigenvalues:", CBparams%DOFM - WRITE(UnSum, '(I6, e15.6)') ( i, CBparams%OmegaL(i)/2.0/pi, i = 1, CBparams%DOFM ) + WRITE(UnSum, '(A, I6)') "#Eigenfrequencies [Hz] for full system, with reaction constraints (+ Soil K/M + SoilDyn K0) " + call yaml_write_array(UnSum, 'Full_frequencies', Omega/(TwoPi), ReFmt, ErrStat2, ErrMsg2) + WRITE(UnSum, '(A, I6)') "#CB frequencies [Hz]" + call yaml_write_array(UnSum, 'CB_frequencies', CBparams%OmegaL(1:p%nDOFM)/(TwoPi), ReFmt, ErrStat2, ErrMsg2) !------------------------------------------------------------------------------------------------------------- - ! write Eigenvectors of full SYstem + ! write Eigenvectors of full System !------------------------------------------------------------------------------------------------------------- WRITE(UnSum, '(A)') SectionDivide - WRITE(UnSum, '(A, I6)') ('FEM Eigenvectors ('//TRIM(Num2LStr(Init%TDOF))//' x '//TRIM(Num2LStr(FEMparams%NOmega))//& - ') [m or rad]. Number of shown eigenvectors (total # of DOFs minus restrained nodes'' DOFs):'), FEMparams%NOmega - WRITE(UnSum, '(6x,'//Num2LStr(FEMparams%NOmega)//'(I15))') (i, i = 1, FEMparams%NOmega )!HEADERS - WRITE(UnSum, '(I6,'//Num2LStr(FEMparams%NOmega)//'e15.6)') ( i, (FEMparams%Modes(i,j), j = 1, FEMparams%NOmega ),i = 1, Init%TDOF) + WRITE(UnSum, '(A)') ('#FEM Eigenvectors ('//TRIM(Num2LStr(p%nDOF_red))//' x '//TRIM(Num2LStr(nOmega))//& + ') [m or rad], full system with reaction constraints (+ Soil K/M + SoilDyn K0)') + call yaml_write_array(UnSum, 'Full_Modes', Modes(:,1:nOmega), ReFmt, ErrStat2, ErrMsg2) !------------------------------------------------------------------------------------------------------------- ! write CB system matrices !------------------------------------------------------------------------------------------------------------- WRITE(UnSum, '(A)') SectionDivide - WRITE(UnSum, '(A)') 'CB Matrices (PhiM,PhiR) (no constraint applied)' - - WRITE(UnSum, '(A)') SubSectionDivide - IF (CBparams%DOFM > 0) THEN - CALL WrMatrix( CBparams%PhiL(:,1:CBparams%DOFM ), UnSum, 'e15.6', 'PhiM' ) - ELSE - WRITE( UnSum, '(A,": ",A," x ",A)', IOSTAT=ErrStat ) "PhiM", TRIM(Num2LStr(p%DOFL)), '0' - END IF - - WRITE(UnSum, '(A)') SubSectionDivide - CALL WrMatrix( CBparams%PhiR, UnSum, 'e15.6', 'PhiR' ) + WRITE(UnSum, '(A)') '#CB Matrices (PhiM,PhiR) (reaction constraints applied)' + call yaml_write_array(UnSum, 'PhiM', CBparams%PhiL(:,1:p%nDOFM ), ReFmt, ErrStat2, ErrMsg2, comment='(CB modes)') + call yaml_write_array(UnSum, 'PhiR', CBparams%PhiR, ReFmt, ErrStat2, ErrMsg2, comment='(Guyan modes)') !------------------------------------------------------------------------------------------------------------- ! write CB system KBBt and MBBt matrices, eq stiffness matrices of the entire substructure at the TP ref point !------------------------------------------------------------------------------------------------------------- WRITE(UnSum, '(A)') SectionDivide - WRITE(UnSum, '(A)') "SubDyn's Structure Equivalent Stiffness and Mass Matrices at the TP reference point (KBBt and MBBt)" - WRITE(UnSum, '(A)') SubSectionDivide - WRITE(UnSum, '(A)') 'KBBt' !Note p%KBB stores KBBt - WRITE(UnSum, '(7(A15))') ' ', (MatHds(i), i = 1, 6 ) - !tried implicit loop unsuccessfully - DO i=1,6 - WRITE(UnSum, '(A15, 6(e15.6))') MatHds(i), (p%KBB(i,j), j = 1, 6) - ENDDO - WRITE(UnSum, '(A)') SubSectionDivide - WRITE(UnSum, '(A)') ('MBBt')!Note p%MBB stores MBBt - WRITE(UnSum, '(7(A15))') ' ', (MatHds(i), i = 1, 6 ) - DO i=1,6 - WRITE(UnSum, '(A15, 6(e15.6))') MatHds(i), (p%MBB(i,j), j = 1, 6) - ENDDO + WRITE(UnSum, '(A)') "#SubDyn's Structure Equivalent Stiffness and Mass Matrices at the TP reference point (Guyan DOFs)" + call yaml_write_array(UnSum, 'KBBt', p%KBB, ReFmt, ErrStat2, ErrMsg2) + call yaml_write_array(UnSum, 'MBBt', p%MBB, ReFmt, ErrStat2, ErrMsg2) + call yaml_write_array(UnSum, 'CBBt', p%CBB, Refmt, ErrStat2, ErrMsg2, comment='(user Guyan Damping + potential joint damping from CB-reduction)') - MRB=matmul(TRANSPOSE(CBparams%TI2),matmul(CBparams%MBB,CBparams%TI2)) !Equivalent mass matrix of the rigid body + ! Set TI2, transformation matrix from R DOFs to SubDyn Origin + CALL AllocAry( TI2, p%nDOFR__ , 6, 'TI2', ErrStat2, ErrMsg2 ); if(Failed()) return + CALL RigidTrnsf(Init, p, (/0._ReKi, 0._ReKi, 0._ReKi/), p%IDR__, p%nDOFR__, TI2, ErrStat2, ErrMsg2); if(Failed()) return + ! Compute Rigid body mass matrix (without Soil, and using both Interface and Reactions nodes as leader DOF) + if (p%nDOFR__/=p%nDOF__Rb) then + call SD_Guyan_RigidBodyMass(Init, p, MBB, ErrStat2, ErrMsg2); if(Failed()) return + MRB=matmul(TRANSPOSE(TI2),matmul(MBB,TI2)) !Equivalent mass matrix of the rigid body + else + MRB=matmul(TRANSPOSE(TI2),matmul(CBparams%MBB,TI2)) !Equivalent mass matrix of the rigid body + endif WRITE(UnSum, '(A)') SectionDivide - WRITE(UnSum, '(A)') 'Rigid Body Equivalent Mass Matrix w.r.t. (0,0,0).' - WRITE(UnSum, '(A)') SubSectionDivide - WRITE(UnSum, '(A)') 'MRB' - WRITE(UnSum, '(7(A15))') ' ', (MatHds(i), i = 1, 6 ) - DO i=1,6 - WRITE(UnSum, '(A15, 6(e15.6))') MatHds(i), (MRB(i,j), j = 1, 6) - ENDDO + WRITE(UnSum, '(A)') '#Rigid Body Equivalent Mass Matrix w.r.t. (0,0,0).' + call yaml_write_array(UnSum, 'MRB', MRB, ReFmt, ErrStat2, ErrMsg2) + WRITE(UnSum, '(A,ES15.6E2)') "#SubDyn's Total Mass (structural and non-structural)=", MRB(1,1) + WRITE(UnSum, '(A,3(ES15.6E2))') "#SubDyn's Total Mass CM coordinates (Xcm,Ycm,Zcm) =", (/-MRB(3,5),-MRB(1,6), MRB(1,5)/) /MRB(1,1) + deallocate(TI2) - WRITE(UnSum, '()') - WRITE(UnSum, '(A,E15.6)') "SubDyn's Total Mass (structural and non-structural)=", MRB(1,1) - WRITE(UnSum, '(A,3(E15.6))') "SubDyn's Total Mass CM coordinates (Xcm,Ycm,Zcm) =", (/-MRB(3,5),-MRB(1,6), MRB(1,5)/) /MRB(1,1) - -#ifdef SD_SUMMARY_DEBUG + + if(p%OutAll) then ! //--- START DEBUG OUTPUTS WRITE(UnSum, '()') WRITE(UnSum, '(A)') SectionDivide - WRITE(UnSum, '(A)') '**** Additional Debugging Information ****' - - !------------------------------------------------------------------------------------------------------------- - ! write assembed K M to a txt file - !------------------------------------------------------------------------------------------------------------- + WRITE(UnSum, '(A)') '#**** Additional Debugging Information ****' + + ! --- Element Me,Ke,Fg, Fce + CALL ElemM(p%ElemProps(1), Me) + CALL ElemK(p%ElemProps(1), Ke) + CALL ElemF(p%ElemProps(1), Init%g, FGe, FCe) + call yaml_write_array(UnSum, 'Ke',Ke, ReFmt, ErrStat2, ErrMsg2, comment='First element stiffness matrix') + call yaml_write_array(UnSum, 'Me',Me, ReFmt, ErrStat2, ErrMsg2, comment='First element mass matrix') + call yaml_write_array(UnSum, 'FGe',FGe, ReFmt, ErrStat2, ErrMsg2, comment='First element gravity vector') + call yaml_write_array(UnSum, 'FCe',FCe, ReFmt, ErrStat2, ErrMsg2, comment='First element cable pretension') + + ! --- Write assembed K M to a txt file WRITE(UnSum, '(A)') SectionDivide - WRITE(UnSum, '(A, I6)') 'FULL FEM K and M matrices. TOTAL FEM TDOFs:', Init%TDOF - WRITE(UnSum, '(A)') ('Stiffness matrix K' ) - WRITE(UnSum, '(15x,'//TRIM(Num2LStr(Init%TDOF))//'(I15))') (i, i = 1, Init%TDOF ) - DO i=1,Init%TDOF - WRITE(UnSum, '(I15, '//TRIM(Num2LStr(Init%TDOF))//'(e15.6))') i, (Init%K(i, j), j = 1, Init%TDOF) - ENDDO - - WRITE(UnSum, '(A)') SubSectionDivide - WRITE(UnSum, '(A)') ('Mass matrix M' ) - WRITE(UnSum, '(15x,'//TRIM(Num2LStr(Init%TDOF))//'(I15))') (i, i = 1, Init%TDOF ) - DO i=1,Init%TDOF - WRITE(UnSum, '(I15, '//TRIM(Num2LStr(Init%TDOF))//'(e15.6))') i, (Init%M(i, j), j = 1, Init%TDOF) - ENDDO - - !------------------------------------------------------------------------------------------------------------- - ! write assembed GRAVITY FORCE FG VECTOR. gravity forces applied at each node of the full system - !------------------------------------------------------------------------------------------------------------- + WRITE(UnSum, '(A, I6)') '#FULL FEM K and M matrices. TOTAL FEM TDOFs:', p%nDOF + call yaml_write_array(UnSum, 'K', Init%K, ReFmt, ErrStat2, ErrMsg2, comment='Stiffness matrix') + call yaml_write_array(UnSum, 'M', Init%M, ReFmt, ErrStat2, ErrMsg2, comment='Mass matrix') + + ! --- write assembed GRAVITY FORCE FG VECTOR. gravity forces applied at each node of the full system WRITE(UnSum, '(A)') SectionDivide - WRITE(UnSum, '(A)') 'Gravity force vector FG applied at each node of the full system' - WRITE(UnSum, '(I6, e15.6)') (i, Init%FG(i), i = 1, Init%TDOF) + WRITE(UnSum, '(A)') '#Gravity and cable loads applied at each node of the system (before DOF elimination with T matrix)' + call yaml_write_array(UnSum, 'FG', p%FG, ReFmt, ErrStat2, ErrMsg2, comment='') - !------------------------------------------------------------------------------------------------------------- - ! write CB system matrices - !------------------------------------------------------------------------------------------------------------- + ! --- write CB system matrices WRITE(UnSum, '(A)') SectionDivide - WRITE(UnSum, '(A)') 'Additional CB Matrices (MBB,MBM,KBB) (no constraint applied)' - - WRITE(UnSum, '(A)') SubSectionDivide - CALL WrMatrix( CBparams%MBB, UnSum, 'e15.6', 'MBB' ) - - WRITE(UnSum, '(A)') SubSectionDivide - IF ( CBparams%DOFM > 0 ) THEN - CALL WrMatrix( CBparams%MBM, UnSum, 'e15.6', 'MBM' ) - ELSE - WRITE( UnSum, '(A,": ",A," x ",A)', IOSTAT=ErrStat ) "MBM", '6', '0' - END IF - - WRITE(UnSum, '(A)') SubSectionDivide - CALL WrMatrix( CBparams%KBB, UnSum, 'e15.6', 'KBB' ) - - WRITE(UnSum, '(A)') SubSectionDivide - CALL WrMatrix( CBparams%OmegaL**2, UnSum, 'e15.6','KMM (diagonal)' ) - - !------------------------------------------------------------------------------------------------------------- - ! write TP TI matrix - !------------------------------------------------------------------------------------------------------------- + WRITE(UnSum, '(A)') '#Additional CB Matrices (MBB,MBM,KBB) (constraint applied)' + call yaml_write_array(UnSum, 'MBB ',CBparams%MBB, ReFmt, ErrStat2, ErrMsg2, comment='') + call yaml_write_array(UnSum, 'MBM', CBparams%MBM, ReFmt, ErrStat2, ErrMsg2, comment='') + !call yaml_write_array(UnSum, 'CBB', CBparams%CBB, ReFmt, ErrStat2, ErrMsg2, comment='') + !call yaml_write_array(UnSum, 'CMM', CBparams%CMM, ReFmt, ErrStat2, ErrMsg2, comment='') + !call yaml_write_array(UnSum, 'CMMdiag_zeta',2.0_ReKi * CBparams%OmegaL(1:p%nDOFM) * Init%JDampings(1:p%nDOFM) , ReFmt, ErrStat2, ErrMsg2, comment='(2ZetaOmegaM)') + call yaml_write_array(UnSum, 'CMMdiag',p%CMMDiag, ReFmt, ErrStat2, ErrMsg2, comment='(2 Zeta OmegaM)') + call yaml_write_array(UnSum, 'KBB', CBparams%KBB, ReFmt, ErrStat2, ErrMsg2, comment='') + call yaml_write_array(UnSum, 'KMM', CBparams%OmegaL**2, ReFmt, ErrStat2, ErrMsg2, comment='(diagonal components, OmegaL^2)') + call yaml_write_array(UnSum, 'KMMdiag', p%KMMDiag, ReFmt, ErrStat2, ErrMsg2, comment='(diagonal components, OmegaL^2)') + IF (p%SttcSolve/= idSIM_None) THEN + call yaml_write_array(UnSum, 'PhiL', transpose(p%PhiL_T), ReFmt, ErrStat2, ErrMsg2, comment='') + call yaml_write_array(UnSum, 'PhiLOm2-1', p%PhiLInvOmgL2, ReFmt, ErrStat2, ErrMsg2, comment='') + call yaml_write_array(UnSum, 'KLL^-1' , p%KLLm1 , ReFmt, ErrStat2, ErrMsg2, comment='') + endif + ! --- Reduction info WRITE(UnSum, '(A)') SectionDivide - WRITE(UnSum, '(A)') 'TP refpoint Transformation Matrix TI ' - CALL WrMatrix( p%TI, UnSum, 'e15.6', 'TI' ) + call yaml_write_array(UnSum, 'T_red', p%T_red, 'ES9.2E2', ErrStat2, ErrMsg2, comment='(Constraint elimination matrix)') + + ! --- Linearization/ state matrices + call StateMatrices(p, ErrStat2, ErrMsg2, AA, BB, CC, DD); if(Failed()) return + call yaml_write_array(UnSum, 'AA', AA, 'ES10.3E2', ErrStat2, ErrMsg2, comment='(State matrix dXdx)') + call yaml_write_array(UnSum, 'BB', BB, 'ES10.3E2', ErrStat2, ErrMsg2, comment='(State matrix dXdu)') + call yaml_write_array(UnSum, 'CC', CC, 'ES10.3E2', ErrStat2, ErrMsg2, comment='(State matrix dYdx)') + call yaml_write_array(UnSum, 'DD', DD, 'ES10.3E2', ErrStat2, ErrMsg2, comment='(State matrix dYdu)') + if(allocated(AA)) deallocate(AA) + if(allocated(BB)) deallocate(BB) + if(allocated(CC)) deallocate(CC) + if(allocated(DD)) deallocate(DD) + endif ! //--- END DEBUG OUTPUTS + + ! --- write TP TI matrix + WRITE(UnSum, '(A)') SectionDivide + call yaml_write_array(UnSum, 'TI' , p%TI , 'ES9.2E2', ErrStat2, ErrMsg2, comment='(TP refpoint Transformation Matrix TI)') + if (allocated(p%TIReact)) then + call yaml_write_array(UnSum, 'TIReact', p%TIReact, 'ES9.2E2', ErrStat2, ErrMsg2, comment='(Transformation Matrix TIreact to (0,0,-WtrDepth))') + endif -#endif + call CleanUp() - CALL SDOut_CloseSum( UnSum, ErrStat, ErrMsg ) - +contains + LOGICAL FUNCTION Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'OutSummary') + Failed = ErrStat >= AbortErrLev + if (Failed) call CleanUp() + END FUNCTION Failed + SUBROUTINE CleanUp() + if(allocated(Omega)) deallocate(Omega) + if(allocated(Modes)) deallocate(Modes) + CALL SDOut_CloseSum( UnSum, ErrStat2, ErrMsg2 ) + END SUBROUTINE CleanUp END SUBROUTINE OutSummary +SUBROUTINE StateMatrices(p, ErrStat, ErrMsg, AA, BB, CC, DD, u) + type(SD_ParameterType), intent(in) :: p !< Parameters + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + real(R8Ki), dimension(:,:), allocatable, optional :: AA !< + real(R8Ki), dimension(:,:), allocatable, optional :: BB !< + real(R8Ki), dimension(:,:), allocatable, optional :: CC !< + real(R8Ki), dimension(:,:), allocatable, optional :: DD !< + type(SD_InputType), intent(in), optional :: u !< Inputs + integer(IntKi) :: nU, nX, nY, nCB, i, j, iNode, iOff, k, nMembers, iField + real(R8Ki), dimension(:), allocatable :: dFext_dFmeshk + real(R8Ki), dimension(:), allocatable :: dFred_dFmeshk + real(R8Ki), dimension(:), allocatable :: dFL_dFmeshk + real(R8Ki), dimension(:,:), allocatable :: PhiM_T + character(ErrMsgLen) :: ErrMsg2 + integer(IntKi) :: ErrStat2 + ErrStat = ErrID_None + ErrMsg = "" + + nCB = p%nDOFM + nX = 2*nCB + nU = 18 + 6*p%nNodes + nY=6 + + ! --- A matrix + if (present(AA)) then + if(allocated(AA)) deallocate(AA) + call AllocAry(AA, nX, nX, 'AA', ErrStat2, ErrMsg2 ); if(Failed()) return; AA(:,:) = 0.0_ReKi + if (nCB>0) then + do i=1,nCB + AA(i,nCB+i) = 1.0_ReKi ! Identity for 12 + enddo + do i=1,nCB + AA(nCB+i,i ) = -p%KMMDiag(i) ! 11 + AA(nCB+i,nCB+i) = -p%CMMDiag(i) ! 22 + enddo + endif + endif + + ! --- B matrix + if (present(BB)) then + if(allocated(BB)) deallocate(BB) + call AllocAry(BB, nX, nU, 'BB', ErrStat2, ErrMsg2 ); if(Failed()) return; BB(:,:) = 0.0_ReKi + if(nCB>0) then + BB(nCB+1:nX, 1 :6 ) = 0.0_ReKi + BB(nCB+1:nX, 13:18 ) = -p%MMB(1:nCB,1:6) ! TODO rotate + call AllocAry(dFext_dFmeshk, p%nDOF , 'dFext', ErrStat2, ErrMsg2 ); if(Failed()) return + call AllocAry(dFred_dFmeshk, p%nDOF_red , 'dFred', ErrStat2, ErrMsg2 ); if(Failed()) return + call AllocAry(dFL_dFmeshk , p%nDOF__L , 'dFl' , ErrStat2, ErrMsg2 ); if(Failed()) return + call AllocAry(PhiM_T , p%nDOFM , p%nDOF__L , 'PhiMT', ErrStat2, ErrMsg2 ); if(Failed()) return + PhiM_T = transpose(p%PhiM) + iOff=18 + k=0 + do iField = 1,2 ! Forces, Moment + do iNode = 1,p%nNodes + nMembers = (size(p%NodesDOF(iNode)%List)-3)/3 ! Number of members deducted from Node's nDOFList + do j=1,3 + k=k+1 + ! Build Fext with unit load (see GetExtForceOnInternalDOF) + dFext_dFmeshk= 0.0_ReKi + if (iField==1) then + ! Force - All nodes have only 3 translational DOFs + dFext_dFmeshk( p%NodesDOF(iNode)%List(j) ) = 1.0_ReKi + else + ! Moment is spread equally across all rotational DOFs if more than 3 rotational DOFs + dFext_dFmeshk( p%NodesDOF(iNode)%List((3+j)::3)) = 1.0_ReKi/nMembers + endif + ! Reduce and keep only "internal" DOFs L + if (p%reduced) then + dFred_dFmeshk = matmul(p%T_red_T, dFext_dFmeshk) + dFL_dFmeshk= dFred_dFmeshk(p%ID__L) + else + dFL_dFmeshk= dFext_dFmeshk(p%ID__L) + endif + ! + BB(nCB+1:nX, iOff+k) = matmul(PhiM_T, dFL_dFmeshk) + enddo ! 1-3 + enddo ! nodes + enddo ! field + endif + endif + + ! --- C matrix + if (present(CC)) then + if(allocated(CC)) deallocate(CC) + call AllocAry(CC, nY, nX, 'CC', ErrStat2, ErrMsg2 ); if(Failed()) return; CC(:,:) = 0.0_ReKi + !print*,'Warning: C matrix does not have all outputs, or extra moment, or static solve' + if (nCB>0) then + CC(1:nY,1:nCB ) = - p%C1_11 + CC(1:nY,nCB+1:nX) = - p%C1_12 + if (p%GuyanLoadCorrection .and. p%Floating .and. present(u)) then + CC(1:3,:) = matmul(transpose(u%TPMesh%Orientation(:,:,1)), CC(1:3,:)) ! >>> Rotate All + CC(4:6,:) = matmul(transpose(u%TPMesh%Orientation(:,:,1)), CC(4:6,:)) ! >>> Rotate All + endif + endif + endif + + ! --- D matrix + if (present(DD)) then + !print*,'Warning: D matrix does not have all outputs, or extra moment, or static solve' + if(allocated(DD)) deallocate(DD) + call AllocAry(DD, nY, nU, 'DD', ErrStat2, ErrMsg2 ); if(Failed()) return; DD(:,:) = 0.0_ReKi + DD(1:nY,1:6 ) = - p%KBB + DD(1:nY,7:12 ) = - p%CBB + DD(1:nY,13:18 ) = - p%MBB + if (p%nDOFM>0) then + if (p%GuyanLoadCorrection .and. p%Floating .and. present(u)) then + ! TODO TODO rotate it A MBmmB A^t + !DD(1:3,:) = DD(1:3,:) + matmul(transpose(u%TPMesh%Orientation(:,:,1)), p%MBmmB(1:3,:) ! >>> Rotate All + DD(1:nY,13:18 ) = DD(1:nY,13:18 )+ p%MBmmB + else + DD(1:nY,13:18 ) = DD(1:nY,13:18 )+ p%MBmmB + endif + endif + endif + + call CleanUp() +contains + LOGICAL FUNCTION Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'StateMatrices') + Failed = ErrStat >= AbortErrLev + if(Failed) call CleanUp() + END FUNCTION Failed + SUBROUTINE CleanUp() + if(allocated(dFext_dFmeshk)) deallocate(dFext_dFmeshk) + if(allocated(dFred_dFmeshk)) deallocate(dFred_dFmeshk) + if(allocated(dFL_dFmeshk)) deallocate(dFL_dFmeshk) + if(allocated(PhiM_T)) deallocate(PhiM_T) + END SUBROUTINE CleanUp +END SUBROUTINE StateMatrices + !------------------------------------------------------------------------------------------------------ -!> This function calculates the length of a member +!> Calculate length of a member as given in input file +!! Joints and Members ID have not been reindexed (Elems and Nodes have) FUNCTION MemberLength(MemberID,Init,ErrStat,ErrMsg) TYPE(SD_InitType), INTENT(IN) :: Init !< Input data for initialization routine, this structure contains many variables needed for summary file INTEGER(IntKi), INTENT(IN) :: MemberID !< Member ID # @@ -2774,87 +3637,57 @@ FUNCTION MemberLength(MemberID,Init,ErrStat,ErrMsg) INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None !Locals - REAL(Reki) :: xyz1(3),xyz2(3) ! Coordinates of joints in GLOBAL REF SYS - INTEGER(IntKi) :: i ! Counter - INTEGER(IntKi) :: Joint1,Joint2 ! JointID - CHARACTER(*), PARAMETER :: RoutineName = 'MemberLength' + REAL(Reki) :: xyz1(3),xyz2(3) ! Coordinates of joints in GLOBAL REF SYS + integer(IntKi) :: iMember !< Member index in Init%Members list + INTEGER(IntKi) :: Joint1,Joint2 ! JointID + CHARACTER(*), PARAMETER :: RoutineName = 'MemberLength' ErrStat = ErrID_None ErrMsg = '' MemberLength=0.0 !Find the MemberID in the list - DO i=1,SIZE(Init%Members, DIM=1) - IF (Init%Members(i,1) .EQ. MemberID) THEN - ! Find joints ID for this member - Joint1 = FindNode(i,1); if (Joint1<0) return - Joint2 = FindNode(i,2); if (Joint2<0) return - xyz1= Init%Joints(Joint1,2:4) - xyz2= Init%Joints(Joint2,2:4) - MemberLength=SQRT( SUM((xyz2-xyz1)**2.) ) - if ( EqualRealNos(MemberLength, 0.0_ReKi) ) then - call SetErrStat(ErrID_Fatal,' Member with ID '//trim(Num2LStr(MemberID))//' has zero length!', ErrStat,ErrMsg,RoutineName); - return - endif - return - ENDIF - ENDDO - call SetErrStat(ErrID_Fatal,' Member with ID '//trim(Num2LStr(MemberID))//' not found in member list!', ErrStat,ErrMsg,RoutineName); - -contains - !> Find JointID for node `iNode` (1 or 2) or member `iMember` - integer(IntKi) function FindNode(iMember,iNode) result(j) - integer(IntKi), intent(in) :: iMember !< Member index in Init%Members list - integer(IntKi), intent(in) :: iNode !< Node index, 1 or 2 for the member iMember - logical :: found - found = .false. - j=1 - do while ( .not. found .and. j <= Init%NJoints ) - if (Init%Members(iMember, iNode+1) == nint(Init%Joints(j,1))) then ! Columns 2/3 for iNode 1/2 - found = .true. - exit - endif - j = j + 1 - enddo - if (.not.found) then - j=-1 - call SetErrStat(ErrID_Fatal,' Member '//trim(Num2LStr(iMember))//' has JointID'//trim(Num2LStr(iNode))//' = '//& - trim(Num2LStr(Init%Members(iMember,iNode+1)))//' which is not in the node list !', ErrStat,ErrMsg,RoutineName) - endif - end function - + iMember = FINDLOCI(Init%Members(:,1), MemberID) + if (iMember<=0) then + call SetErrStat(ErrID_Fatal,' Member with ID '//trim(Num2LStr(MemberID))//' not found in member list!', ErrStat,ErrMsg,RoutineName); + return + endif + ! Find joints ID for this member + Joint1 = FINDLOCI(Init%Joints(:,1), Init%Members(iMember,2)) + Joint2 = FINDLOCI(Init%Joints(:,1), Init%Members(iMember,3)) + xyz1= Init%Joints(Joint1,2:4) + xyz2= Init%Joints(Joint2,2:4) + MemberLength=SQRT( SUM((xyz2-xyz1)**2.) ) + if ( EqualRealNos(MemberLength, 0.0_ReKi) ) then + call SetErrStat(ErrID_Fatal,' Member with ID '//trim(Num2LStr(MemberID))//' has zero length!', ErrStat,ErrMsg,RoutineName); + return + endif END FUNCTION MemberLength !------------------------------------------------------------------------------------------------------ !> Calculate member mass, given properties at the ends, keep units consistent !! For now it works only for circular pipes or for a linearly varying area -FUNCTION MemberMass(rho1,D1,t1,rho2,D2,t2,L,ctube) - REAL(ReKi), INTENT(IN) :: rho1,D1,t1,rho2,D2,t2 ,L ! Density, OD and wall thickness for circular tube members at ends, Length of member - ! IF ctube=.FALSE. then D1/2=Area at end1/2, t1 and t2 are ignored - REAL(ReKi) :: MemberMass !mass - LOGICAL, INTENT(IN) :: ctube ! =TRUE for circular pipes, false elseshape - !LOCALS - REAL(ReKi) ::a0,a1,a2,b0,b1,dd,dt !temporary coefficients - - !Density allowed to vary linearly only - b0=rho1 - b1=(rho2-rho1)/L - !Here we will need to figure out what element it is for now circular pipes - IF (ctube) THEN !circular tube - a0=pi * (D1*t1-t1**2.) - dt=t2-t1 !thickness variation - dd=D2-D1 !OD variation - a1=pi * ( dd*t1 + D1*dt -2.*t1*dt)/L - a2=pi * ( dd*dt-dt**2.)/L**2. - - ELSE !linearly varying area - a0=D1 !This is an area - a1=(D2-D1)/L !Delta area - a2=0. - - ENDIF - MemberMass= b0*a0*L +(a0*b1+b0*a1)*L**2/2. + (b0*a2+b1*a1)*L**3/3 + a2*b1*L**4/4.!Integral of rho*A dz - -END FUNCTION MemberMass +FUNCTION BeamMass(rho1,D1,t1,rho2,D2,t2,L,ctube) + REAL(ReKi), INTENT(IN) :: rho1,D1,t1,rho2,D2,t2 ,L ! Density, OD and wall thickness for circular tube members at ends, Length of member + LOGICAL, INTENT(IN) :: ctube ! =TRUE for circular pipes, false elseshape + REAL(ReKi) :: BeamMass !mass + REAL(ReKi) :: a0,a1,a2,b0,b1,dd,dt !temporary coefficients + !Density allowed to vary linearly only + b0=rho1 + b1=(rho2-rho1)/L + !Here we will need to figure out what element it is for now circular pipes + IF (ctube) THEN !circular tube + a0=pi * (D1*t1-t1**2.) + dt=t2-t1 !thickness variation + dd=D2-D1 !OD variation + a1=pi * ( dd*t1 + D1*dt -2.*t1*dt)/L + a2=pi * ( dd*dt-dt**2.)/L**2. + ELSE !linearly varying area + a0=D1 !This is an area + a1=(D2-D1)/L !Delta area + a2=0. + ENDIF + BeamMass= b0*a0*L +(a0*b1+b0*a1)*L**2/2. + (b0*a2+b1*a1)*L**3/3 + a2*b1*L**4/4.!Integral of rho*A dz +END FUNCTION BeamMass !------------------------------------------------------------------------------------------------------ !> Check whether MAT IS SYMMETRIC AND RETURNS THE MAXIMUM RELATIVE ERROR @@ -2889,4 +3722,78 @@ SUBROUTINE SymMatDebug(M,MAT) END SUBROUTINE SymMatDebug -End Module SubDyn +FUNCTION is_numeric(string, x) + IMPLICIT NONE + CHARACTER(len=*), INTENT(IN) :: string + REAL(ReKi), INTENT(OUT) :: x + LOGICAL :: is_numeric + INTEGER :: e,n + CHARACTER(len=12) :: fmt + x = 0.0_ReKi + n=LEN_TRIM(string) + WRITE(fmt,'("(F",I0,".0)")') n + READ(string,fmt,IOSTAT=e) x + is_numeric = e == 0 +END FUNCTION is_numeric +FUNCTION is_logical(string, b) + IMPLICIT NONE + CHARACTER(len=*), INTENT(IN) :: string + Logical, INTENT(OUT) :: b + LOGICAL :: is_logical + INTEGER :: e,n + b = .false. + n=LEN_TRIM(string) + READ(string,*,IOSTAT=e) b + is_logical = e == 0 +END FUNCTION is_logical + +!> Parses a file for Kxx,Kxy,..Kxthtx,..Kxtz, Kytx, Kyty,..Kztz +SUBROUTINE ReadSSIfile ( Filename, JointID, SSIK, SSIM, ErrStat, ErrMsg, UnEc ) + USE NWTC_IO + INTEGER, INTENT(IN) :: JointID !< ID of th ejoint for which we are reading SSI + INTEGER, INTENT(IN), OPTIONAL :: UnEc !< I/O unit for echo file. If present and > 0, write to UnEc + INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Error status; if present, program does not abort on error + CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message + INTEGER :: CurLine !< The current line to be parsed in the FileInfo structure. + REAL(FEKi), INTENT(INOUT) , dimension(21) :: SSIK, SSIM !< Matrices being filled by reading the file. + CHARACTER(*), INTENT(IN) :: Filename !< Name of the input file. + ! Local declarations: + CHARACTER(5), DIMENSION(21) :: Knames=(/'Kxx ','Kxy ','Kyy ','Kxz ','Kyz ', 'Kzz ','Kxtx ','Kytx ','Kztx ','Ktxtx', & + 'Kxty ','Kyty ','Kzty ','Ktxty','Ktyty', & + 'Kxtz ','Kytz ','Kztz ','Ktxtz','Ktytz','Ktztz'/) ! Dictionary of names by column for an Upper Triangular Matrix + CHARACTER(5), DIMENSION(21) :: Mnames=(/'Mxx ','Mxy ','Myy ','Mxz ','Myz ', 'Mzz ','Mxtx ','Mytx ','Mztx ','Mtxtx', & + 'Mxty ','Myty ','Mzty ','Mtxty','Mtyty', & + 'Mxtz ','Mytz ','Mztz ','Mtxtz','Mtytz','Mtztz'/) + TYPE (FileInfoType) :: FileInfo ! The derived type for holding the file information. + INTEGER(IntKi) :: i, j, imax !counters + CHARACTER(ErrMsgLen) :: ErrMsg2 + INTEGER(IntKi) :: ErrStat2 ! Error status; if present, program does not abort on error + CHARACTER(*), PARAMETER :: RoutineName = 'ReadSSIfile' + + SSIK=0.0_FEKi + SSIM=0.0_FEKi + + CALL ProcessComFile ( Filename, FileInfo, ErrStat2, ErrMsg2 );CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); IF (ErrStat >= AbortErrLev) RETURN + CurLine = 1 + imax=21 + DO i=1, imax !This will search also for already hit up names, but that's ok, it should be pretty fast + DO j=1,FileInfo%NumLines + CurLine=j + CALL ParseVarWDefault ( FileInfo, CurLine, Knames(i), SSIK(i), 0.0_FEKi, ErrStat2, ErrMsg2 ) + CALL ParseVarWDefault ( FileInfo, CurLine, Mnames(i), SSIM(i), 0.0_FEKi, ErrStat2, ErrMsg2 ) + ENDDO + ENDDO + IF ( PRESENT(UnEc) ) THEN + IF ( UnEc .GT. 0 ) THEN + WRITE (UnEc,'(1X,A20," = ",I11)') 'JOINT ID',JointID + DO i=1,21 + WRITE (UnEc,'(1X,ES11.4e2," = ",A20)') SSIK(i), Knames(i) + WRITE (UnEc,'(1X,ES11.4e2," = ",A20)') SSIM(i), Mnames(i) + ENDDO + ENDIF + END IF + RETURN +END SUBROUTINE ReadSSIfile + + +end module SubDyn diff --git a/modules/subdyn/src/SubDyn_Driver.f90 b/modules/subdyn/src/SubDyn_Driver.f90 index eaa18c094b..bbe48257be 100644 --- a/modules/subdyn/src/SubDyn_Driver.f90 +++ b/modules/subdyn/src/SubDyn_Driver.f90 @@ -77,12 +77,12 @@ PROGRAM TestSubDyn 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(SD_Drvr_InitInput) :: drvrInitInp ! Initialization data for the driver program - INTEGER(IntKi) :: UnInp ! Inputs file identifier + INTEGER :: UnIn ! Unit number for the input file + INTEGER :: UnEcho ! The local unit number for this module's echo file INTEGER(IntKi) :: UnSD_Out ! Output file identifier REAL(ReKi), ALLOCATABLE :: SDin(:,:) ! Variable for storing time, forces, and body velocities, in m/s or rad/s for SubDyn inputs INTEGER(IntKi) :: J ! Generic loop counter REAL(ReKi) :: dcm (3,3) ! The resulting transformation matrix from X to x, (-). - REAL(DbKi) :: maxAngle ! For debugging, see what the largest rotational angle input is for the simulation CHARACTER(10) :: AngleMsg ! For debugging, a string version of the largest rotation input ! Other/Misc variables @@ -90,327 +90,177 @@ PROGRAM TestSubDyn REAL(DbKi) :: TMax REAL(DbKi) :: OutTime ! Used to determine if output should be generated at this simulation time REAL(ReKi) :: PrevClockTime ! Clock time at start of simulation in seconds - REAL :: UsrTime1 ! User CPU time for simulation initialization + REAL(ReKi) :: UsrTime1 ! User CPU time for simulation initialization INTEGER :: StrtTime (8) ! Start time of simulation CHARACTER(200) :: git_commit ! String containing the current git commit hash TYPE(ProgDesc), PARAMETER :: version = ProgDesc( 'SubDyn Driver', '', '' ) ! The version number of this program. !............................................................................................................................... ! Routines called in initialization !............................................................................................................................... - - + ErrMsg = "" + ErrStat = ErrID_None + UnEcho=-1 + UnIn =-1 - ! Get the current time - + ! Get the current time CALL DATE_AND_TIME ( Values=StrtTime ) ! Let's time the whole simulation CALL CPU_TIME ( UsrTime1 ) ! Initial time (this zeros the start time when used as a MATLAB function) PrevClockTime = TimeValues2Seconds( StrtTime ) ! We'll use this time for the SimStats routine TiLstPrn = 0.0_DbKi ! The first value of ZTime, used to write simulation stats to screen (s) - - ! Initialize the NWTC Subroutine Library - + ! Initialize the NWTC Subroutine Library CALL NWTC_Init( ) - ! Display the copyright notice + ! Display the copyright notice CALL DispCopyrightLicense( version%Name ) - ! Obtain OpenFAST git commit hash + ! Obtain OpenFAST git commit hash git_commit = QueryGitVersion() - ! Tell our users what they're running + ! Tell our users what they're running CALL WrScr( ' Running '//TRIM( version%Name )//' a part of OpenFAST - '//TRIM(git_Commit)//NewLine//' linked with '//TRIM( NWTC_Ver%Name )//NewLine ) - - - ! Set the abort error level to a fatal error + ! Set the abort error level to a fatal error AbortErrLev = ErrID_Fatal - IF ( command_argument_count() > 1 ) CALL print_help() + IF ( command_argument_count() /= 1 ) then + CALL print_help() + STOP + endif - ! Parse the driver input file and run the simulation based on that file - + ! Parse the driver input file and run the simulation based on that file IF ( command_argument_count() == 1 ) THEN - CALL get_command_argument(1, drvrFilename) - CALL ReadDriverInputFile( drvrFilename, drvrInitInp, ErrStat, ErrMsg ) - IF ( ErrStat /= 0 ) THEN - CALL WrScr( ErrMsg ) - STOP - END IF + + CALL ReadDriverInputFile( drvrFilename, drvrInitInp); InitInData%g = drvrInitInp%Gravity - !InitInData%UseInputFile = .TRUE. InitInData%SDInputFile = drvrInitInp%SDInputFile - InitInData%RootName = drvrInitInp%OutRootName + InitInData%RootName = drvrInitInp%OutRootName InitInData%TP_RefPoint = drvrInitInp%TP_RefPoint InitInData%SubRotateZ = drvrInitInp%SubRotateZ TimeInterval = drvrInitInp%TimeInterval InitInData%WtrDpth = drvrInitInp%WtrDpth - ELSE - ! Called without a driver input file! - CALL WrScr( 'Running SubDyn without a driver file! This is for SubDyn developers only.' ) - ! InitInData%SDInputFile = '..\BeamFEM\IOFiles\TestBeam2.txt' - InitInData%SDInputFile = '..\MergedSubDyn\IOFiles\TestBeam3.txt' - ! InitInData%SDInputFile = '..\BeamFEM\IOFiles\TestFrame.txt' - InitInData%g = 9.80665 - !InitInData%TP_RefPoint = (/0.0, 0.0, 100.0/) !testbeam2 - InitInData%TP_RefPoint = (/50.0, 0.0, 50.0/) !testbeam3 - InitInData%SubRotateZ = 0.0 - InitInData%WtrDpth = 20.0 - !InitInData%TP_RefPoint = (/0.0, 0.0, 40.0/) !testframe - ! Set the driver's request for time interval here: - TimeInterval = 0.001 ! Glue code's request for delta time (likely based on information from other modules) END IF + + TMax = TimeInterval * drvrInitInp%NSteps - - TMax = TimeInterval * drvrInitInp%NSteps - - ! Initialize the module - - CALL SD_Init( InitInData, u(1), p, x, xd, z, OtherState, y, m, TimeInterval, InitOutData, ErrStat1, ErrMsg1 ) - IF ( ErrStat1 /= 0 ) THEN - CALL WrScr( ErrMsg1 ) - STOP - END IF + ! Initialize the module + CALL SD_Init( InitInData, u(1), p, x, xd, z, OtherState, y, m, TimeInterval, InitOutData, ErrStat2, ErrMsg2 ); call AbortIfFailed() + CALL AllocAry(SDin, drvrInitInp%NSteps, 19, 'SDinput array', ErrStat2, ErrMsg2); call AbortIfFailed() + SDin(:,:)=0.0_ReKi - ! Read Input time series data from a file - + ! Read Input time series data from a file IF ( drvrInitInp%InputsMod == 2 ) THEN - - ! Open the inputs data file - CALL GetNewUnit( UnInp ) - CALL OpenFInpFile ( UnInp, drvrInitInp%InputsFile, ErrStat, ErrMsg ) ! Open inputs file. - IF (ErrStat >= AbortErrLev) THEN - CALL WrScr( 'SubDyn input timeseries file not found.') - CALL WrScr( trim(ErrMsg) ) - STOP - END IF - - ALLOCATE ( SDin(drvrInitInp%NSteps, 13), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for SDin array.' - CALL WrScr( ErrMsg ) - CLOSE( UnInp ) - STOP - END IF - + ! Open the inputs data file + CALL GetNewUnit( UnIn ) + CALL OpenFInpFile ( UnIn, drvrInitInp%InputsFile, ErrStat2, ErrMsg2); Call AbortIfFailed() DO n = 1,drvrInitInp%NSteps - READ (UnInp,*,IOSTAT=ErrStat) (SDin (n,J), J=1,13) - - IF ( ErrStat /= 0 ) THEN - ErrMsg = 'File not found' - CALL WrScr( ErrMsg ) - CLOSE ( UnInp ) - STOP - END IF + ! TODO Add safety for backward compatibility if only 13 columns + READ (UnIn,*,IOSTAT=ErrStat2) (SDin (n,J), J=1,19) + ErrMsg2 = ' Error reading line '//trim(Num2LStr(n))//' of file: '//trim(drvrInitInp%InputsFile) + call AbortIfFailed() END DO - - ! Close the inputs file - CLOSE ( UnInp ) - END IF + CLOSE ( UnIn ) + else + ! We fill an array with constant values + do n = 0,drvrInitInp%NSteps-1 ! Loop on time steps, starts at 0 + SDin(n+1,1) = n*TimeInterval + SDin(n+1,2:7 ) = drvrInitInp%uTPInSteady(1:6) ! Displacements + SDin(n+1,8:13) = drvrInitInp%uDotTPInSteady(1:6) ! Velocities + !SDin(n+1,14:19) = drvrInitInp%uDotDotTPInSteady(1:6) ! Accelerations + enddo + end if - ! Destroy initialization data - - CALL SD_DestroyInitInput( InitInData, ErrStat2, ErrMsg2 ) - CALL SD_DestroyInitOutput( InitOutData, ErrStat3, ErrMsg3 ) - - - ! Handle the initialization error after destroying the data structures - - IF ( ErrStat1 /= ErrID_None .OR. ErrStat2 /=0 .OR. ErrStat3 /= 0) THEN ! Check if there was an error and do something about it if necessary - CALL WrScr( ErrMsg1 ) - STOP - END IF - - IF ( ErrStat2 /=0 .OR. ErrStat3 /= 0) THEN ! Check if there was an error and do something about it if necessary - CALL WrScr( 'Error destroying SubDyn intialization data' ) - STOP - END IF + ! Destroy initialization data + CALL SD_DestroyInitInput( InitInData, ErrStat2, ErrMsg2 ); call AbortIfFailed() + CALL SD_DestroyInitOutput( InitOutData, ErrStat2, ErrMsg2 ); call AbortIfFailed() !............................................................................................................................... ! Routines called in loose coupling -- the glue code may implement this in various ways !............................................................................................................................... - ! Force the displacement of the interface node in the global Z direction to be the sag of the column under it's own weight + ! u(1)%UFL(3) =-12.958 !this is for testbeam3 - !u(1)%UFL(3) = -0.001821207 !-0.001821235 !This is for testbeam.txt - ! u(1)%UFL(3)=-12.958 !this is for testbeam3 - - call wrscr('') - DO n = 0,drvrInitInp%NSteps-1 + ! TEMPORARY HACK FOR CONTROLLABLE CABLES + !allocate(u(1)%CableDeltaL(5)) + !!u(1)%CableDeltaL= 1.0e7_ReKi + !u(1)%CableDeltaL= 0.0e7_ReKi + + call WrScr('') + DO n = 0,drvrInitInp%NSteps-1 ! Loop on time steps, starts at 0 Time = n*TimeInterval InputTime(1) = Time - ! Modify u (likely from the outputs of another module or a set of test conditions) here: - + ! Set module inputs u (likely from the outputs of another module or a set of test conditions) here: IF ( u(1)%TPMesh%Initialized ) THEN - ! For now, set all hydrodynamic load inputs to 0.0 u(1)%LMesh%Force (:,:) = 0.0 - !u(1)%LMesh%Force (3,5:8) = 1.e7 !DEBUGGING - !u(1)%LMesh%Force(3,5) = 1.e7 - !u(1)%LMesh%Force(3,6) = 1.e7 - !u(1)%LMesh%Force(3,7) = 1.e7 - !u(1)%LMesh%Force(3,8) = 1.e7 u(1)%LMesh%Moment (:,:) = 0.0 + ! Input displacements, velocities and potentially accelerations + u(1)%TPMesh%TranslationDisp(:,1) = SDin(n+1,2:4) + CALL SmllRotTrans( 'InputRotation', REAL(SDin(n+1,5),reki), REAL(SDin(n+1,6),reki), REAL(SDin(n+1,7),reki), dcm, 'Junk', ErrStat, ErrMsg ) + u(1)%TPMesh%Orientation(:,:,1) = dcm + u(1)%TPMesh%TranslationVel(:,1) = SDin(n+1,8:10) + u(1)%TPMesh%RotationVel(:,1) = SDin(n+1,11:13) + IF ( drvrInitInp%InputsMod == 2 ) THEN - - - - u(1)%TPMesh%TranslationDisp(:,1) = SDin(n+1,2:4) - - - ! Compute direction cosine matrix from the rotation angles - - IF ( abs(SDin(n+1,5)) > maxAngle ) maxAngle = abs(SDin(n+1,5)) - IF ( abs(SDin(n+1,6)) > maxAngle ) maxAngle = abs(SDin(n+1,6)) - IF ( abs(SDin(n+1,7)) > maxAngle ) maxAngle = abs(SDin(n+1,7)) - - CALL SmllRotTrans( 'InputRotation', REAL(SDin(n+1,5),reki), REAL(SDin(n+1,6),reki), REAL(SDin(n+1,7),reki), dcm, 'Junk', ErrStat, ErrMsg ) - u(1)%TPMesh%Orientation(:,:,1) = dcm - - - u(1)%TPMesh%TranslationVel(:,1) = SDin(n+1,8:10) - u(1)%TPMesh%RotationVel(:,1) = SDin(n+1,11:13) - - ELSE - - u(1)%TPMesh%TranslationDisp(:,1) = drvrInitInp%uTPInSteady(1:3) - - - ! Compute direction cosine matrix from the rotation angles - CALL SmllRotTrans( 'InputRotation', REAL(drvrInitInp%uTPInSteady(4),reki), REAL(drvrInitInp%uTPInSteady(5),reki), REAL(drvrInitInp%uTPInSteady(6),reki), dcm, 'Junk', ErrStat, ErrMsg ) - u(1)%TPMesh%Orientation(:,:,1) = dcm - - u(1)%TPMesh%TranslationVel(:,1) = drvrInitInp%uDotTPInSteady(1:3) - u(1)%TPMesh%RotationVel(:,1) = drvrInitInp%uDotTPInSteady(4:6) - + u(1)%TPMesh%TranslationAcc(:,1) = SDin(n+1,14:16) + u(1)%TPMesh%RotationAcc(:,1) = SDin(n+1,17:19) + ELSE ! constant inputs u(1)%TPMesh%TranslationAcc(:,1) = drvrInitInp%uDotDotTPInSteady(1:3) u(1)%TPMesh%RotationAcc(:,1) = drvrInitInp%uDotDotTPInSteady(4:6) - END IF - END IF - ! Calculate outputs at n - - CALL SD_CalcOutput( Time, u(1), p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) THEN ! Check if there was an error and do something about it if necessary - CALL WrScr( ErrMsg ) - IF ( ErrStat >= AbortErrLev) STOP - END IF - - ! Get state variables at next step: INPUT at step n, OUTPUT at step n + 1 - - CALL SD_UpdateStates( Time, n, u, InputTime, p, x, xd, z, OtherState, m, ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) THEN ! Check if there was an error and do something about it if necessary - CALL WrScr( ErrMsg ) - IF ( ErrStat >= AbortErrLev) STOP - END IF - - !..................................................... - ! Display simulation status every SttsTime-seconds: - !..................................................... + ! Calculate outputs at n + CALL SD_CalcOutput( Time, u(1), p, x, xd, z, OtherState, y, m, ErrStat2, ErrMsg2); call AbortIfFailed() + ! Get state variables at next step: INPUT at step n, OUTPUT at step n + 1 + CALL SD_UpdateStates( Time, n, u, InputTime, p, x, xd, z, OtherState, m, ErrStat2, ErrMsg2); call AbortIfFailed() + ! Display simulation status every SttsTime-seconds: IF ( Time - TiLstPrn >= 1 ) THEN - CALL SimStatus( TiLstPrn, PrevClockTime, Time, TMax ) - ENDIF - END DO + END DO ! Loop on n, time steps - !............................................................................................................................... ! Routine to terminate program execution - !............................................................................................................................... - - CALL SD_End( u(1), p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) + CALL SD_End( u(1), p, x, xd, z, OtherState, y, m, ErrStat2, ErrMsg2) IF ( ErrStat /= ErrID_None ) THEN CALL WrScr( ErrMsg ) END IF - - !............................................................................................................................ - ! Write simulation times and stop - !............................................................................................................................ - + ! Write simulation times and stop CALL RunTimes( StrtTime, UsrTime1, StrtTime, UsrTime1, Time ) CONTAINS + SUBROUTINE AbortIfFailed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SubDyn_Driver') + IF ( ErrStat /= ErrID_None ) THEN + CALL WrScr( ErrMsg ) + END IF + if (ErrStat >= AbortErrLev) then + call CleanUp() + STOP + endif + END SUBROUTINE AbortIfFailed - !------------------------------------------------------------------------------------------------------------------------------- - SUBROUTINE CleanupEchoFile( EchoFlag, UnEcho) - ! The routine cleans up the module echo file and resets the NWTC_Library, reattaching it to - ! any existing echo information - !............................................................................................................................... - LOGICAL, INTENT( IN ) :: EchoFlag ! local version of echo flag - INTEGER, INTENT( IN ) :: UnEcho ! echo unit number - - - ! Close this module's echo file - - IF ( EchoFlag ) THEN - CLOSE(UnEcho) - END IF - - - - END SUBROUTINE CleanupEchoFile - - - !------------------------------------------------------------------------------------------------------------------------------- - SUBROUTINE CheckError(ErrID,Msg) - ! This subroutine sets the error message and level and cleans up if the error is >= AbortErrLev - !............................................................................................................................... - - ! Passed arguments - INTEGER(IntKi), INTENT(IN) :: ErrID ! The error identifier (ErrStat) - CHARACTER(*), INTENT(IN) :: Msg ! The error message (ErrMsg) - - INTEGER(IntKi) :: ErrStat3 ! The error identifier (ErrStat) - CHARACTER(1024) :: ErrMsg3 ! The error message (ErrMsg) - - !............................................................................................................................ - ! Set error status/message; - !............................................................................................................................ - - IF ( ErrID /= ErrID_None ) THEN - - IF ( LEN_TRIM(ErrMsg) > 0 ) ErrMsg = TRIM(ErrMsg)//NewLine - ErrMsg = TRIM(ErrMsg)//' '//TRIM(Msg) - ErrStat = MAX(ErrStat, ErrID) - - !......................................................................................................................... - ! Clean up if we're going to return on error: close files, deallocate local arrays - !......................................................................................................................... - IF ( ErrStat >= AbortErrLev ) THEN - ! CALL CleanupInit(InputFileData, ErrStat3, ErrMsg3 ) - - END IF - - END IF - - - END SUBROUTINE CheckError + SUBROUTINE CleanUp() + if(UnEcho>0) CLOSE(UnEcho) + if(UnEcho>0) CLOSE( UnIn) + if(allocated(SDin)) deallocate(SDin) + END SUBROUTINE CleanUp !------------------------------------------------------------------------------------------------------------------------------- - SUBROUTINE ReadDriverInputFile( inputFile, InitInp, ErrStat, ErrMsg ) - ! - !............................................................................................................................... + SUBROUTINE ReadDriverInputFile( inputFile, InitInp) CHARACTER(*), INTENT( IN ) :: inputFile TYPE(SD_Drvr_InitInput), INTENT( OUT ) :: InitInp - INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - ! Local variables - + ! Local variables INTEGER :: I ! generic integer for counting INTEGER :: J ! generic integer for counting CHARACTER( 2) :: strI ! string version of the loop counter - INTEGER :: UnIn ! Unit number for the input file - INTEGER :: UnEchoLocal ! The local unit number for this module's echo file CHARACTER(1024) :: EchoFile ! Name of SubDyn echo file CHARACTER(1024) :: Line ! String to temporarially hold value of read line CHARACTER(1024) :: TmpPath ! Temporary storage for relative path name @@ -418,365 +268,73 @@ SUBROUTINE ReadDriverInputFile( inputFile, InitInp, ErrStat, ErrMsg ) CHARACTER(1024) :: FileName ! Name of SubDyn input file CHARACTER(1024) :: FilePath ! Path Name of SubDyn input file - UnEChoLocal=-1 + UnEcho=-1 + UnIn =-1 FileName = TRIM(inputFile) CALL GetNewUnit( UnIn ) - CALL OpenFInpFile( UnIn, FileName, ErrStat, ErrMsg ) - - IF ( ErrStat >= AbortErrLev ) THEN - CALL WrScr( 'Failed to open SubDyn Driver input file.') - ErrStat = ErrID_Fatal - CLOSE( UnIn ) - RETURN - END IF - + CALL OpenFInpFile( UnIn, FileName, ErrStat2, ErrMsg2); + call AbortIfFailed() CALL WrScr( 'Opening SubDyn Driver input file: '//FileName ) - - - !------------------------------------------------------------------------------------------------- - ! File header - !------------------------------------------------------------------------------------------------- - - CALL ReadCom( UnIn, FileName, 'SubDyn Driver input file header line 1', ErrStat, ErrMsg ) - - IF ( ErrStat >= AbortErrLev ) THEN - ErrStat = ErrID_Fatal - CLOSE( UnIn ) - RETURN - END IF - - - CALL ReadCom( UnIn, FileName, 'SubDyn Driver input file header line 2', ErrStat, ErrMsg ) - - IF ( ErrStat >= AbortErrLev ) THEN - ErrStat = ErrID_Fatal - CLOSE( UnIn ) - RETURN - END IF - - - ! Echo Input Files. - - CALL ReadVar ( UnIn, FileName, InitInp%Echo, 'Echo', 'Echo Input', ErrStat, ErrMsg ) - - IF ( ErrStat >= AbortErrLev ) THEN - ErrStat = ErrID_Fatal - CLOSE( UnIn ) - RETURN - END IF - - - ! If we are Echoing the input then we should re-read the first three lines so that we can echo them - ! using the NWTC_Library routines. The echoing is done inside those routines via a global variable - ! which we must store, set, and then replace on error or completion. + ! Read until "echo" + CALL ReadCom( UnIn, FileName, 'SubDyn Driver input file header line 1', ErrStat2, ErrMsg2); call AbortIfFailed() + CALL ReadCom( UnIn, FileName, 'SubDyn Driver input file header line 2', ErrStat2, ErrMsg2); call AbortIfFailed() + CALL ReadVar ( UnIn, FileName, InitInp%Echo, 'Echo', 'Echo Input', ErrStat2, ErrMsg2); call AbortIfFailed() + ! If we echo, we rewind IF ( InitInp%Echo ) THEN - EchoFile = TRIM(FileName)//'.echo' - CALL GetNewUnit( UnEchoLocal ) - CALL OpenEcho ( UnEchoLocal, EchoFile, ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) THEN - !ErrMsg = ' Failed to open Echo file.' - ErrStat = ErrID_Fatal - CLOSE( UnIn ) - RETURN - END IF - + CALL GetNewUnit( UnEcho ) + CALL OpenEcho ( UnEcho, EchoFile, ErrStat, ErrMsg ); call AbortIfFailed() REWIND(UnIn) - - CALL ReadCom( UnIn, FileName, 'SubDyn Driver input file header line 1', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read SubDyn Driver input file header line 1.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - CALL ReadCom( UnIn, FileName, 'SubDyn Driver input file header line 2', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read SubDyn Driver input file header line 2.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - ! Echo Input Files. Note this line is prevented from being echoed by the ReadVar routine. - - CALL ReadVar ( UnIn, FileName, InitInp%Echo, 'Echo', 'Echo the input file data', ErrStat, ErrMsg, UnEchoLocal ) - !WRITE (UnEchoLocal,Frmt ) InitInp%Echo, 'Echo', 'Echo input file' - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read Echo parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - END IF - !------------------------------------------------------------------------------------------------- - ! Environmental conditions section - !------------------------------------------------------------------------------------------------- - - ! Header - - CALL ReadCom( UnIn, FileName, 'Environmental conditions header', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read Comment line.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - ! Gravity - Gravity. - - CALL ReadVar ( UnIn, FileName, InitInp%Gravity, 'Gravity', 'Gravity', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read Gravity parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - ! WtrDpth - Gravity. - - CALL ReadVar ( UnIn, FileName, InitInp%WtrDpth, 'WtrDpth', 'WtrDpth', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read WtrDpth parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN + CALL ReadCom( UnIn, FileName, 'SubDyn Driver input file header line 1', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadCom( UnIn, FileName, 'SubDyn Driver input file header line 2', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar ( UnIn, FileName, InitInp%Echo, 'Echo', 'Echo the input file data', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() END IF - !------------------------------------------------------------------------------------------------- - ! SubDyn section - !------------------------------------------------------------------------------------------------- - - ! Header - - CALL ReadCom( UnIn, FileName, 'SubDyn header', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read Comment line.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN + !---------------------- ENVIRONMENTAL CONDITIONS ------------------------------------------------- + CALL ReadCom( UnIn, FileName, 'Environmental conditions header', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%Gravity, 'Gravity', 'Gravity', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%WtrDpth, 'WtrDpth', 'WtrDpth', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + !---------------------- SubDyn ------------------------------------------------------------------- + CALL ReadCom( UnIn, FileName, 'SubDyn header', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%SDInputFile, 'HDInputFile', 'SubDyn input filename', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%OutRootName, 'OutRootName', 'SubDyn output root filename', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%NSteps , 'NSteps', 'Number of time steps in the SubDyn simulation', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%TimeInterval, 'TimeInterval', 'Time interval for any SubDyn inputs', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadAry( UnIn, FileName, InitInp%TP_RefPoint, 3, 'TP reference point', 'TP reference point', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%SubRotateZ, 'SubRotateZ', 'Rotation angle in degrees about Z axis.', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + !---------------------- INPUTS ------------------------------------------------------------------- + CALL ReadCom( UnIn, FileName, 'INPUTS header', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%InputsMod , 'InputsMod', 'Model for the inputs', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%InputsFile, 'InputsFile', 'Filename for the SubDyn inputs', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + !---------------------- STEADY INPUTS (for InputsMod = 1) ---------------------------------------- + CALL ReadCom( UnIn, FileName, 'STEADY STATE INPUTS header', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + IF ( InitInp%InputsMod == 1 ) THEN + CALL ReadAry ( UnIn, FileName, InitInp%uTPInSteady , 6, 'uInSteady', 'Steady-state TP displacements and rotations.', ErrStat2, ErrMsg2, UnEcho) + CALL ReadAry ( UnIn, FileName, InitInp%uDotTPInSteady , 6, 'uDotTPInSteady', 'Steady-state TP translational and rotational velocities.', ErrStat2, ErrMsg2, UnEcho) + CALL ReadAry ( UnIn, FileName, InitInp%uDotDotTPInSteady, 6, 'uDotDotTPInSteady', 'Steady-state TP translational and rotational accelerations.', ErrStat2, ErrMsg2, UnEcho) + ELSE + InitInp%uTPInSteady = 0.0 + InitInp%uDotTPInSteady = 0.0 + InitInp%uDotDotTPInSteady = 0.0 END IF + if(UnEcho>0) CLOSE( UnEcho ) + if(UnIn>0) CLOSE( UnIn ) - - ! HDInputFile - - CALL ReadVar ( UnIn, FileName, InitInp%SDInputFile, 'HDInputFile', & - 'SubDyn input filename', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read SDInputFile parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF + ! Perform input checks and triggers + CALL GetPath( FileName, FilePath ) IF ( PathIsRelative( InitInp%SDInputFile ) ) then - CALL GetPath( FileName, FilePath ) InitInp%SDInputFile = TRIM(FilePath)//TRIM(InitInp%SDInputFile) END IF - - ! OutRootName - - CALL ReadVar ( UnIn, FileName, InitInp%OutRootName, 'OutRootName', & - 'SubDyn output root filename', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read OutRootName parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - ! NSteps - - CALL ReadVar ( UnIn, FileName, InitInp%NSteps, 'NSteps', & - 'Number of time steps in the SubDyn simulation', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read NSteps parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - ! TimeInterval - - CALL ReadVar ( UnIn, FileName, InitInp%TimeInterval, 'TimeInterval', & - 'Time interval for any SubDyn inputs', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read TimeInterval parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - ! TP_RefPoint - - CALL ReadAry ( UnIn, FileName, InitInp%TP_RefPoint, 3, 'TP reference point', & - 'TP reference point', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read TP_RefPoint parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - ! SubRotateZ - - CALL ReadVar ( UnIn, FileName, InitInp%SubRotateZ, 'SubRotateZ', & - 'Rotation angle in degrees about Z axis.', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read SubRotateZ parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - !------------------------------------------------------------------------------------------------- - ! INPUTS section - !------------------------------------------------------------------------------------------------- - - ! Header - - CALL ReadCom( UnIn, FileName, 'INPUTS header', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read Comment line.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - - ! InputsMod - - CALL ReadVar ( UnIn, FileName, InitInp%InputsMod, 'InputsMod', & - 'Model for the inputs', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read InputsMod parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - ! InputsFile - - CALL ReadVar ( UnIn, FileName, InitInp%InputsFile, 'InputsFile', & - 'Filename for the SubDyn inputs', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read InputsFile parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - !------------------------------------------------------------------------------------------------- - ! STEADY STATE INPUTS section - !------------------------------------------------------------------------------------------------- + IF ( PathIsRelative( InitInp%OutRootName ) ) then + InitInp%OutRootName = TRIM(FilePath)//TRIM(InitInp%OutRootName) + endif + IF ( PathIsRelative( InitInp%InputsFile ) ) then + InitInp%InputsFile = TRIM(FilePath)//TRIM(InitInp%InputsFile) + endif - ! Header - - CALL ReadCom( UnIn, FileName, 'STEADY STATE INPUTS header', ErrStat, ErrMsg, UnEchoLocal ) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read Comment line.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - IF ( InitInp%InputsMod == 1 ) THEN - - ! uTPInSteady - - CALL ReadAry ( UnIn, FileName, InitInp%uTPInSteady, 6, 'uInSteady', & - 'Steady-state TP displacements and rotations.', ErrStat, ErrMsg, UnEchoLocal) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read uTPInSteady parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - ! uDotTPInSteady - - CALL ReadAry ( UnIn, FileName, InitInp%uDotTPInSteady, 6, 'uDotTPInSteady', & - ' Steady-state TP translational and rotational velocities.', ErrStat, ErrMsg, UnEchoLocal) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read uDotTPInSteady parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - - - ! uDotDotTPInSteady - - CALL ReadAry ( UnIn, FileName, InitInp%uDotDotTPInSteady, 6, 'uDotDotTPInSteady', & - ' Steady-state TP translational and rotational accelerations.', ErrStat, ErrMsg, UnEchoLocal) - - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read uDotDotTPInSteady parameter.' - ErrStat = ErrID_Fatal - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - RETURN - END IF - ELSE - InitInp%uTPInSteady = 0.0 - InitInp%uDotTPInSteady = 0.0 - InitInp%uDotDotTPInSteady = 0.0 - END IF - - - CALL CleanupEchoFile( InitInp%Echo, UnEchoLocal ) - CLOSE( UnIn ) - END SUBROUTINE ReadDriverInputFile subroutine print_help() @@ -787,7 +345,5 @@ subroutine print_help() print '(a)', 'Where driverfilename is the name of the SubDyn driver input file.' print '(a)', '' end subroutine print_help - !---------------------------------------------------------------------------------------------------------------------------------- - END PROGRAM TestSubDyn diff --git a/modules/subdyn/src/SubDyn_Output.f90 b/modules/subdyn/src/SubDyn_Output.f90 index cbd2913c47..88b05b9be2 100644 --- a/modules/subdyn/src/SubDyn_Output.f90 +++ b/modules/subdyn/src/SubDyn_Output.f90 @@ -18,3741 +18,18 @@ ! !********************************************************************************************************************************** MODULE SubDyn_Output + USE NWTC_Library + USE SubDyn_Types + USE SD_FEM + USE SubDyn_Output_Params, only: MNfmKe, MNfmMe, MNTDss, MNRDe, MNTRAe, IntfSS, IntfTRss, IntfTRAss, ReactSS + USE SubDyn_Output_Params, only: ParamIndxAry, ParamUnitsAry, ValidParamAry, SSqm01, SSqmd01, SSqmdd01 - ! This MODULE stores variables used for output. + IMPLICIT NONE - USE NWTC_Library - USE SubDyn_Types - USE SD_FEM - IMPLICIT NONE - - ! The maximum number of output channels which can be output by the code. + ! The maximum number of output channels which can be output by the code. INTEGER(IntKi),PUBLIC, PARAMETER :: MaxOutPts = 2265 - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 1 - - PRIVATE - - ! Indices for computing output channels: - ! NOTES: - ! (1) These parameters are in the order stored in "OutListParameters.xlsx" - ! (2) Array AllOuts() must be dimensioned to the value of the largest output parameter - - ! Time: - - INTEGER, PARAMETER :: Time = 0 - - - ! Member Forces: - - INTEGER(IntKi), PARAMETER :: M1N1FKxe = 1 - INTEGER(IntKi), PARAMETER :: M1N2FKxe = 2 - INTEGER(IntKi), PARAMETER :: M1N3FKxe = 3 - INTEGER(IntKi), PARAMETER :: M1N4FKxe = 4 - INTEGER(IntKi), PARAMETER :: M1N5FKxe = 5 - INTEGER(IntKi), PARAMETER :: M1N6FKxe = 6 - INTEGER(IntKi), PARAMETER :: M1N7FKxe = 7 - INTEGER(IntKi), PARAMETER :: M1N8FKxe = 8 - INTEGER(IntKi), PARAMETER :: M1N9FKxe = 9 - INTEGER(IntKi), PARAMETER :: M2N1FKxe = 10 - INTEGER(IntKi), PARAMETER :: M2N2FKxe = 11 - INTEGER(IntKi), PARAMETER :: M2N3FKxe = 12 - INTEGER(IntKi), PARAMETER :: M2N4FKxe = 13 - INTEGER(IntKi), PARAMETER :: M2N5FKxe = 14 - INTEGER(IntKi), PARAMETER :: M2N6FKxe = 15 - INTEGER(IntKi), PARAMETER :: M2N7FKxe = 16 - INTEGER(IntKi), PARAMETER :: M2N8FKxe = 17 - INTEGER(IntKi), PARAMETER :: M2N9FKxe = 18 - INTEGER(IntKi), PARAMETER :: M3N1FKxe = 19 - INTEGER(IntKi), PARAMETER :: M3N2FKxe = 20 - INTEGER(IntKi), PARAMETER :: M3N3FKxe = 21 - INTEGER(IntKi), PARAMETER :: M3N4FKxe = 22 - INTEGER(IntKi), PARAMETER :: M3N5FKxe = 23 - INTEGER(IntKi), PARAMETER :: M3N6FKxe = 24 - INTEGER(IntKi), PARAMETER :: M3N7FKxe = 25 - INTEGER(IntKi), PARAMETER :: M3N8FKxe = 26 - INTEGER(IntKi), PARAMETER :: M3N9FKxe = 27 - INTEGER(IntKi), PARAMETER :: M4N1FKxe = 28 - INTEGER(IntKi), PARAMETER :: M4N2FKxe = 29 - INTEGER(IntKi), PARAMETER :: M4N3FKxe = 30 - INTEGER(IntKi), PARAMETER :: M4N4FKxe = 31 - INTEGER(IntKi), PARAMETER :: M4N5FKxe = 32 - INTEGER(IntKi), PARAMETER :: M4N6FKxe = 33 - INTEGER(IntKi), PARAMETER :: M4N7FKxe = 34 - INTEGER(IntKi), PARAMETER :: M4N8FKxe = 35 - INTEGER(IntKi), PARAMETER :: M4N9FKxe = 36 - INTEGER(IntKi), PARAMETER :: M5N1FKxe = 37 - INTEGER(IntKi), PARAMETER :: M5N2FKxe = 38 - INTEGER(IntKi), PARAMETER :: M5N3FKxe = 39 - INTEGER(IntKi), PARAMETER :: M5N4FKxe = 40 - INTEGER(IntKi), PARAMETER :: M5N5FKxe = 41 - INTEGER(IntKi), PARAMETER :: M5N6FKxe = 42 - INTEGER(IntKi), PARAMETER :: M5N7FKxe = 43 - INTEGER(IntKi), PARAMETER :: M5N8FKxe = 44 - INTEGER(IntKi), PARAMETER :: M5N9FKxe = 45 - INTEGER(IntKi), PARAMETER :: M6N1FKxe = 46 - INTEGER(IntKi), PARAMETER :: M6N2FKxe = 47 - INTEGER(IntKi), PARAMETER :: M6N3FKxe = 48 - INTEGER(IntKi), PARAMETER :: M6N4FKxe = 49 - INTEGER(IntKi), PARAMETER :: M6N5FKxe = 50 - INTEGER(IntKi), PARAMETER :: M6N6FKxe = 51 - INTEGER(IntKi), PARAMETER :: M6N7FKxe = 52 - INTEGER(IntKi), PARAMETER :: M6N8FKxe = 53 - INTEGER(IntKi), PARAMETER :: M6N9FKxe = 54 - INTEGER(IntKi), PARAMETER :: M7N1FKxe = 55 - INTEGER(IntKi), PARAMETER :: M7N2FKxe = 56 - INTEGER(IntKi), PARAMETER :: M7N3FKxe = 57 - INTEGER(IntKi), PARAMETER :: M7N4FKxe = 58 - INTEGER(IntKi), PARAMETER :: M7N5FKxe = 59 - INTEGER(IntKi), PARAMETER :: M7N6FKxe = 60 - INTEGER(IntKi), PARAMETER :: M7N7FKxe = 61 - INTEGER(IntKi), PARAMETER :: M7N8FKxe = 62 - INTEGER(IntKi), PARAMETER :: M7N9FKxe = 63 - INTEGER(IntKi), PARAMETER :: M8N1FKxe = 64 - INTEGER(IntKi), PARAMETER :: M8N2FKxe = 65 - INTEGER(IntKi), PARAMETER :: M8N3FKxe = 66 - INTEGER(IntKi), PARAMETER :: M8N4FKxe = 67 - INTEGER(IntKi), PARAMETER :: M8N5FKxe = 68 - INTEGER(IntKi), PARAMETER :: M8N6FKxe = 69 - INTEGER(IntKi), PARAMETER :: M8N7FKxe = 70 - INTEGER(IntKi), PARAMETER :: M8N8FKxe = 71 - INTEGER(IntKi), PARAMETER :: M8N9FKxe = 72 - INTEGER(IntKi), PARAMETER :: M9N1FKxe = 73 - INTEGER(IntKi), PARAMETER :: M9N2FKxe = 74 - INTEGER(IntKi), PARAMETER :: M9N3FKxe = 75 - INTEGER(IntKi), PARAMETER :: M9N4FKxe = 76 - INTEGER(IntKi), PARAMETER :: M9N5FKxe = 77 - INTEGER(IntKi), PARAMETER :: M9N6FKxe = 78 - INTEGER(IntKi), PARAMETER :: M9N7FKxe = 79 - INTEGER(IntKi), PARAMETER :: M9N8FKxe = 80 - INTEGER(IntKi), PARAMETER :: M9N9FKxe = 81 - INTEGER(IntKi), PARAMETER :: M1N1FKye = 82 - INTEGER(IntKi), PARAMETER :: M1N2FKye = 83 - INTEGER(IntKi), PARAMETER :: M1N3FKye = 84 - INTEGER(IntKi), PARAMETER :: M1N4FKye = 85 - INTEGER(IntKi), PARAMETER :: M1N5FKye = 86 - INTEGER(IntKi), PARAMETER :: M1N6FKye = 87 - INTEGER(IntKi), PARAMETER :: M1N7FKye = 88 - INTEGER(IntKi), PARAMETER :: M1N8FKye = 89 - INTEGER(IntKi), PARAMETER :: M1N9FKye = 90 - INTEGER(IntKi), PARAMETER :: M2N1FKye = 91 - INTEGER(IntKi), PARAMETER :: M2N2FKye = 92 - INTEGER(IntKi), PARAMETER :: M2N3FKye = 93 - INTEGER(IntKi), PARAMETER :: M2N4FKye = 94 - INTEGER(IntKi), PARAMETER :: M2N5FKye = 95 - INTEGER(IntKi), PARAMETER :: M2N6FKye = 96 - INTEGER(IntKi), PARAMETER :: M2N7FKye = 97 - INTEGER(IntKi), PARAMETER :: M2N8FKye = 98 - INTEGER(IntKi), PARAMETER :: M2N9FKye = 99 - INTEGER(IntKi), PARAMETER :: M3N1FKye = 100 - INTEGER(IntKi), PARAMETER :: M3N2FKye = 101 - INTEGER(IntKi), PARAMETER :: M3N3FKye = 102 - INTEGER(IntKi), PARAMETER :: M3N4FKye = 103 - INTEGER(IntKi), PARAMETER :: M3N5FKye = 104 - INTEGER(IntKi), PARAMETER :: M3N6FKye = 105 - INTEGER(IntKi), PARAMETER :: M3N7FKye = 106 - INTEGER(IntKi), PARAMETER :: M3N8FKye = 107 - INTEGER(IntKi), PARAMETER :: M3N9FKye = 108 - INTEGER(IntKi), PARAMETER :: M4N1FKye = 109 - INTEGER(IntKi), PARAMETER :: M4N2FKye = 110 - INTEGER(IntKi), PARAMETER :: M4N3FKye = 111 - INTEGER(IntKi), PARAMETER :: M4N4FKye = 112 - INTEGER(IntKi), PARAMETER :: M4N5FKye = 113 - INTEGER(IntKi), PARAMETER :: M4N6FKye = 114 - INTEGER(IntKi), PARAMETER :: M4N7FKye = 115 - INTEGER(IntKi), PARAMETER :: M4N8FKye = 116 - INTEGER(IntKi), PARAMETER :: M4N9FKye = 117 - INTEGER(IntKi), PARAMETER :: M5N1FKye = 118 - INTEGER(IntKi), PARAMETER :: M5N2FKye = 119 - INTEGER(IntKi), PARAMETER :: M5N3FKye = 120 - INTEGER(IntKi), PARAMETER :: M5N4FKye = 121 - INTEGER(IntKi), PARAMETER :: M5N5FKye = 122 - INTEGER(IntKi), PARAMETER :: M5N6FKye = 123 - INTEGER(IntKi), PARAMETER :: M5N7FKye = 124 - INTEGER(IntKi), PARAMETER :: M5N8FKye = 125 - INTEGER(IntKi), PARAMETER :: M5N9FKye = 126 - INTEGER(IntKi), PARAMETER :: M6N1FKye = 127 - INTEGER(IntKi), PARAMETER :: M6N2FKye = 128 - INTEGER(IntKi), PARAMETER :: M6N3FKye = 129 - INTEGER(IntKi), PARAMETER :: M6N4FKye = 130 - INTEGER(IntKi), PARAMETER :: M6N5FKye = 131 - INTEGER(IntKi), PARAMETER :: M6N6FKye = 132 - INTEGER(IntKi), PARAMETER :: M6N7FKye = 133 - INTEGER(IntKi), PARAMETER :: M6N8FKye = 134 - INTEGER(IntKi), PARAMETER :: M6N9FKye = 135 - INTEGER(IntKi), PARAMETER :: M7N1FKye = 136 - INTEGER(IntKi), PARAMETER :: M7N2FKye = 137 - INTEGER(IntKi), PARAMETER :: M7N3FKye = 138 - INTEGER(IntKi), PARAMETER :: M7N4FKye = 139 - INTEGER(IntKi), PARAMETER :: M7N5FKye = 140 - INTEGER(IntKi), PARAMETER :: M7N6FKye = 141 - INTEGER(IntKi), PARAMETER :: M7N7FKye = 142 - INTEGER(IntKi), PARAMETER :: M7N8FKye = 143 - INTEGER(IntKi), PARAMETER :: M7N9FKye = 144 - INTEGER(IntKi), PARAMETER :: M8N1FKye = 145 - INTEGER(IntKi), PARAMETER :: M8N2FKye = 146 - INTEGER(IntKi), PARAMETER :: M8N3FKye = 147 - INTEGER(IntKi), PARAMETER :: M8N4FKye = 148 - INTEGER(IntKi), PARAMETER :: M8N5FKye = 149 - INTEGER(IntKi), PARAMETER :: M8N6FKye = 150 - INTEGER(IntKi), PARAMETER :: M8N7FKye = 151 - INTEGER(IntKi), PARAMETER :: M8N8FKye = 152 - INTEGER(IntKi), PARAMETER :: M8N9FKye = 153 - INTEGER(IntKi), PARAMETER :: M9N1FKye = 154 - INTEGER(IntKi), PARAMETER :: M9N2FKye = 155 - INTEGER(IntKi), PARAMETER :: M9N3FKye = 156 - INTEGER(IntKi), PARAMETER :: M9N4FKye = 157 - INTEGER(IntKi), PARAMETER :: M9N5FKye = 158 - INTEGER(IntKi), PARAMETER :: M9N6FKye = 159 - INTEGER(IntKi), PARAMETER :: M9N7FKye = 160 - INTEGER(IntKi), PARAMETER :: M9N8FKye = 161 - INTEGER(IntKi), PARAMETER :: M9N9FKye = 162 - INTEGER(IntKi), PARAMETER :: M1N1FKze = 163 - INTEGER(IntKi), PARAMETER :: M1N2FKze = 164 - INTEGER(IntKi), PARAMETER :: M1N3FKze = 165 - INTEGER(IntKi), PARAMETER :: M1N4FKze = 166 - INTEGER(IntKi), PARAMETER :: M1N5FKze = 167 - INTEGER(IntKi), PARAMETER :: M1N6FKze = 168 - INTEGER(IntKi), PARAMETER :: M1N7FKze = 169 - INTEGER(IntKi), PARAMETER :: M1N8FKze = 170 - INTEGER(IntKi), PARAMETER :: M1N9FKze = 171 - INTEGER(IntKi), PARAMETER :: M2N1FKze = 172 - INTEGER(IntKi), PARAMETER :: M2N2FKze = 173 - INTEGER(IntKi), PARAMETER :: M2N3FKze = 174 - INTEGER(IntKi), PARAMETER :: M2N4FKze = 175 - INTEGER(IntKi), PARAMETER :: M2N5FKze = 176 - INTEGER(IntKi), PARAMETER :: M2N6FKze = 177 - INTEGER(IntKi), PARAMETER :: M2N7FKze = 178 - INTEGER(IntKi), PARAMETER :: M2N8FKze = 179 - INTEGER(IntKi), PARAMETER :: M2N9FKze = 180 - INTEGER(IntKi), PARAMETER :: M3N1FKze = 181 - INTEGER(IntKi), PARAMETER :: M3N2FKze = 182 - INTEGER(IntKi), PARAMETER :: M3N3FKze = 183 - INTEGER(IntKi), PARAMETER :: M3N4FKze = 184 - INTEGER(IntKi), PARAMETER :: M3N5FKze = 185 - INTEGER(IntKi), PARAMETER :: M3N6FKze = 186 - INTEGER(IntKi), PARAMETER :: M3N7FKze = 187 - INTEGER(IntKi), PARAMETER :: M3N8FKze = 188 - INTEGER(IntKi), PARAMETER :: M3N9FKze = 189 - INTEGER(IntKi), PARAMETER :: M4N1FKze = 190 - INTEGER(IntKi), PARAMETER :: M4N2FKze = 191 - INTEGER(IntKi), PARAMETER :: M4N3FKze = 192 - INTEGER(IntKi), PARAMETER :: M4N4FKze = 193 - INTEGER(IntKi), PARAMETER :: M4N5FKze = 194 - INTEGER(IntKi), PARAMETER :: M4N6FKze = 195 - INTEGER(IntKi), PARAMETER :: M4N7FKze = 196 - INTEGER(IntKi), PARAMETER :: M4N8FKze = 197 - INTEGER(IntKi), PARAMETER :: M4N9FKze = 198 - INTEGER(IntKi), PARAMETER :: M5N1FKze = 199 - INTEGER(IntKi), PARAMETER :: M5N2FKze = 200 - INTEGER(IntKi), PARAMETER :: M5N3FKze = 201 - INTEGER(IntKi), PARAMETER :: M5N4FKze = 202 - INTEGER(IntKi), PARAMETER :: M5N5FKze = 203 - INTEGER(IntKi), PARAMETER :: M5N6FKze = 204 - INTEGER(IntKi), PARAMETER :: M5N7FKze = 205 - INTEGER(IntKi), PARAMETER :: M5N8FKze = 206 - INTEGER(IntKi), PARAMETER :: M5N9FKze = 207 - INTEGER(IntKi), PARAMETER :: M6N1FKze = 208 - INTEGER(IntKi), PARAMETER :: M6N2FKze = 209 - INTEGER(IntKi), PARAMETER :: M6N3FKze = 210 - INTEGER(IntKi), PARAMETER :: M6N4FKze = 211 - INTEGER(IntKi), PARAMETER :: M6N5FKze = 212 - INTEGER(IntKi), PARAMETER :: M6N6FKze = 213 - INTEGER(IntKi), PARAMETER :: M6N7FKze = 214 - INTEGER(IntKi), PARAMETER :: M6N8FKze = 215 - INTEGER(IntKi), PARAMETER :: M6N9FKze = 216 - INTEGER(IntKi), PARAMETER :: M7N1FKze = 217 - INTEGER(IntKi), PARAMETER :: M7N2FKze = 218 - INTEGER(IntKi), PARAMETER :: M7N3FKze = 219 - INTEGER(IntKi), PARAMETER :: M7N4FKze = 220 - INTEGER(IntKi), PARAMETER :: M7N5FKze = 221 - INTEGER(IntKi), PARAMETER :: M7N6FKze = 222 - INTEGER(IntKi), PARAMETER :: M7N7FKze = 223 - INTEGER(IntKi), PARAMETER :: M7N8FKze = 224 - INTEGER(IntKi), PARAMETER :: M7N9FKze = 225 - INTEGER(IntKi), PARAMETER :: M8N1FKze = 226 - INTEGER(IntKi), PARAMETER :: M8N2FKze = 227 - INTEGER(IntKi), PARAMETER :: M8N3FKze = 228 - INTEGER(IntKi), PARAMETER :: M8N4FKze = 229 - INTEGER(IntKi), PARAMETER :: M8N5FKze = 230 - INTEGER(IntKi), PARAMETER :: M8N6FKze = 231 - INTEGER(IntKi), PARAMETER :: M8N7FKze = 232 - INTEGER(IntKi), PARAMETER :: M8N8FKze = 233 - INTEGER(IntKi), PARAMETER :: M8N9FKze = 234 - INTEGER(IntKi), PARAMETER :: M9N1FKze = 235 - INTEGER(IntKi), PARAMETER :: M9N2FKze = 236 - INTEGER(IntKi), PARAMETER :: M9N3FKze = 237 - INTEGER(IntKi), PARAMETER :: M9N4FKze = 238 - INTEGER(IntKi), PARAMETER :: M9N5FKze = 239 - INTEGER(IntKi), PARAMETER :: M9N6FKze = 240 - INTEGER(IntKi), PARAMETER :: M9N7FKze = 241 - INTEGER(IntKi), PARAMETER :: M9N8FKze = 242 - INTEGER(IntKi), PARAMETER :: M9N9FKze = 243 - INTEGER(IntKi), PARAMETER :: M1N1FMxe = 244 - INTEGER(IntKi), PARAMETER :: M1N2FMxe = 245 - INTEGER(IntKi), PARAMETER :: M1N3FMxe = 246 - INTEGER(IntKi), PARAMETER :: M1N4FMxe = 247 - INTEGER(IntKi), PARAMETER :: M1N5FMxe = 248 - INTEGER(IntKi), PARAMETER :: M1N6FMxe = 249 - INTEGER(IntKi), PARAMETER :: M1N7FMxe = 250 - INTEGER(IntKi), PARAMETER :: M1N8FMxe = 251 - INTEGER(IntKi), PARAMETER :: M1N9FMxe = 252 - INTEGER(IntKi), PARAMETER :: M2N1FMxe = 253 - INTEGER(IntKi), PARAMETER :: M2N2FMxe = 254 - INTEGER(IntKi), PARAMETER :: M2N3FMxe = 255 - INTEGER(IntKi), PARAMETER :: M2N4FMxe = 256 - INTEGER(IntKi), PARAMETER :: M2N5FMxe = 257 - INTEGER(IntKi), PARAMETER :: M2N6FMxe = 258 - INTEGER(IntKi), PARAMETER :: M2N7FMxe = 259 - INTEGER(IntKi), PARAMETER :: M2N8FMxe = 260 - INTEGER(IntKi), PARAMETER :: M2N9FMxe = 261 - INTEGER(IntKi), PARAMETER :: M3N1FMxe = 262 - INTEGER(IntKi), PARAMETER :: M3N2FMxe = 263 - INTEGER(IntKi), PARAMETER :: M3N3FMxe = 264 - INTEGER(IntKi), PARAMETER :: M3N4FMxe = 265 - INTEGER(IntKi), PARAMETER :: M3N5FMxe = 266 - INTEGER(IntKi), PARAMETER :: M3N6FMxe = 267 - INTEGER(IntKi), PARAMETER :: M3N7FMxe = 268 - INTEGER(IntKi), PARAMETER :: M3N8FMxe = 269 - INTEGER(IntKi), PARAMETER :: M3N9FMxe = 270 - INTEGER(IntKi), PARAMETER :: M4N1FMxe = 271 - INTEGER(IntKi), PARAMETER :: M4N2FMxe = 272 - INTEGER(IntKi), PARAMETER :: M4N3FMxe = 273 - INTEGER(IntKi), PARAMETER :: M4N4FMxe = 274 - INTEGER(IntKi), PARAMETER :: M4N5FMxe = 275 - INTEGER(IntKi), PARAMETER :: M4N6FMxe = 276 - INTEGER(IntKi), PARAMETER :: M4N7FMxe = 277 - INTEGER(IntKi), PARAMETER :: M4N8FMxe = 278 - INTEGER(IntKi), PARAMETER :: M4N9FMxe = 279 - INTEGER(IntKi), PARAMETER :: M5N1FMxe = 280 - INTEGER(IntKi), PARAMETER :: M5N2FMxe = 281 - INTEGER(IntKi), PARAMETER :: M5N3FMxe = 282 - INTEGER(IntKi), PARAMETER :: M5N4FMxe = 283 - INTEGER(IntKi), PARAMETER :: M5N5FMxe = 284 - INTEGER(IntKi), PARAMETER :: M5N6FMxe = 285 - INTEGER(IntKi), PARAMETER :: M5N7FMxe = 286 - INTEGER(IntKi), PARAMETER :: M5N8FMxe = 287 - INTEGER(IntKi), PARAMETER :: M5N9FMxe = 288 - INTEGER(IntKi), PARAMETER :: M6N1FMxe = 289 - INTEGER(IntKi), PARAMETER :: M6N2FMxe = 290 - INTEGER(IntKi), PARAMETER :: M6N3FMxe = 291 - INTEGER(IntKi), PARAMETER :: M6N4FMxe = 292 - INTEGER(IntKi), PARAMETER :: M6N5FMxe = 293 - INTEGER(IntKi), PARAMETER :: M6N6FMxe = 294 - INTEGER(IntKi), PARAMETER :: M6N7FMxe = 295 - INTEGER(IntKi), PARAMETER :: M6N8FMxe = 296 - INTEGER(IntKi), PARAMETER :: M6N9FMxe = 297 - INTEGER(IntKi), PARAMETER :: M7N1FMxe = 298 - INTEGER(IntKi), PARAMETER :: M7N2FMxe = 299 - INTEGER(IntKi), PARAMETER :: M7N3FMxe = 300 - INTEGER(IntKi), PARAMETER :: M7N4FMxe = 301 - INTEGER(IntKi), PARAMETER :: M7N5FMxe = 302 - INTEGER(IntKi), PARAMETER :: M7N6FMxe = 303 - INTEGER(IntKi), PARAMETER :: M7N7FMxe = 304 - INTEGER(IntKi), PARAMETER :: M7N8FMxe = 305 - INTEGER(IntKi), PARAMETER :: M7N9FMxe = 306 - INTEGER(IntKi), PARAMETER :: M8N1FMxe = 307 - INTEGER(IntKi), PARAMETER :: M8N2FMxe = 308 - INTEGER(IntKi), PARAMETER :: M8N3FMxe = 309 - INTEGER(IntKi), PARAMETER :: M8N4FMxe = 310 - INTEGER(IntKi), PARAMETER :: M8N5FMxe = 311 - INTEGER(IntKi), PARAMETER :: M8N6FMxe = 312 - INTEGER(IntKi), PARAMETER :: M8N7FMxe = 313 - INTEGER(IntKi), PARAMETER :: M8N8FMxe = 314 - INTEGER(IntKi), PARAMETER :: M8N9FMxe = 315 - INTEGER(IntKi), PARAMETER :: M9N1FMxe = 316 - INTEGER(IntKi), PARAMETER :: M9N2FMxe = 317 - INTEGER(IntKi), PARAMETER :: M9N3FMxe = 318 - INTEGER(IntKi), PARAMETER :: M9N4FMxe = 319 - INTEGER(IntKi), PARAMETER :: M9N5FMxe = 320 - INTEGER(IntKi), PARAMETER :: M9N6FMxe = 321 - INTEGER(IntKi), PARAMETER :: M9N7FMxe = 322 - INTEGER(IntKi), PARAMETER :: M9N8FMxe = 323 - INTEGER(IntKi), PARAMETER :: M9N9FMxe = 324 - INTEGER(IntKi), PARAMETER :: M1N1FMye = 325 - INTEGER(IntKi), PARAMETER :: M1N2FMye = 326 - INTEGER(IntKi), PARAMETER :: M1N3FMye = 327 - INTEGER(IntKi), PARAMETER :: M1N4FMye = 328 - INTEGER(IntKi), PARAMETER :: M1N5FMye = 329 - INTEGER(IntKi), PARAMETER :: M1N6FMye = 330 - INTEGER(IntKi), PARAMETER :: M1N7FMye = 331 - INTEGER(IntKi), PARAMETER :: M1N8FMye = 332 - INTEGER(IntKi), PARAMETER :: M1N9FMye = 333 - INTEGER(IntKi), PARAMETER :: M2N1FMye = 334 - INTEGER(IntKi), PARAMETER :: M2N2FMye = 335 - INTEGER(IntKi), PARAMETER :: M2N3FMye = 336 - INTEGER(IntKi), PARAMETER :: M2N4FMye = 337 - INTEGER(IntKi), PARAMETER :: M2N5FMye = 338 - INTEGER(IntKi), PARAMETER :: M2N6FMye = 339 - INTEGER(IntKi), PARAMETER :: M2N7FMye = 340 - INTEGER(IntKi), PARAMETER :: M2N8FMye = 341 - INTEGER(IntKi), PARAMETER :: M2N9FMye = 342 - INTEGER(IntKi), PARAMETER :: M3N1FMye = 343 - INTEGER(IntKi), PARAMETER :: M3N2FMye = 344 - INTEGER(IntKi), PARAMETER :: M3N3FMye = 345 - INTEGER(IntKi), PARAMETER :: M3N4FMye = 346 - INTEGER(IntKi), PARAMETER :: M3N5FMye = 347 - INTEGER(IntKi), PARAMETER :: M3N6FMye = 348 - INTEGER(IntKi), PARAMETER :: M3N7FMye = 349 - INTEGER(IntKi), PARAMETER :: M3N8FMye = 350 - INTEGER(IntKi), PARAMETER :: M3N9FMye = 351 - INTEGER(IntKi), PARAMETER :: M4N1FMye = 352 - INTEGER(IntKi), PARAMETER :: M4N2FMye = 353 - INTEGER(IntKi), PARAMETER :: M4N3FMye = 354 - INTEGER(IntKi), PARAMETER :: M4N4FMye = 355 - INTEGER(IntKi), PARAMETER :: M4N5FMye = 356 - INTEGER(IntKi), PARAMETER :: M4N6FMye = 357 - INTEGER(IntKi), PARAMETER :: M4N7FMye = 358 - INTEGER(IntKi), PARAMETER :: M4N8FMye = 359 - INTEGER(IntKi), PARAMETER :: M4N9FMye = 360 - INTEGER(IntKi), PARAMETER :: M5N1FMye = 361 - INTEGER(IntKi), PARAMETER :: M5N2FMye = 362 - INTEGER(IntKi), PARAMETER :: M5N3FMye = 363 - INTEGER(IntKi), PARAMETER :: M5N4FMye = 364 - INTEGER(IntKi), PARAMETER :: M5N5FMye = 365 - INTEGER(IntKi), PARAMETER :: M5N6FMye = 366 - INTEGER(IntKi), PARAMETER :: M5N7FMye = 367 - INTEGER(IntKi), PARAMETER :: M5N8FMye = 368 - INTEGER(IntKi), PARAMETER :: M5N9FMye = 369 - INTEGER(IntKi), PARAMETER :: M6N1FMye = 370 - INTEGER(IntKi), PARAMETER :: M6N2FMye = 371 - INTEGER(IntKi), PARAMETER :: M6N3FMye = 372 - INTEGER(IntKi), PARAMETER :: M6N4FMye = 373 - INTEGER(IntKi), PARAMETER :: M6N5FMye = 374 - INTEGER(IntKi), PARAMETER :: M6N6FMye = 375 - INTEGER(IntKi), PARAMETER :: M6N7FMye = 376 - INTEGER(IntKi), PARAMETER :: M6N8FMye = 377 - INTEGER(IntKi), PARAMETER :: M6N9FMye = 378 - INTEGER(IntKi), PARAMETER :: M7N1FMye = 379 - INTEGER(IntKi), PARAMETER :: M7N2FMye = 380 - INTEGER(IntKi), PARAMETER :: M7N3FMye = 381 - INTEGER(IntKi), PARAMETER :: M7N4FMye = 382 - INTEGER(IntKi), PARAMETER :: M7N5FMye = 383 - INTEGER(IntKi), PARAMETER :: M7N6FMye = 384 - INTEGER(IntKi), PARAMETER :: M7N7FMye = 385 - INTEGER(IntKi), PARAMETER :: M7N8FMye = 386 - INTEGER(IntKi), PARAMETER :: M7N9FMye = 387 - INTEGER(IntKi), PARAMETER :: M8N1FMye = 388 - INTEGER(IntKi), PARAMETER :: M8N2FMye = 389 - INTEGER(IntKi), PARAMETER :: M8N3FMye = 390 - INTEGER(IntKi), PARAMETER :: M8N4FMye = 391 - INTEGER(IntKi), PARAMETER :: M8N5FMye = 392 - INTEGER(IntKi), PARAMETER :: M8N6FMye = 393 - INTEGER(IntKi), PARAMETER :: M8N7FMye = 394 - INTEGER(IntKi), PARAMETER :: M8N8FMye = 395 - INTEGER(IntKi), PARAMETER :: M8N9FMye = 396 - INTEGER(IntKi), PARAMETER :: M9N1FMye = 397 - INTEGER(IntKi), PARAMETER :: M9N2FMye = 398 - INTEGER(IntKi), PARAMETER :: M9N3FMye = 399 - INTEGER(IntKi), PARAMETER :: M9N4FMye = 400 - INTEGER(IntKi), PARAMETER :: M9N5FMye = 401 - INTEGER(IntKi), PARAMETER :: M9N6FMye = 402 - INTEGER(IntKi), PARAMETER :: M9N7FMye = 403 - INTEGER(IntKi), PARAMETER :: M9N8FMye = 404 - INTEGER(IntKi), PARAMETER :: M9N9FMye = 405 - INTEGER(IntKi), PARAMETER :: M1N1FMze = 406 - INTEGER(IntKi), PARAMETER :: M1N2FMze = 407 - INTEGER(IntKi), PARAMETER :: M1N3FMze = 408 - INTEGER(IntKi), PARAMETER :: M1N4FMze = 409 - INTEGER(IntKi), PARAMETER :: M1N5FMze = 410 - INTEGER(IntKi), PARAMETER :: M1N6FMze = 411 - INTEGER(IntKi), PARAMETER :: M1N7FMze = 412 - INTEGER(IntKi), PARAMETER :: M1N8FMze = 413 - INTEGER(IntKi), PARAMETER :: M1N9FMze = 414 - INTEGER(IntKi), PARAMETER :: M2N1FMze = 415 - INTEGER(IntKi), PARAMETER :: M2N2FMze = 416 - INTEGER(IntKi), PARAMETER :: M2N3FMze = 417 - INTEGER(IntKi), PARAMETER :: M2N4FMze = 418 - INTEGER(IntKi), PARAMETER :: M2N5FMze = 419 - INTEGER(IntKi), PARAMETER :: M2N6FMze = 420 - INTEGER(IntKi), PARAMETER :: M2N7FMze = 421 - INTEGER(IntKi), PARAMETER :: M2N8FMze = 422 - INTEGER(IntKi), PARAMETER :: M2N9FMze = 423 - INTEGER(IntKi), PARAMETER :: M3N1FMze = 424 - INTEGER(IntKi), PARAMETER :: M3N2FMze = 425 - INTEGER(IntKi), PARAMETER :: M3N3FMze = 426 - INTEGER(IntKi), PARAMETER :: M3N4FMze = 427 - INTEGER(IntKi), PARAMETER :: M3N5FMze = 428 - INTEGER(IntKi), PARAMETER :: M3N6FMze = 429 - INTEGER(IntKi), PARAMETER :: M3N7FMze = 430 - INTEGER(IntKi), PARAMETER :: M3N8FMze = 431 - INTEGER(IntKi), PARAMETER :: M3N9FMze = 432 - INTEGER(IntKi), PARAMETER :: M4N1FMze = 433 - INTEGER(IntKi), PARAMETER :: M4N2FMze = 434 - INTEGER(IntKi), PARAMETER :: M4N3FMze = 435 - INTEGER(IntKi), PARAMETER :: M4N4FMze = 436 - INTEGER(IntKi), PARAMETER :: M4N5FMze = 437 - INTEGER(IntKi), PARAMETER :: M4N6FMze = 438 - INTEGER(IntKi), PARAMETER :: M4N7FMze = 439 - INTEGER(IntKi), PARAMETER :: M4N8FMze = 440 - INTEGER(IntKi), PARAMETER :: M4N9FMze = 441 - INTEGER(IntKi), PARAMETER :: M5N1FMze = 442 - INTEGER(IntKi), PARAMETER :: M5N2FMze = 443 - INTEGER(IntKi), PARAMETER :: M5N3FMze = 444 - INTEGER(IntKi), PARAMETER :: M5N4FMze = 445 - INTEGER(IntKi), PARAMETER :: M5N5FMze = 446 - INTEGER(IntKi), PARAMETER :: M5N6FMze = 447 - INTEGER(IntKi), PARAMETER :: M5N7FMze = 448 - INTEGER(IntKi), PARAMETER :: M5N8FMze = 449 - INTEGER(IntKi), PARAMETER :: M5N9FMze = 450 - INTEGER(IntKi), PARAMETER :: M6N1FMze = 451 - INTEGER(IntKi), PARAMETER :: M6N2FMze = 452 - INTEGER(IntKi), PARAMETER :: M6N3FMze = 453 - INTEGER(IntKi), PARAMETER :: M6N4FMze = 454 - INTEGER(IntKi), PARAMETER :: M6N5FMze = 455 - INTEGER(IntKi), PARAMETER :: M6N6FMze = 456 - INTEGER(IntKi), PARAMETER :: M6N7FMze = 457 - INTEGER(IntKi), PARAMETER :: M6N8FMze = 458 - INTEGER(IntKi), PARAMETER :: M6N9FMze = 459 - INTEGER(IntKi), PARAMETER :: M7N1FMze = 460 - INTEGER(IntKi), PARAMETER :: M7N2FMze = 461 - INTEGER(IntKi), PARAMETER :: M7N3FMze = 462 - INTEGER(IntKi), PARAMETER :: M7N4FMze = 463 - INTEGER(IntKi), PARAMETER :: M7N5FMze = 464 - INTEGER(IntKi), PARAMETER :: M7N6FMze = 465 - INTEGER(IntKi), PARAMETER :: M7N7FMze = 466 - INTEGER(IntKi), PARAMETER :: M7N8FMze = 467 - INTEGER(IntKi), PARAMETER :: M7N9FMze = 468 - INTEGER(IntKi), PARAMETER :: M8N1FMze = 469 - INTEGER(IntKi), PARAMETER :: M8N2FMze = 470 - INTEGER(IntKi), PARAMETER :: M8N3FMze = 471 - INTEGER(IntKi), PARAMETER :: M8N4FMze = 472 - INTEGER(IntKi), PARAMETER :: M8N5FMze = 473 - INTEGER(IntKi), PARAMETER :: M8N6FMze = 474 - INTEGER(IntKi), PARAMETER :: M8N7FMze = 475 - INTEGER(IntKi), PARAMETER :: M8N8FMze = 476 - INTEGER(IntKi), PARAMETER :: M8N9FMze = 477 - INTEGER(IntKi), PARAMETER :: M9N1FMze = 478 - INTEGER(IntKi), PARAMETER :: M9N2FMze = 479 - INTEGER(IntKi), PARAMETER :: M9N3FMze = 480 - INTEGER(IntKi), PARAMETER :: M9N4FMze = 481 - INTEGER(IntKi), PARAMETER :: M9N5FMze = 482 - INTEGER(IntKi), PARAMETER :: M9N6FMze = 483 - INTEGER(IntKi), PARAMETER :: M9N7FMze = 484 - INTEGER(IntKi), PARAMETER :: M9N8FMze = 485 - INTEGER(IntKi), PARAMETER :: M9N9FMze = 486 - INTEGER(IntKi), PARAMETER :: M1N1MKxe = 487 - INTEGER(IntKi), PARAMETER :: M1N2MKxe = 488 - INTEGER(IntKi), PARAMETER :: M1N3MKxe = 489 - INTEGER(IntKi), PARAMETER :: M1N4MKxe = 490 - INTEGER(IntKi), PARAMETER :: M1N5MKxe = 491 - INTEGER(IntKi), PARAMETER :: M1N6MKxe = 492 - INTEGER(IntKi), PARAMETER :: M1N7MKxe = 493 - INTEGER(IntKi), PARAMETER :: M1N8MKxe = 494 - INTEGER(IntKi), PARAMETER :: M1N9MKxe = 495 - INTEGER(IntKi), PARAMETER :: M2N1MKxe = 496 - INTEGER(IntKi), PARAMETER :: M2N2MKxe = 497 - INTEGER(IntKi), PARAMETER :: M2N3MKxe = 498 - INTEGER(IntKi), PARAMETER :: M2N4MKxe = 499 - INTEGER(IntKi), PARAMETER :: M2N5MKxe = 500 - INTEGER(IntKi), PARAMETER :: M2N6MKxe = 501 - INTEGER(IntKi), PARAMETER :: M2N7MKxe = 502 - INTEGER(IntKi), PARAMETER :: M2N8MKxe = 503 - INTEGER(IntKi), PARAMETER :: M2N9MKxe = 504 - INTEGER(IntKi), PARAMETER :: M3N1MKxe = 505 - INTEGER(IntKi), PARAMETER :: M3N2MKxe = 506 - INTEGER(IntKi), PARAMETER :: M3N3MKxe = 507 - INTEGER(IntKi), PARAMETER :: M3N4MKxe = 508 - INTEGER(IntKi), PARAMETER :: M3N5MKxe = 509 - INTEGER(IntKi), PARAMETER :: M3N6MKxe = 510 - INTEGER(IntKi), PARAMETER :: M3N7MKxe = 511 - INTEGER(IntKi), PARAMETER :: M3N8MKxe = 512 - INTEGER(IntKi), PARAMETER :: M3N9MKxe = 513 - INTEGER(IntKi), PARAMETER :: M4N1MKxe = 514 - INTEGER(IntKi), PARAMETER :: M4N2MKxe = 515 - INTEGER(IntKi), PARAMETER :: M4N3MKxe = 516 - INTEGER(IntKi), PARAMETER :: M4N4MKxe = 517 - INTEGER(IntKi), PARAMETER :: M4N5MKxe = 518 - INTEGER(IntKi), PARAMETER :: M4N6MKxe = 519 - INTEGER(IntKi), PARAMETER :: M4N7MKxe = 520 - INTEGER(IntKi), PARAMETER :: M4N8MKxe = 521 - INTEGER(IntKi), PARAMETER :: M4N9MKxe = 522 - INTEGER(IntKi), PARAMETER :: M5N1MKxe = 523 - INTEGER(IntKi), PARAMETER :: M5N2MKxe = 524 - INTEGER(IntKi), PARAMETER :: M5N3MKxe = 525 - INTEGER(IntKi), PARAMETER :: M5N4MKxe = 526 - INTEGER(IntKi), PARAMETER :: M5N5MKxe = 527 - INTEGER(IntKi), PARAMETER :: M5N6MKxe = 528 - INTEGER(IntKi), PARAMETER :: M5N7MKxe = 529 - INTEGER(IntKi), PARAMETER :: M5N8MKxe = 530 - INTEGER(IntKi), PARAMETER :: M5N9MKxe = 531 - INTEGER(IntKi), PARAMETER :: M6N1MKxe = 532 - INTEGER(IntKi), PARAMETER :: M6N2MKxe = 533 - INTEGER(IntKi), PARAMETER :: M6N3MKxe = 534 - INTEGER(IntKi), PARAMETER :: M6N4MKxe = 535 - INTEGER(IntKi), PARAMETER :: M6N5MKxe = 536 - INTEGER(IntKi), PARAMETER :: M6N6MKxe = 537 - INTEGER(IntKi), PARAMETER :: M6N7MKxe = 538 - INTEGER(IntKi), PARAMETER :: M6N8MKxe = 539 - INTEGER(IntKi), PARAMETER :: M6N9MKxe = 540 - INTEGER(IntKi), PARAMETER :: M7N1MKxe = 541 - INTEGER(IntKi), PARAMETER :: M7N2MKxe = 542 - INTEGER(IntKi), PARAMETER :: M7N3MKxe = 543 - INTEGER(IntKi), PARAMETER :: M7N4MKxe = 544 - INTEGER(IntKi), PARAMETER :: M7N5MKxe = 545 - INTEGER(IntKi), PARAMETER :: M7N6MKxe = 546 - INTEGER(IntKi), PARAMETER :: M7N7MKxe = 547 - INTEGER(IntKi), PARAMETER :: M7N8MKxe = 548 - INTEGER(IntKi), PARAMETER :: M7N9MKxe = 549 - INTEGER(IntKi), PARAMETER :: M8N1MKxe = 550 - INTEGER(IntKi), PARAMETER :: M8N2MKxe = 551 - INTEGER(IntKi), PARAMETER :: M8N3MKxe = 552 - INTEGER(IntKi), PARAMETER :: M8N4MKxe = 553 - INTEGER(IntKi), PARAMETER :: M8N5MKxe = 554 - INTEGER(IntKi), PARAMETER :: M8N6MKxe = 555 - INTEGER(IntKi), PARAMETER :: M8N7MKxe = 556 - INTEGER(IntKi), PARAMETER :: M8N8MKxe = 557 - INTEGER(IntKi), PARAMETER :: M8N9MKxe = 558 - INTEGER(IntKi), PARAMETER :: M9N1MKxe = 559 - INTEGER(IntKi), PARAMETER :: M9N2MKxe = 560 - INTEGER(IntKi), PARAMETER :: M9N3MKxe = 561 - INTEGER(IntKi), PARAMETER :: M9N4MKxe = 562 - INTEGER(IntKi), PARAMETER :: M9N5MKxe = 563 - INTEGER(IntKi), PARAMETER :: M9N6MKxe = 564 - INTEGER(IntKi), PARAMETER :: M9N7MKxe = 565 - INTEGER(IntKi), PARAMETER :: M9N8MKxe = 566 - INTEGER(IntKi), PARAMETER :: M9N9MKxe = 567 - INTEGER(IntKi), PARAMETER :: M1N1MKye = 568 - INTEGER(IntKi), PARAMETER :: M1N2MKye = 569 - INTEGER(IntKi), PARAMETER :: M1N3MKye = 570 - INTEGER(IntKi), PARAMETER :: M1N4MKye = 571 - INTEGER(IntKi), PARAMETER :: M1N5MKye = 572 - INTEGER(IntKi), PARAMETER :: M1N6MKye = 573 - INTEGER(IntKi), PARAMETER :: M1N7MKye = 574 - INTEGER(IntKi), PARAMETER :: M1N8MKye = 575 - INTEGER(IntKi), PARAMETER :: M1N9MKye = 576 - INTEGER(IntKi), PARAMETER :: M2N1MKye = 577 - INTEGER(IntKi), PARAMETER :: M2N2MKye = 578 - INTEGER(IntKi), PARAMETER :: M2N3MKye = 579 - INTEGER(IntKi), PARAMETER :: M2N4MKye = 580 - INTEGER(IntKi), PARAMETER :: M2N5MKye = 581 - INTEGER(IntKi), PARAMETER :: M2N6MKye = 582 - INTEGER(IntKi), PARAMETER :: M2N7MKye = 583 - INTEGER(IntKi), PARAMETER :: M2N8MKye = 584 - INTEGER(IntKi), PARAMETER :: M2N9MKye = 585 - INTEGER(IntKi), PARAMETER :: M3N1MKye = 586 - INTEGER(IntKi), PARAMETER :: M3N2MKye = 587 - INTEGER(IntKi), PARAMETER :: M3N3MKye = 588 - INTEGER(IntKi), PARAMETER :: M3N4MKye = 589 - INTEGER(IntKi), PARAMETER :: M3N5MKye = 590 - INTEGER(IntKi), PARAMETER :: M3N6MKye = 591 - INTEGER(IntKi), PARAMETER :: M3N7MKye = 592 - INTEGER(IntKi), PARAMETER :: M3N8MKye = 593 - INTEGER(IntKi), PARAMETER :: M3N9MKye = 594 - INTEGER(IntKi), PARAMETER :: M4N1MKye = 595 - INTEGER(IntKi), PARAMETER :: M4N2MKye = 596 - INTEGER(IntKi), PARAMETER :: M4N3MKye = 597 - INTEGER(IntKi), PARAMETER :: M4N4MKye = 598 - INTEGER(IntKi), PARAMETER :: M4N5MKye = 599 - INTEGER(IntKi), PARAMETER :: M4N6MKye = 600 - INTEGER(IntKi), PARAMETER :: M4N7MKye = 601 - INTEGER(IntKi), PARAMETER :: M4N8MKye = 602 - INTEGER(IntKi), PARAMETER :: M4N9MKye = 603 - INTEGER(IntKi), PARAMETER :: M5N1MKye = 604 - INTEGER(IntKi), PARAMETER :: M5N2MKye = 605 - INTEGER(IntKi), PARAMETER :: M5N3MKye = 606 - INTEGER(IntKi), PARAMETER :: M5N4MKye = 607 - INTEGER(IntKi), PARAMETER :: M5N5MKye = 608 - INTEGER(IntKi), PARAMETER :: M5N6MKye = 609 - INTEGER(IntKi), PARAMETER :: M5N7MKye = 610 - INTEGER(IntKi), PARAMETER :: M5N8MKye = 611 - INTEGER(IntKi), PARAMETER :: M5N9MKye = 612 - INTEGER(IntKi), PARAMETER :: M6N1MKye = 613 - INTEGER(IntKi), PARAMETER :: M6N2MKye = 614 - INTEGER(IntKi), PARAMETER :: M6N3MKye = 615 - INTEGER(IntKi), PARAMETER :: M6N4MKye = 616 - INTEGER(IntKi), PARAMETER :: M6N5MKye = 617 - INTEGER(IntKi), PARAMETER :: M6N6MKye = 618 - INTEGER(IntKi), PARAMETER :: M6N7MKye = 619 - INTEGER(IntKi), PARAMETER :: M6N8MKye = 620 - INTEGER(IntKi), PARAMETER :: M6N9MKye = 621 - INTEGER(IntKi), PARAMETER :: M7N1MKye = 622 - INTEGER(IntKi), PARAMETER :: M7N2MKye = 623 - INTEGER(IntKi), PARAMETER :: M7N3MKye = 624 - INTEGER(IntKi), PARAMETER :: M7N4MKye = 625 - INTEGER(IntKi), PARAMETER :: M7N5MKye = 626 - INTEGER(IntKi), PARAMETER :: M7N6MKye = 627 - INTEGER(IntKi), PARAMETER :: M7N7MKye = 628 - INTEGER(IntKi), PARAMETER :: M7N8MKye = 629 - INTEGER(IntKi), PARAMETER :: M7N9MKye = 630 - INTEGER(IntKi), PARAMETER :: M8N1MKye = 631 - INTEGER(IntKi), PARAMETER :: M8N2MKye = 632 - INTEGER(IntKi), PARAMETER :: M8N3MKye = 633 - INTEGER(IntKi), PARAMETER :: M8N4MKye = 634 - INTEGER(IntKi), PARAMETER :: M8N5MKye = 635 - INTEGER(IntKi), PARAMETER :: M8N6MKye = 636 - INTEGER(IntKi), PARAMETER :: M8N7MKye = 637 - INTEGER(IntKi), PARAMETER :: M8N8MKye = 638 - INTEGER(IntKi), PARAMETER :: M8N9MKye = 639 - INTEGER(IntKi), PARAMETER :: M9N1MKye = 640 - INTEGER(IntKi), PARAMETER :: M9N2MKye = 641 - INTEGER(IntKi), PARAMETER :: M9N3MKye = 642 - INTEGER(IntKi), PARAMETER :: M9N4MKye = 643 - INTEGER(IntKi), PARAMETER :: M9N5MKye = 644 - INTEGER(IntKi), PARAMETER :: M9N6MKye = 645 - INTEGER(IntKi), PARAMETER :: M9N7MKye = 646 - INTEGER(IntKi), PARAMETER :: M9N8MKye = 647 - INTEGER(IntKi), PARAMETER :: M9N9MKye = 648 - INTEGER(IntKi), PARAMETER :: M1N1MKze = 649 - INTEGER(IntKi), PARAMETER :: M1N2MKze = 650 - INTEGER(IntKi), PARAMETER :: M1N3MKze = 651 - INTEGER(IntKi), PARAMETER :: M1N4MKze = 652 - INTEGER(IntKi), PARAMETER :: M1N5MKze = 653 - INTEGER(IntKi), PARAMETER :: M1N6MKze = 654 - INTEGER(IntKi), PARAMETER :: M1N7MKze = 655 - INTEGER(IntKi), PARAMETER :: M1N8MKze = 656 - INTEGER(IntKi), PARAMETER :: M1N9MKze = 657 - INTEGER(IntKi), PARAMETER :: M2N1MKze = 658 - INTEGER(IntKi), PARAMETER :: M2N2MKze = 659 - INTEGER(IntKi), PARAMETER :: M2N3MKze = 660 - INTEGER(IntKi), PARAMETER :: M2N4MKze = 661 - INTEGER(IntKi), PARAMETER :: M2N5MKze = 662 - INTEGER(IntKi), PARAMETER :: M2N6MKze = 663 - INTEGER(IntKi), PARAMETER :: M2N7MKze = 664 - INTEGER(IntKi), PARAMETER :: M2N8MKze = 665 - INTEGER(IntKi), PARAMETER :: M2N9MKze = 666 - INTEGER(IntKi), PARAMETER :: M3N1MKze = 667 - INTEGER(IntKi), PARAMETER :: M3N2MKze = 668 - INTEGER(IntKi), PARAMETER :: M3N3MKze = 669 - INTEGER(IntKi), PARAMETER :: M3N4MKze = 670 - INTEGER(IntKi), PARAMETER :: M3N5MKze = 671 - INTEGER(IntKi), PARAMETER :: M3N6MKze = 672 - INTEGER(IntKi), PARAMETER :: M3N7MKze = 673 - INTEGER(IntKi), PARAMETER :: M3N8MKze = 674 - INTEGER(IntKi), PARAMETER :: M3N9MKze = 675 - INTEGER(IntKi), PARAMETER :: M4N1MKze = 676 - INTEGER(IntKi), PARAMETER :: M4N2MKze = 677 - INTEGER(IntKi), PARAMETER :: M4N3MKze = 678 - INTEGER(IntKi), PARAMETER :: M4N4MKze = 679 - INTEGER(IntKi), PARAMETER :: M4N5MKze = 680 - INTEGER(IntKi), PARAMETER :: M4N6MKze = 681 - INTEGER(IntKi), PARAMETER :: M4N7MKze = 682 - INTEGER(IntKi), PARAMETER :: M4N8MKze = 683 - INTEGER(IntKi), PARAMETER :: M4N9MKze = 684 - INTEGER(IntKi), PARAMETER :: M5N1MKze = 685 - INTEGER(IntKi), PARAMETER :: M5N2MKze = 686 - INTEGER(IntKi), PARAMETER :: M5N3MKze = 687 - INTEGER(IntKi), PARAMETER :: M5N4MKze = 688 - INTEGER(IntKi), PARAMETER :: M5N5MKze = 689 - INTEGER(IntKi), PARAMETER :: M5N6MKze = 690 - INTEGER(IntKi), PARAMETER :: M5N7MKze = 691 - INTEGER(IntKi), PARAMETER :: M5N8MKze = 692 - INTEGER(IntKi), PARAMETER :: M5N9MKze = 693 - INTEGER(IntKi), PARAMETER :: M6N1MKze = 694 - INTEGER(IntKi), PARAMETER :: M6N2MKze = 695 - INTEGER(IntKi), PARAMETER :: M6N3MKze = 696 - INTEGER(IntKi), PARAMETER :: M6N4MKze = 697 - INTEGER(IntKi), PARAMETER :: M6N5MKze = 698 - INTEGER(IntKi), PARAMETER :: M6N6MKze = 699 - INTEGER(IntKi), PARAMETER :: M6N7MKze = 700 - INTEGER(IntKi), PARAMETER :: M6N8MKze = 701 - INTEGER(IntKi), PARAMETER :: M6N9MKze = 702 - INTEGER(IntKi), PARAMETER :: M7N1MKze = 703 - INTEGER(IntKi), PARAMETER :: M7N2MKze = 704 - INTEGER(IntKi), PARAMETER :: M7N3MKze = 705 - INTEGER(IntKi), PARAMETER :: M7N4MKze = 706 - INTEGER(IntKi), PARAMETER :: M7N5MKze = 707 - INTEGER(IntKi), PARAMETER :: M7N6MKze = 708 - INTEGER(IntKi), PARAMETER :: M7N7MKze = 709 - INTEGER(IntKi), PARAMETER :: M7N8MKze = 710 - INTEGER(IntKi), PARAMETER :: M7N9MKze = 711 - INTEGER(IntKi), PARAMETER :: M8N1MKze = 712 - INTEGER(IntKi), PARAMETER :: M8N2MKze = 713 - INTEGER(IntKi), PARAMETER :: M8N3MKze = 714 - INTEGER(IntKi), PARAMETER :: M8N4MKze = 715 - INTEGER(IntKi), PARAMETER :: M8N5MKze = 716 - INTEGER(IntKi), PARAMETER :: M8N6MKze = 717 - INTEGER(IntKi), PARAMETER :: M8N7MKze = 718 - INTEGER(IntKi), PARAMETER :: M8N8MKze = 719 - INTEGER(IntKi), PARAMETER :: M8N9MKze = 720 - INTEGER(IntKi), PARAMETER :: M9N1MKze = 721 - INTEGER(IntKi), PARAMETER :: M9N2MKze = 722 - INTEGER(IntKi), PARAMETER :: M9N3MKze = 723 - INTEGER(IntKi), PARAMETER :: M9N4MKze = 724 - INTEGER(IntKi), PARAMETER :: M9N5MKze = 725 - INTEGER(IntKi), PARAMETER :: M9N6MKze = 726 - INTEGER(IntKi), PARAMETER :: M9N7MKze = 727 - INTEGER(IntKi), PARAMETER :: M9N8MKze = 728 - INTEGER(IntKi), PARAMETER :: M9N9MKze = 729 - INTEGER(IntKi), PARAMETER :: M1N1MMxe = 730 - INTEGER(IntKi), PARAMETER :: M1N2MMxe = 731 - INTEGER(IntKi), PARAMETER :: M1N3MMxe = 732 - INTEGER(IntKi), PARAMETER :: M1N4MMxe = 733 - INTEGER(IntKi), PARAMETER :: M1N5MMxe = 734 - INTEGER(IntKi), PARAMETER :: M1N6MMxe = 735 - INTEGER(IntKi), PARAMETER :: M1N7MMxe = 736 - INTEGER(IntKi), PARAMETER :: M1N8MMxe = 737 - INTEGER(IntKi), PARAMETER :: M1N9MMxe = 738 - INTEGER(IntKi), PARAMETER :: M2N1MMxe = 739 - INTEGER(IntKi), PARAMETER :: M2N2MMxe = 740 - INTEGER(IntKi), PARAMETER :: M2N3MMxe = 741 - INTEGER(IntKi), PARAMETER :: M2N4MMxe = 742 - INTEGER(IntKi), PARAMETER :: M2N5MMxe = 743 - INTEGER(IntKi), PARAMETER :: M2N6MMxe = 744 - INTEGER(IntKi), PARAMETER :: M2N7MMxe = 745 - INTEGER(IntKi), PARAMETER :: M2N8MMxe = 746 - INTEGER(IntKi), PARAMETER :: M2N9MMxe = 747 - INTEGER(IntKi), PARAMETER :: M3N1MMxe = 748 - INTEGER(IntKi), PARAMETER :: M3N2MMxe = 749 - INTEGER(IntKi), PARAMETER :: M3N3MMxe = 750 - INTEGER(IntKi), PARAMETER :: M3N4MMxe = 751 - INTEGER(IntKi), PARAMETER :: M3N5MMxe = 752 - INTEGER(IntKi), PARAMETER :: M3N6MMxe = 753 - INTEGER(IntKi), PARAMETER :: M3N7MMxe = 754 - INTEGER(IntKi), PARAMETER :: M3N8MMxe = 755 - INTEGER(IntKi), PARAMETER :: M3N9MMxe = 756 - INTEGER(IntKi), PARAMETER :: M4N1MMxe = 757 - INTEGER(IntKi), PARAMETER :: M4N2MMxe = 758 - INTEGER(IntKi), PARAMETER :: M4N3MMxe = 759 - INTEGER(IntKi), PARAMETER :: M4N4MMxe = 760 - INTEGER(IntKi), PARAMETER :: M4N5MMxe = 761 - INTEGER(IntKi), PARAMETER :: M4N6MMxe = 762 - INTEGER(IntKi), PARAMETER :: M4N7MMxe = 763 - INTEGER(IntKi), PARAMETER :: M4N8MMxe = 764 - INTEGER(IntKi), PARAMETER :: M4N9MMxe = 765 - INTEGER(IntKi), PARAMETER :: M5N1MMxe = 766 - INTEGER(IntKi), PARAMETER :: M5N2MMxe = 767 - INTEGER(IntKi), PARAMETER :: M5N3MMxe = 768 - INTEGER(IntKi), PARAMETER :: M5N4MMxe = 769 - INTEGER(IntKi), PARAMETER :: M5N5MMxe = 770 - INTEGER(IntKi), PARAMETER :: M5N6MMxe = 771 - INTEGER(IntKi), PARAMETER :: M5N7MMxe = 772 - INTEGER(IntKi), PARAMETER :: M5N8MMxe = 773 - INTEGER(IntKi), PARAMETER :: M5N9MMxe = 774 - INTEGER(IntKi), PARAMETER :: M6N1MMxe = 775 - INTEGER(IntKi), PARAMETER :: M6N2MMxe = 776 - INTEGER(IntKi), PARAMETER :: M6N3MMxe = 777 - INTEGER(IntKi), PARAMETER :: M6N4MMxe = 778 - INTEGER(IntKi), PARAMETER :: M6N5MMxe = 779 - INTEGER(IntKi), PARAMETER :: M6N6MMxe = 780 - INTEGER(IntKi), PARAMETER :: M6N7MMxe = 781 - INTEGER(IntKi), PARAMETER :: M6N8MMxe = 782 - INTEGER(IntKi), PARAMETER :: M6N9MMxe = 783 - INTEGER(IntKi), PARAMETER :: M7N1MMxe = 784 - INTEGER(IntKi), PARAMETER :: M7N2MMxe = 785 - INTEGER(IntKi), PARAMETER :: M7N3MMxe = 786 - INTEGER(IntKi), PARAMETER :: M7N4MMxe = 787 - INTEGER(IntKi), PARAMETER :: M7N5MMxe = 788 - INTEGER(IntKi), PARAMETER :: M7N6MMxe = 789 - INTEGER(IntKi), PARAMETER :: M7N7MMxe = 790 - INTEGER(IntKi), PARAMETER :: M7N8MMxe = 791 - INTEGER(IntKi), PARAMETER :: M7N9MMxe = 792 - INTEGER(IntKi), PARAMETER :: M8N1MMxe = 793 - INTEGER(IntKi), PARAMETER :: M8N2MMxe = 794 - INTEGER(IntKi), PARAMETER :: M8N3MMxe = 795 - INTEGER(IntKi), PARAMETER :: M8N4MMxe = 796 - INTEGER(IntKi), PARAMETER :: M8N5MMxe = 797 - INTEGER(IntKi), PARAMETER :: M8N6MMxe = 798 - INTEGER(IntKi), PARAMETER :: M8N7MMxe = 799 - INTEGER(IntKi), PARAMETER :: M8N8MMxe = 800 - INTEGER(IntKi), PARAMETER :: M8N9MMxe = 801 - INTEGER(IntKi), PARAMETER :: M9N1MMxe = 802 - INTEGER(IntKi), PARAMETER :: M9N2MMxe = 803 - INTEGER(IntKi), PARAMETER :: M9N3MMxe = 804 - INTEGER(IntKi), PARAMETER :: M9N4MMxe = 805 - INTEGER(IntKi), PARAMETER :: M9N5MMxe = 806 - INTEGER(IntKi), PARAMETER :: M9N6MMxe = 807 - INTEGER(IntKi), PARAMETER :: M9N7MMxe = 808 - INTEGER(IntKi), PARAMETER :: M9N8MMxe = 809 - INTEGER(IntKi), PARAMETER :: M9N9MMxe = 810 - INTEGER(IntKi), PARAMETER :: M1N1MMye = 811 - INTEGER(IntKi), PARAMETER :: M1N2MMye = 812 - INTEGER(IntKi), PARAMETER :: M1N3MMye = 813 - INTEGER(IntKi), PARAMETER :: M1N4MMye = 814 - INTEGER(IntKi), PARAMETER :: M1N5MMye = 815 - INTEGER(IntKi), PARAMETER :: M1N6MMye = 816 - INTEGER(IntKi), PARAMETER :: M1N7MMye = 817 - INTEGER(IntKi), PARAMETER :: M1N8MMye = 818 - INTEGER(IntKi), PARAMETER :: M1N9MMye = 819 - INTEGER(IntKi), PARAMETER :: M2N1MMye = 820 - INTEGER(IntKi), PARAMETER :: M2N2MMye = 821 - INTEGER(IntKi), PARAMETER :: M2N3MMye = 822 - INTEGER(IntKi), PARAMETER :: M2N4MMye = 823 - INTEGER(IntKi), PARAMETER :: M2N5MMye = 824 - INTEGER(IntKi), PARAMETER :: M2N6MMye = 825 - INTEGER(IntKi), PARAMETER :: M2N7MMye = 826 - INTEGER(IntKi), PARAMETER :: M2N8MMye = 827 - INTEGER(IntKi), PARAMETER :: M2N9MMye = 828 - INTEGER(IntKi), PARAMETER :: M3N1MMye = 829 - INTEGER(IntKi), PARAMETER :: M3N2MMye = 830 - INTEGER(IntKi), PARAMETER :: M3N3MMye = 831 - INTEGER(IntKi), PARAMETER :: M3N4MMye = 832 - INTEGER(IntKi), PARAMETER :: M3N5MMye = 833 - INTEGER(IntKi), PARAMETER :: M3N6MMye = 834 - INTEGER(IntKi), PARAMETER :: M3N7MMye = 835 - INTEGER(IntKi), PARAMETER :: M3N8MMye = 836 - INTEGER(IntKi), PARAMETER :: M3N9MMye = 837 - INTEGER(IntKi), PARAMETER :: M4N1MMye = 838 - INTEGER(IntKi), PARAMETER :: M4N2MMye = 839 - INTEGER(IntKi), PARAMETER :: M4N3MMye = 840 - INTEGER(IntKi), PARAMETER :: M4N4MMye = 841 - INTEGER(IntKi), PARAMETER :: M4N5MMye = 842 - INTEGER(IntKi), PARAMETER :: M4N6MMye = 843 - INTEGER(IntKi), PARAMETER :: M4N7MMye = 844 - INTEGER(IntKi), PARAMETER :: M4N8MMye = 845 - INTEGER(IntKi), PARAMETER :: M4N9MMye = 846 - INTEGER(IntKi), PARAMETER :: M5N1MMye = 847 - INTEGER(IntKi), PARAMETER :: M5N2MMye = 848 - INTEGER(IntKi), PARAMETER :: M5N3MMye = 849 - INTEGER(IntKi), PARAMETER :: M5N4MMye = 850 - INTEGER(IntKi), PARAMETER :: M5N5MMye = 851 - INTEGER(IntKi), PARAMETER :: M5N6MMye = 852 - INTEGER(IntKi), PARAMETER :: M5N7MMye = 853 - INTEGER(IntKi), PARAMETER :: M5N8MMye = 854 - INTEGER(IntKi), PARAMETER :: M5N9MMye = 855 - INTEGER(IntKi), PARAMETER :: M6N1MMye = 856 - INTEGER(IntKi), PARAMETER :: M6N2MMye = 857 - INTEGER(IntKi), PARAMETER :: M6N3MMye = 858 - INTEGER(IntKi), PARAMETER :: M6N4MMye = 859 - INTEGER(IntKi), PARAMETER :: M6N5MMye = 860 - INTEGER(IntKi), PARAMETER :: M6N6MMye = 861 - INTEGER(IntKi), PARAMETER :: M6N7MMye = 862 - INTEGER(IntKi), PARAMETER :: M6N8MMye = 863 - INTEGER(IntKi), PARAMETER :: M6N9MMye = 864 - INTEGER(IntKi), PARAMETER :: M7N1MMye = 865 - INTEGER(IntKi), PARAMETER :: M7N2MMye = 866 - INTEGER(IntKi), PARAMETER :: M7N3MMye = 867 - INTEGER(IntKi), PARAMETER :: M7N4MMye = 868 - INTEGER(IntKi), PARAMETER :: M7N5MMye = 869 - INTEGER(IntKi), PARAMETER :: M7N6MMye = 870 - INTEGER(IntKi), PARAMETER :: M7N7MMye = 871 - INTEGER(IntKi), PARAMETER :: M7N8MMye = 872 - INTEGER(IntKi), PARAMETER :: M7N9MMye = 873 - INTEGER(IntKi), PARAMETER :: M8N1MMye = 874 - INTEGER(IntKi), PARAMETER :: M8N2MMye = 875 - INTEGER(IntKi), PARAMETER :: M8N3MMye = 876 - INTEGER(IntKi), PARAMETER :: M8N4MMye = 877 - INTEGER(IntKi), PARAMETER :: M8N5MMye = 878 - INTEGER(IntKi), PARAMETER :: M8N6MMye = 879 - INTEGER(IntKi), PARAMETER :: M8N7MMye = 880 - INTEGER(IntKi), PARAMETER :: M8N8MMye = 881 - INTEGER(IntKi), PARAMETER :: M8N9MMye = 882 - INTEGER(IntKi), PARAMETER :: M9N1MMye = 883 - INTEGER(IntKi), PARAMETER :: M9N2MMye = 884 - INTEGER(IntKi), PARAMETER :: M9N3MMye = 885 - INTEGER(IntKi), PARAMETER :: M9N4MMye = 886 - INTEGER(IntKi), PARAMETER :: M9N5MMye = 887 - INTEGER(IntKi), PARAMETER :: M9N6MMye = 888 - INTEGER(IntKi), PARAMETER :: M9N7MMye = 889 - INTEGER(IntKi), PARAMETER :: M9N8MMye = 890 - INTEGER(IntKi), PARAMETER :: M9N9MMye = 891 - INTEGER(IntKi), PARAMETER :: M1N1MMze = 892 - INTEGER(IntKi), PARAMETER :: M1N2MMze = 893 - INTEGER(IntKi), PARAMETER :: M1N3MMze = 894 - INTEGER(IntKi), PARAMETER :: M1N4MMze = 895 - INTEGER(IntKi), PARAMETER :: M1N5MMze = 896 - INTEGER(IntKi), PARAMETER :: M1N6MMze = 897 - INTEGER(IntKi), PARAMETER :: M1N7MMze = 898 - INTEGER(IntKi), PARAMETER :: M1N8MMze = 899 - INTEGER(IntKi), PARAMETER :: M1N9MMze = 900 - INTEGER(IntKi), PARAMETER :: M2N1MMze = 901 - INTEGER(IntKi), PARAMETER :: M2N2MMze = 902 - INTEGER(IntKi), PARAMETER :: M2N3MMze = 903 - INTEGER(IntKi), PARAMETER :: M2N4MMze = 904 - INTEGER(IntKi), PARAMETER :: M2N5MMze = 905 - INTEGER(IntKi), PARAMETER :: M2N6MMze = 906 - INTEGER(IntKi), PARAMETER :: M2N7MMze = 907 - INTEGER(IntKi), PARAMETER :: M2N8MMze = 908 - INTEGER(IntKi), PARAMETER :: M2N9MMze = 909 - INTEGER(IntKi), PARAMETER :: M3N1MMze = 910 - INTEGER(IntKi), PARAMETER :: M3N2MMze = 911 - INTEGER(IntKi), PARAMETER :: M3N3MMze = 912 - INTEGER(IntKi), PARAMETER :: M3N4MMze = 913 - INTEGER(IntKi), PARAMETER :: M3N5MMze = 914 - INTEGER(IntKi), PARAMETER :: M3N6MMze = 915 - INTEGER(IntKi), PARAMETER :: M3N7MMze = 916 - INTEGER(IntKi), PARAMETER :: M3N8MMze = 917 - INTEGER(IntKi), PARAMETER :: M3N9MMze = 918 - INTEGER(IntKi), PARAMETER :: M4N1MMze = 919 - INTEGER(IntKi), PARAMETER :: M4N2MMze = 920 - INTEGER(IntKi), PARAMETER :: M4N3MMze = 921 - INTEGER(IntKi), PARAMETER :: M4N4MMze = 922 - INTEGER(IntKi), PARAMETER :: M4N5MMze = 923 - INTEGER(IntKi), PARAMETER :: M4N6MMze = 924 - INTEGER(IntKi), PARAMETER :: M4N7MMze = 925 - INTEGER(IntKi), PARAMETER :: M4N8MMze = 926 - INTEGER(IntKi), PARAMETER :: M4N9MMze = 927 - INTEGER(IntKi), PARAMETER :: M5N1MMze = 928 - INTEGER(IntKi), PARAMETER :: M5N2MMze = 929 - INTEGER(IntKi), PARAMETER :: M5N3MMze = 930 - INTEGER(IntKi), PARAMETER :: M5N4MMze = 931 - INTEGER(IntKi), PARAMETER :: M5N5MMze = 932 - INTEGER(IntKi), PARAMETER :: M5N6MMze = 933 - INTEGER(IntKi), PARAMETER :: M5N7MMze = 934 - INTEGER(IntKi), PARAMETER :: M5N8MMze = 935 - INTEGER(IntKi), PARAMETER :: M5N9MMze = 936 - INTEGER(IntKi), PARAMETER :: M6N1MMze = 937 - INTEGER(IntKi), PARAMETER :: M6N2MMze = 938 - INTEGER(IntKi), PARAMETER :: M6N3MMze = 939 - INTEGER(IntKi), PARAMETER :: M6N4MMze = 940 - INTEGER(IntKi), PARAMETER :: M6N5MMze = 941 - INTEGER(IntKi), PARAMETER :: M6N6MMze = 942 - INTEGER(IntKi), PARAMETER :: M6N7MMze = 943 - INTEGER(IntKi), PARAMETER :: M6N8MMze = 944 - INTEGER(IntKi), PARAMETER :: M6N9MMze = 945 - INTEGER(IntKi), PARAMETER :: M7N1MMze = 946 - INTEGER(IntKi), PARAMETER :: M7N2MMze = 947 - INTEGER(IntKi), PARAMETER :: M7N3MMze = 948 - INTEGER(IntKi), PARAMETER :: M7N4MMze = 949 - INTEGER(IntKi), PARAMETER :: M7N5MMze = 950 - INTEGER(IntKi), PARAMETER :: M7N6MMze = 951 - INTEGER(IntKi), PARAMETER :: M7N7MMze = 952 - INTEGER(IntKi), PARAMETER :: M7N8MMze = 953 - INTEGER(IntKi), PARAMETER :: M7N9MMze = 954 - INTEGER(IntKi), PARAMETER :: M8N1MMze = 955 - INTEGER(IntKi), PARAMETER :: M8N2MMze = 956 - INTEGER(IntKi), PARAMETER :: M8N3MMze = 957 - INTEGER(IntKi), PARAMETER :: M8N4MMze = 958 - INTEGER(IntKi), PARAMETER :: M8N5MMze = 959 - INTEGER(IntKi), PARAMETER :: M8N6MMze = 960 - INTEGER(IntKi), PARAMETER :: M8N7MMze = 961 - INTEGER(IntKi), PARAMETER :: M8N8MMze = 962 - INTEGER(IntKi), PARAMETER :: M8N9MMze = 963 - INTEGER(IntKi), PARAMETER :: M9N1MMze = 964 - INTEGER(IntKi), PARAMETER :: M9N2MMze = 965 - INTEGER(IntKi), PARAMETER :: M9N3MMze = 966 - INTEGER(IntKi), PARAMETER :: M9N4MMze = 967 - INTEGER(IntKi), PARAMETER :: M9N5MMze = 968 - INTEGER(IntKi), PARAMETER :: M9N6MMze = 969 - INTEGER(IntKi), PARAMETER :: M9N7MMze = 970 - INTEGER(IntKi), PARAMETER :: M9N8MMze = 971 - INTEGER(IntKi), PARAMETER :: M9N9MMze = 972 - - - ! Displacements: - - INTEGER(IntKi), PARAMETER :: M1N1TDxss = 973 - INTEGER(IntKi), PARAMETER :: M1N2TDxss = 974 - INTEGER(IntKi), PARAMETER :: M1N3TDxss = 975 - INTEGER(IntKi), PARAMETER :: M1N4TDxss = 976 - INTEGER(IntKi), PARAMETER :: M1N5TDxss = 977 - INTEGER(IntKi), PARAMETER :: M1N6TDxss = 978 - INTEGER(IntKi), PARAMETER :: M1N7TDxss = 979 - INTEGER(IntKi), PARAMETER :: M1N8TDxss = 980 - INTEGER(IntKi), PARAMETER :: M1N9TDxss = 981 - INTEGER(IntKi), PARAMETER :: M2N1TDxss = 982 - INTEGER(IntKi), PARAMETER :: M2N2TDxss = 983 - INTEGER(IntKi), PARAMETER :: M2N3TDxss = 984 - INTEGER(IntKi), PARAMETER :: M2N4TDxss = 985 - INTEGER(IntKi), PARAMETER :: M2N5TDxss = 986 - INTEGER(IntKi), PARAMETER :: M2N6TDxss = 987 - INTEGER(IntKi), PARAMETER :: M2N7TDxss = 988 - INTEGER(IntKi), PARAMETER :: M2N8TDxss = 989 - INTEGER(IntKi), PARAMETER :: M2N9TDxss = 990 - INTEGER(IntKi), PARAMETER :: M3N1TDxss = 991 - INTEGER(IntKi), PARAMETER :: M3N2TDxss = 992 - INTEGER(IntKi), PARAMETER :: M3N3TDxss = 993 - INTEGER(IntKi), PARAMETER :: M3N4TDxss = 994 - INTEGER(IntKi), PARAMETER :: M3N5TDxss = 995 - INTEGER(IntKi), PARAMETER :: M3N6TDxss = 996 - INTEGER(IntKi), PARAMETER :: M3N7TDxss = 997 - INTEGER(IntKi), PARAMETER :: M3N8TDxss = 998 - INTEGER(IntKi), PARAMETER :: M3N9TDxss = 999 - INTEGER(IntKi), PARAMETER :: M4N1TDxss = 1000 - INTEGER(IntKi), PARAMETER :: M4N2TDxss = 1001 - INTEGER(IntKi), PARAMETER :: M4N3TDxss = 1002 - INTEGER(IntKi), PARAMETER :: M4N4TDxss = 1003 - INTEGER(IntKi), PARAMETER :: M4N5TDxss = 1004 - INTEGER(IntKi), PARAMETER :: M4N6TDxss = 1005 - INTEGER(IntKi), PARAMETER :: M4N7TDxss = 1006 - INTEGER(IntKi), PARAMETER :: M4N8TDxss = 1007 - INTEGER(IntKi), PARAMETER :: M4N9TDxss = 1008 - INTEGER(IntKi), PARAMETER :: M5N1TDxss = 1009 - INTEGER(IntKi), PARAMETER :: M5N2TDxss = 1010 - INTEGER(IntKi), PARAMETER :: M5N3TDxss = 1011 - INTEGER(IntKi), PARAMETER :: M5N4TDxss = 1012 - INTEGER(IntKi), PARAMETER :: M5N5TDxss = 1013 - INTEGER(IntKi), PARAMETER :: M5N6TDxss = 1014 - INTEGER(IntKi), PARAMETER :: M5N7TDxss = 1015 - INTEGER(IntKi), PARAMETER :: M5N8TDxss = 1016 - INTEGER(IntKi), PARAMETER :: M5N9TDxss = 1017 - INTEGER(IntKi), PARAMETER :: M6N1TDxss = 1018 - INTEGER(IntKi), PARAMETER :: M6N2TDxss = 1019 - INTEGER(IntKi), PARAMETER :: M6N3TDxss = 1020 - INTEGER(IntKi), PARAMETER :: M6N4TDxss = 1021 - INTEGER(IntKi), PARAMETER :: M6N5TDxss = 1022 - INTEGER(IntKi), PARAMETER :: M6N6TDxss = 1023 - INTEGER(IntKi), PARAMETER :: M6N7TDxss = 1024 - INTEGER(IntKi), PARAMETER :: M6N8TDxss = 1025 - INTEGER(IntKi), PARAMETER :: M6N9TDxss = 1026 - INTEGER(IntKi), PARAMETER :: M7N1TDxss = 1027 - INTEGER(IntKi), PARAMETER :: M7N2TDxss = 1028 - INTEGER(IntKi), PARAMETER :: M7N3TDxss = 1029 - INTEGER(IntKi), PARAMETER :: M7N4TDxss = 1030 - INTEGER(IntKi), PARAMETER :: M7N5TDxss = 1031 - INTEGER(IntKi), PARAMETER :: M7N6TDxss = 1032 - INTEGER(IntKi), PARAMETER :: M7N7TDxss = 1033 - INTEGER(IntKi), PARAMETER :: M7N8TDxss = 1034 - INTEGER(IntKi), PARAMETER :: M7N9TDxss = 1035 - INTEGER(IntKi), PARAMETER :: M8N1TDxss = 1036 - INTEGER(IntKi), PARAMETER :: M8N2TDxss = 1037 - INTEGER(IntKi), PARAMETER :: M8N3TDxss = 1038 - INTEGER(IntKi), PARAMETER :: M8N4TDxss = 1039 - INTEGER(IntKi), PARAMETER :: M8N5TDxss = 1040 - INTEGER(IntKi), PARAMETER :: M8N6TDxss = 1041 - INTEGER(IntKi), PARAMETER :: M8N7TDxss = 1042 - INTEGER(IntKi), PARAMETER :: M8N8TDxss = 1043 - INTEGER(IntKi), PARAMETER :: M8N9TDxss = 1044 - INTEGER(IntKi), PARAMETER :: M9N1TDxss = 1045 - INTEGER(IntKi), PARAMETER :: M9N2TDxss = 1046 - INTEGER(IntKi), PARAMETER :: M9N3TDxss = 1047 - INTEGER(IntKi), PARAMETER :: M9N4TDxss = 1048 - INTEGER(IntKi), PARAMETER :: M9N5TDxss = 1049 - INTEGER(IntKi), PARAMETER :: M9N6TDxss = 1050 - INTEGER(IntKi), PARAMETER :: M9N7TDxss = 1051 - INTEGER(IntKi), PARAMETER :: M9N8TDxss = 1052 - INTEGER(IntKi), PARAMETER :: M9N9TDxss = 1053 - INTEGER(IntKi), PARAMETER :: M1N1TDyss = 1054 - INTEGER(IntKi), PARAMETER :: M1N2TDyss = 1055 - INTEGER(IntKi), PARAMETER :: M1N3TDyss = 1056 - INTEGER(IntKi), PARAMETER :: M1N4TDyss = 1057 - INTEGER(IntKi), PARAMETER :: M1N5TDyss = 1058 - INTEGER(IntKi), PARAMETER :: M1N6TDyss = 1059 - INTEGER(IntKi), PARAMETER :: M1N7TDyss = 1060 - INTEGER(IntKi), PARAMETER :: M1N8TDyss = 1061 - INTEGER(IntKi), PARAMETER :: M1N9TDyss = 1062 - INTEGER(IntKi), PARAMETER :: M2N1TDyss = 1063 - INTEGER(IntKi), PARAMETER :: M2N2TDyss = 1064 - INTEGER(IntKi), PARAMETER :: M2N3TDyss = 1065 - INTEGER(IntKi), PARAMETER :: M2N4TDyss = 1066 - INTEGER(IntKi), PARAMETER :: M2N5TDyss = 1067 - INTEGER(IntKi), PARAMETER :: M2N6TDyss = 1068 - INTEGER(IntKi), PARAMETER :: M2N7TDyss = 1069 - INTEGER(IntKi), PARAMETER :: M2N8TDyss = 1070 - INTEGER(IntKi), PARAMETER :: M2N9TDyss = 1071 - INTEGER(IntKi), PARAMETER :: M3N1TDyss = 1072 - INTEGER(IntKi), PARAMETER :: M3N2TDyss = 1073 - INTEGER(IntKi), PARAMETER :: M3N3TDyss = 1074 - INTEGER(IntKi), PARAMETER :: M3N4TDyss = 1075 - INTEGER(IntKi), PARAMETER :: M3N5TDyss = 1076 - INTEGER(IntKi), PARAMETER :: M3N6TDyss = 1077 - INTEGER(IntKi), PARAMETER :: M3N7TDyss = 1078 - INTEGER(IntKi), PARAMETER :: M3N8TDyss = 1079 - INTEGER(IntKi), PARAMETER :: M3N9TDyss = 1080 - INTEGER(IntKi), PARAMETER :: M4N1TDyss = 1081 - INTEGER(IntKi), PARAMETER :: M4N2TDyss = 1082 - INTEGER(IntKi), PARAMETER :: M4N3TDyss = 1083 - INTEGER(IntKi), PARAMETER :: M4N4TDyss = 1084 - INTEGER(IntKi), PARAMETER :: M4N5TDyss = 1085 - INTEGER(IntKi), PARAMETER :: M4N6TDyss = 1086 - INTEGER(IntKi), PARAMETER :: M4N7TDyss = 1087 - INTEGER(IntKi), PARAMETER :: M4N8TDyss = 1088 - INTEGER(IntKi), PARAMETER :: M4N9TDyss = 1089 - INTEGER(IntKi), PARAMETER :: M5N1TDyss = 1090 - INTEGER(IntKi), PARAMETER :: M5N2TDyss = 1091 - INTEGER(IntKi), PARAMETER :: M5N3TDyss = 1092 - INTEGER(IntKi), PARAMETER :: M5N4TDyss = 1093 - INTEGER(IntKi), PARAMETER :: M5N5TDyss = 1094 - INTEGER(IntKi), PARAMETER :: M5N6TDyss = 1095 - INTEGER(IntKi), PARAMETER :: M5N7TDyss = 1096 - INTEGER(IntKi), PARAMETER :: M5N8TDyss = 1097 - INTEGER(IntKi), PARAMETER :: M5N9TDyss = 1098 - INTEGER(IntKi), PARAMETER :: M6N1TDyss = 1099 - INTEGER(IntKi), PARAMETER :: M6N2TDyss = 1100 - INTEGER(IntKi), PARAMETER :: M6N3TDyss = 1101 - INTEGER(IntKi), PARAMETER :: M6N4TDyss = 1102 - INTEGER(IntKi), PARAMETER :: M6N5TDyss = 1103 - INTEGER(IntKi), PARAMETER :: M6N6TDyss = 1104 - INTEGER(IntKi), PARAMETER :: M6N7TDyss = 1105 - INTEGER(IntKi), PARAMETER :: M6N8TDyss = 1106 - INTEGER(IntKi), PARAMETER :: M6N9TDyss = 1107 - INTEGER(IntKi), PARAMETER :: M7N1TDyss = 1108 - INTEGER(IntKi), PARAMETER :: M7N2TDyss = 1109 - INTEGER(IntKi), PARAMETER :: M7N3TDyss = 1110 - INTEGER(IntKi), PARAMETER :: M7N4TDyss = 1111 - INTEGER(IntKi), PARAMETER :: M7N5TDyss = 1112 - INTEGER(IntKi), PARAMETER :: M7N6TDyss = 1113 - INTEGER(IntKi), PARAMETER :: M7N7TDyss = 1114 - INTEGER(IntKi), PARAMETER :: M7N8TDyss = 1115 - INTEGER(IntKi), PARAMETER :: M7N9TDyss = 1116 - INTEGER(IntKi), PARAMETER :: M8N1TDyss = 1117 - INTEGER(IntKi), PARAMETER :: M8N2TDyss = 1118 - INTEGER(IntKi), PARAMETER :: M8N3TDyss = 1119 - INTEGER(IntKi), PARAMETER :: M8N4TDyss = 1120 - INTEGER(IntKi), PARAMETER :: M8N5TDyss = 1121 - INTEGER(IntKi), PARAMETER :: M8N6TDyss = 1122 - INTEGER(IntKi), PARAMETER :: M8N7TDyss = 1123 - INTEGER(IntKi), PARAMETER :: M8N8TDyss = 1124 - INTEGER(IntKi), PARAMETER :: M8N9TDyss = 1125 - INTEGER(IntKi), PARAMETER :: M9N1TDyss = 1126 - INTEGER(IntKi), PARAMETER :: M9N2TDyss = 1127 - INTEGER(IntKi), PARAMETER :: M9N3TDyss = 1128 - INTEGER(IntKi), PARAMETER :: M9N4TDyss = 1129 - INTEGER(IntKi), PARAMETER :: M9N5TDyss = 1130 - INTEGER(IntKi), PARAMETER :: M9N6TDyss = 1131 - INTEGER(IntKi), PARAMETER :: M9N7TDyss = 1132 - INTEGER(IntKi), PARAMETER :: M9N8TDyss = 1133 - INTEGER(IntKi), PARAMETER :: M9N9TDyss = 1134 - INTEGER(IntKi), PARAMETER :: M1N1TDzss = 1135 - INTEGER(IntKi), PARAMETER :: M1N2TDzss = 1136 - INTEGER(IntKi), PARAMETER :: M1N3TDzss = 1137 - INTEGER(IntKi), PARAMETER :: M1N4TDzss = 1138 - INTEGER(IntKi), PARAMETER :: M1N5TDzss = 1139 - INTEGER(IntKi), PARAMETER :: M1N6TDzss = 1140 - INTEGER(IntKi), PARAMETER :: M1N7TDzss = 1141 - INTEGER(IntKi), PARAMETER :: M1N8TDzss = 1142 - INTEGER(IntKi), PARAMETER :: M1N9TDzss = 1143 - INTEGER(IntKi), PARAMETER :: M2N1TDzss = 1144 - INTEGER(IntKi), PARAMETER :: M2N2TDzss = 1145 - INTEGER(IntKi), PARAMETER :: M2N3TDzss = 1146 - INTEGER(IntKi), PARAMETER :: M2N4TDzss = 1147 - INTEGER(IntKi), PARAMETER :: M2N5TDzss = 1148 - INTEGER(IntKi), PARAMETER :: M2N6TDzss = 1149 - INTEGER(IntKi), PARAMETER :: M2N7TDzss = 1150 - INTEGER(IntKi), PARAMETER :: M2N8TDzss = 1151 - INTEGER(IntKi), PARAMETER :: M2N9TDzss = 1152 - INTEGER(IntKi), PARAMETER :: M3N1TDzss = 1153 - INTEGER(IntKi), PARAMETER :: M3N2TDzss = 1154 - INTEGER(IntKi), PARAMETER :: M3N3TDzss = 1155 - INTEGER(IntKi), PARAMETER :: M3N4TDzss = 1156 - INTEGER(IntKi), PARAMETER :: M3N5TDzss = 1157 - INTEGER(IntKi), PARAMETER :: M3N6TDzss = 1158 - INTEGER(IntKi), PARAMETER :: M3N7TDzss = 1159 - INTEGER(IntKi), PARAMETER :: M3N8TDzss = 1160 - INTEGER(IntKi), PARAMETER :: M3N9TDzss = 1161 - INTEGER(IntKi), PARAMETER :: M4N1TDzss = 1162 - INTEGER(IntKi), PARAMETER :: M4N2TDzss = 1163 - INTEGER(IntKi), PARAMETER :: M4N3TDzss = 1164 - INTEGER(IntKi), PARAMETER :: M4N4TDzss = 1165 - INTEGER(IntKi), PARAMETER :: M4N5TDzss = 1166 - INTEGER(IntKi), PARAMETER :: M4N6TDzss = 1167 - INTEGER(IntKi), PARAMETER :: M4N7TDzss = 1168 - INTEGER(IntKi), PARAMETER :: M4N8TDzss = 1169 - INTEGER(IntKi), PARAMETER :: M4N9TDzss = 1170 - INTEGER(IntKi), PARAMETER :: M5N1TDzss = 1171 - INTEGER(IntKi), PARAMETER :: M5N2TDzss = 1172 - INTEGER(IntKi), PARAMETER :: M5N3TDzss = 1173 - INTEGER(IntKi), PARAMETER :: M5N4TDzss = 1174 - INTEGER(IntKi), PARAMETER :: M5N5TDzss = 1175 - INTEGER(IntKi), PARAMETER :: M5N6TDzss = 1176 - INTEGER(IntKi), PARAMETER :: M5N7TDzss = 1177 - INTEGER(IntKi), PARAMETER :: M5N8TDzss = 1178 - INTEGER(IntKi), PARAMETER :: M5N9TDzss = 1179 - INTEGER(IntKi), PARAMETER :: M6N1TDzss = 1180 - INTEGER(IntKi), PARAMETER :: M6N2TDzss = 1181 - INTEGER(IntKi), PARAMETER :: M6N3TDzss = 1182 - INTEGER(IntKi), PARAMETER :: M6N4TDzss = 1183 - INTEGER(IntKi), PARAMETER :: M6N5TDzss = 1184 - INTEGER(IntKi), PARAMETER :: M6N6TDzss = 1185 - INTEGER(IntKi), PARAMETER :: M6N7TDzss = 1186 - INTEGER(IntKi), PARAMETER :: M6N8TDzss = 1187 - INTEGER(IntKi), PARAMETER :: M6N9TDzss = 1188 - INTEGER(IntKi), PARAMETER :: M7N1TDzss = 1189 - INTEGER(IntKi), PARAMETER :: M7N2TDzss = 1190 - INTEGER(IntKi), PARAMETER :: M7N3TDzss = 1191 - INTEGER(IntKi), PARAMETER :: M7N4TDzss = 1192 - INTEGER(IntKi), PARAMETER :: M7N5TDzss = 1193 - INTEGER(IntKi), PARAMETER :: M7N6TDzss = 1194 - INTEGER(IntKi), PARAMETER :: M7N7TDzss = 1195 - INTEGER(IntKi), PARAMETER :: M7N8TDzss = 1196 - INTEGER(IntKi), PARAMETER :: M7N9TDzss = 1197 - INTEGER(IntKi), PARAMETER :: M8N1TDzss = 1198 - INTEGER(IntKi), PARAMETER :: M8N2TDzss = 1199 - INTEGER(IntKi), PARAMETER :: M8N3TDzss = 1200 - INTEGER(IntKi), PARAMETER :: M8N4TDzss = 1201 - INTEGER(IntKi), PARAMETER :: M8N5TDzss = 1202 - INTEGER(IntKi), PARAMETER :: M8N6TDzss = 1203 - INTEGER(IntKi), PARAMETER :: M8N7TDzss = 1204 - INTEGER(IntKi), PARAMETER :: M8N8TDzss = 1205 - INTEGER(IntKi), PARAMETER :: M8N9TDzss = 1206 - INTEGER(IntKi), PARAMETER :: M9N1TDzss = 1207 - INTEGER(IntKi), PARAMETER :: M9N2TDzss = 1208 - INTEGER(IntKi), PARAMETER :: M9N3TDzss = 1209 - INTEGER(IntKi), PARAMETER :: M9N4TDzss = 1210 - INTEGER(IntKi), PARAMETER :: M9N5TDzss = 1211 - INTEGER(IntKi), PARAMETER :: M9N6TDzss = 1212 - INTEGER(IntKi), PARAMETER :: M9N7TDzss = 1213 - INTEGER(IntKi), PARAMETER :: M9N8TDzss = 1214 - INTEGER(IntKi), PARAMETER :: M9N9TDzss = 1215 - INTEGER(IntKi), PARAMETER :: M1N1RDxe = 1216 - INTEGER(IntKi), PARAMETER :: M1N2RDxe = 1217 - INTEGER(IntKi), PARAMETER :: M1N3RDxe = 1218 - INTEGER(IntKi), PARAMETER :: M1N4RDxe = 1219 - INTEGER(IntKi), PARAMETER :: M1N5RDxe = 1220 - INTEGER(IntKi), PARAMETER :: M1N6RDxe = 1221 - INTEGER(IntKi), PARAMETER :: M1N7RDxe = 1222 - INTEGER(IntKi), PARAMETER :: M1N8RDxe = 1223 - INTEGER(IntKi), PARAMETER :: M1N9RDxe = 1224 - INTEGER(IntKi), PARAMETER :: M2N1RDxe = 1225 - INTEGER(IntKi), PARAMETER :: M2N2RDxe = 1226 - INTEGER(IntKi), PARAMETER :: M2N3RDxe = 1227 - INTEGER(IntKi), PARAMETER :: M2N4RDxe = 1228 - INTEGER(IntKi), PARAMETER :: M2N5RDxe = 1229 - INTEGER(IntKi), PARAMETER :: M2N6RDxe = 1230 - INTEGER(IntKi), PARAMETER :: M2N7RDxe = 1231 - INTEGER(IntKi), PARAMETER :: M2N8RDxe = 1232 - INTEGER(IntKi), PARAMETER :: M2N9RDxe = 1233 - INTEGER(IntKi), PARAMETER :: M3N1RDxe = 1234 - INTEGER(IntKi), PARAMETER :: M3N2RDxe = 1235 - INTEGER(IntKi), PARAMETER :: M3N3RDxe = 1236 - INTEGER(IntKi), PARAMETER :: M3N4RDxe = 1237 - INTEGER(IntKi), PARAMETER :: M3N5RDxe = 1238 - INTEGER(IntKi), PARAMETER :: M3N6RDxe = 1239 - INTEGER(IntKi), PARAMETER :: M3N7RDxe = 1240 - INTEGER(IntKi), PARAMETER :: M3N8RDxe = 1241 - INTEGER(IntKi), PARAMETER :: M3N9RDxe = 1242 - INTEGER(IntKi), PARAMETER :: M4N1RDxe = 1243 - INTEGER(IntKi), PARAMETER :: M4N2RDxe = 1244 - INTEGER(IntKi), PARAMETER :: M4N3RDxe = 1245 - INTEGER(IntKi), PARAMETER :: M4N4RDxe = 1246 - INTEGER(IntKi), PARAMETER :: M4N5RDxe = 1247 - INTEGER(IntKi), PARAMETER :: M4N6RDxe = 1248 - INTEGER(IntKi), PARAMETER :: M4N7RDxe = 1249 - INTEGER(IntKi), PARAMETER :: M4N8RDxe = 1250 - INTEGER(IntKi), PARAMETER :: M4N9RDxe = 1251 - INTEGER(IntKi), PARAMETER :: M5N1RDxe = 1252 - INTEGER(IntKi), PARAMETER :: M5N2RDxe = 1253 - INTEGER(IntKi), PARAMETER :: M5N3RDxe = 1254 - INTEGER(IntKi), PARAMETER :: M5N4RDxe = 1255 - INTEGER(IntKi), PARAMETER :: M5N5RDxe = 1256 - INTEGER(IntKi), PARAMETER :: M5N6RDxe = 1257 - INTEGER(IntKi), PARAMETER :: M5N7RDxe = 1258 - INTEGER(IntKi), PARAMETER :: M5N8RDxe = 1259 - INTEGER(IntKi), PARAMETER :: M5N9RDxe = 1260 - INTEGER(IntKi), PARAMETER :: M6N1RDxe = 1261 - INTEGER(IntKi), PARAMETER :: M6N2RDxe = 1262 - INTEGER(IntKi), PARAMETER :: M6N3RDxe = 1263 - INTEGER(IntKi), PARAMETER :: M6N4RDxe = 1264 - INTEGER(IntKi), PARAMETER :: M6N5RDxe = 1265 - INTEGER(IntKi), PARAMETER :: M6N6RDxe = 1266 - INTEGER(IntKi), PARAMETER :: M6N7RDxe = 1267 - INTEGER(IntKi), PARAMETER :: M6N8RDxe = 1268 - INTEGER(IntKi), PARAMETER :: M6N9RDxe = 1269 - INTEGER(IntKi), PARAMETER :: M7N1RDxe = 1270 - INTEGER(IntKi), PARAMETER :: M7N2RDxe = 1271 - INTEGER(IntKi), PARAMETER :: M7N3RDxe = 1272 - INTEGER(IntKi), PARAMETER :: M7N4RDxe = 1273 - INTEGER(IntKi), PARAMETER :: M7N5RDxe = 1274 - INTEGER(IntKi), PARAMETER :: M7N6RDxe = 1275 - INTEGER(IntKi), PARAMETER :: M7N7RDxe = 1276 - INTEGER(IntKi), PARAMETER :: M7N8RDxe = 1277 - INTEGER(IntKi), PARAMETER :: M7N9RDxe = 1278 - INTEGER(IntKi), PARAMETER :: M8N1RDxe = 1279 - INTEGER(IntKi), PARAMETER :: M8N2RDxe = 1280 - INTEGER(IntKi), PARAMETER :: M8N3RDxe = 1281 - INTEGER(IntKi), PARAMETER :: M8N4RDxe = 1282 - INTEGER(IntKi), PARAMETER :: M8N5RDxe = 1283 - INTEGER(IntKi), PARAMETER :: M8N6RDxe = 1284 - INTEGER(IntKi), PARAMETER :: M8N7RDxe = 1285 - INTEGER(IntKi), PARAMETER :: M8N8RDxe = 1286 - INTEGER(IntKi), PARAMETER :: M8N9RDxe = 1287 - INTEGER(IntKi), PARAMETER :: M9N1RDxe = 1288 - INTEGER(IntKi), PARAMETER :: M9N2RDxe = 1289 - INTEGER(IntKi), PARAMETER :: M9N3RDxe = 1290 - INTEGER(IntKi), PARAMETER :: M9N4RDxe = 1291 - INTEGER(IntKi), PARAMETER :: M9N5RDxe = 1292 - INTEGER(IntKi), PARAMETER :: M9N6RDxe = 1293 - INTEGER(IntKi), PARAMETER :: M9N7RDxe = 1294 - INTEGER(IntKi), PARAMETER :: M9N8RDxe = 1295 - INTEGER(IntKi), PARAMETER :: M9N9RDxe = 1296 - INTEGER(IntKi), PARAMETER :: M1N1RDye = 1297 - INTEGER(IntKi), PARAMETER :: M1N2RDye = 1298 - INTEGER(IntKi), PARAMETER :: M1N3RDye = 1299 - INTEGER(IntKi), PARAMETER :: M1N4RDye = 1300 - INTEGER(IntKi), PARAMETER :: M1N5RDye = 1301 - INTEGER(IntKi), PARAMETER :: M1N6RDye = 1302 - INTEGER(IntKi), PARAMETER :: M1N7RDye = 1303 - INTEGER(IntKi), PARAMETER :: M1N8RDye = 1304 - INTEGER(IntKi), PARAMETER :: M1N9RDye = 1305 - INTEGER(IntKi), PARAMETER :: M2N1RDye = 1306 - INTEGER(IntKi), PARAMETER :: M2N2RDye = 1307 - INTEGER(IntKi), PARAMETER :: M2N3RDye = 1308 - INTEGER(IntKi), PARAMETER :: M2N4RDye = 1309 - INTEGER(IntKi), PARAMETER :: M2N5RDye = 1310 - INTEGER(IntKi), PARAMETER :: M2N6RDye = 1311 - INTEGER(IntKi), PARAMETER :: M2N7RDye = 1312 - INTEGER(IntKi), PARAMETER :: M2N8RDye = 1313 - INTEGER(IntKi), PARAMETER :: M2N9RDye = 1314 - INTEGER(IntKi), PARAMETER :: M3N1RDye = 1315 - INTEGER(IntKi), PARAMETER :: M3N2RDye = 1316 - INTEGER(IntKi), PARAMETER :: M3N3RDye = 1317 - INTEGER(IntKi), PARAMETER :: M3N4RDye = 1318 - INTEGER(IntKi), PARAMETER :: M3N5RDye = 1319 - INTEGER(IntKi), PARAMETER :: M3N6RDye = 1320 - INTEGER(IntKi), PARAMETER :: M3N7RDye = 1321 - INTEGER(IntKi), PARAMETER :: M3N8RDye = 1322 - INTEGER(IntKi), PARAMETER :: M3N9RDye = 1323 - INTEGER(IntKi), PARAMETER :: M4N1RDye = 1324 - INTEGER(IntKi), PARAMETER :: M4N2RDye = 1325 - INTEGER(IntKi), PARAMETER :: M4N3RDye = 1326 - INTEGER(IntKi), PARAMETER :: M4N4RDye = 1327 - INTEGER(IntKi), PARAMETER :: M4N5RDye = 1328 - INTEGER(IntKi), PARAMETER :: M4N6RDye = 1329 - INTEGER(IntKi), PARAMETER :: M4N7RDye = 1330 - INTEGER(IntKi), PARAMETER :: M4N8RDye = 1331 - INTEGER(IntKi), PARAMETER :: M4N9RDye = 1332 - INTEGER(IntKi), PARAMETER :: M5N1RDye = 1333 - INTEGER(IntKi), PARAMETER :: M5N2RDye = 1334 - INTEGER(IntKi), PARAMETER :: M5N3RDye = 1335 - INTEGER(IntKi), PARAMETER :: M5N4RDye = 1336 - INTEGER(IntKi), PARAMETER :: M5N5RDye = 1337 - INTEGER(IntKi), PARAMETER :: M5N6RDye = 1338 - INTEGER(IntKi), PARAMETER :: M5N7RDye = 1339 - INTEGER(IntKi), PARAMETER :: M5N8RDye = 1340 - INTEGER(IntKi), PARAMETER :: M5N9RDye = 1341 - INTEGER(IntKi), PARAMETER :: M6N1RDye = 1342 - INTEGER(IntKi), PARAMETER :: M6N2RDye = 1343 - INTEGER(IntKi), PARAMETER :: M6N3RDye = 1344 - INTEGER(IntKi), PARAMETER :: M6N4RDye = 1345 - INTEGER(IntKi), PARAMETER :: M6N5RDye = 1346 - INTEGER(IntKi), PARAMETER :: M6N6RDye = 1347 - INTEGER(IntKi), PARAMETER :: M6N7RDye = 1348 - INTEGER(IntKi), PARAMETER :: M6N8RDye = 1349 - INTEGER(IntKi), PARAMETER :: M6N9RDye = 1350 - INTEGER(IntKi), PARAMETER :: M7N1RDye = 1351 - INTEGER(IntKi), PARAMETER :: M7N2RDye = 1352 - INTEGER(IntKi), PARAMETER :: M7N3RDye = 1353 - INTEGER(IntKi), PARAMETER :: M7N4RDye = 1354 - INTEGER(IntKi), PARAMETER :: M7N5RDye = 1355 - INTEGER(IntKi), PARAMETER :: M7N6RDye = 1356 - INTEGER(IntKi), PARAMETER :: M7N7RDye = 1357 - INTEGER(IntKi), PARAMETER :: M7N8RDye = 1358 - INTEGER(IntKi), PARAMETER :: M7N9RDye = 1359 - INTEGER(IntKi), PARAMETER :: M8N1RDye = 1360 - INTEGER(IntKi), PARAMETER :: M8N2RDye = 1361 - INTEGER(IntKi), PARAMETER :: M8N3RDye = 1362 - INTEGER(IntKi), PARAMETER :: M8N4RDye = 1363 - INTEGER(IntKi), PARAMETER :: M8N5RDye = 1364 - INTEGER(IntKi), PARAMETER :: M8N6RDye = 1365 - INTEGER(IntKi), PARAMETER :: M8N7RDye = 1366 - INTEGER(IntKi), PARAMETER :: M8N8RDye = 1367 - INTEGER(IntKi), PARAMETER :: M8N9RDye = 1368 - INTEGER(IntKi), PARAMETER :: M9N1RDye = 1369 - INTEGER(IntKi), PARAMETER :: M9N2RDye = 1370 - INTEGER(IntKi), PARAMETER :: M9N3RDye = 1371 - INTEGER(IntKi), PARAMETER :: M9N4RDye = 1372 - INTEGER(IntKi), PARAMETER :: M9N5RDye = 1373 - INTEGER(IntKi), PARAMETER :: M9N6RDye = 1374 - INTEGER(IntKi), PARAMETER :: M9N7RDye = 1375 - INTEGER(IntKi), PARAMETER :: M9N8RDye = 1376 - INTEGER(IntKi), PARAMETER :: M9N9RDye = 1377 - INTEGER(IntKi), PARAMETER :: M1N1RDze = 1378 - INTEGER(IntKi), PARAMETER :: M1N2RDze = 1379 - INTEGER(IntKi), PARAMETER :: M1N3RDze = 1380 - INTEGER(IntKi), PARAMETER :: M1N4RDze = 1381 - INTEGER(IntKi), PARAMETER :: M1N5RDze = 1382 - INTEGER(IntKi), PARAMETER :: M1N6RDze = 1383 - INTEGER(IntKi), PARAMETER :: M1N7RDze = 1384 - INTEGER(IntKi), PARAMETER :: M1N8RDze = 1385 - INTEGER(IntKi), PARAMETER :: M1N9RDze = 1386 - INTEGER(IntKi), PARAMETER :: M2N1RDze = 1387 - INTEGER(IntKi), PARAMETER :: M2N2RDze = 1388 - INTEGER(IntKi), PARAMETER :: M2N3RDze = 1389 - INTEGER(IntKi), PARAMETER :: M2N4RDze = 1390 - INTEGER(IntKi), PARAMETER :: M2N5RDze = 1391 - INTEGER(IntKi), PARAMETER :: M2N6RDze = 1392 - INTEGER(IntKi), PARAMETER :: M2N7RDze = 1393 - INTEGER(IntKi), PARAMETER :: M2N8RDze = 1394 - INTEGER(IntKi), PARAMETER :: M2N9RDze = 1395 - INTEGER(IntKi), PARAMETER :: M3N1RDze = 1396 - INTEGER(IntKi), PARAMETER :: M3N2RDze = 1397 - INTEGER(IntKi), PARAMETER :: M3N3RDze = 1398 - INTEGER(IntKi), PARAMETER :: M3N4RDze = 1399 - INTEGER(IntKi), PARAMETER :: M3N5RDze = 1400 - INTEGER(IntKi), PARAMETER :: M3N6RDze = 1401 - INTEGER(IntKi), PARAMETER :: M3N7RDze = 1402 - INTEGER(IntKi), PARAMETER :: M3N8RDze = 1403 - INTEGER(IntKi), PARAMETER :: M3N9RDze = 1404 - INTEGER(IntKi), PARAMETER :: M4N1RDze = 1405 - INTEGER(IntKi), PARAMETER :: M4N2RDze = 1406 - INTEGER(IntKi), PARAMETER :: M4N3RDze = 1407 - INTEGER(IntKi), PARAMETER :: M4N4RDze = 1408 - INTEGER(IntKi), PARAMETER :: M4N5RDze = 1409 - INTEGER(IntKi), PARAMETER :: M4N6RDze = 1410 - INTEGER(IntKi), PARAMETER :: M4N7RDze = 1411 - INTEGER(IntKi), PARAMETER :: M4N8RDze = 1412 - INTEGER(IntKi), PARAMETER :: M4N9RDze = 1413 - INTEGER(IntKi), PARAMETER :: M5N1RDze = 1414 - INTEGER(IntKi), PARAMETER :: M5N2RDze = 1415 - INTEGER(IntKi), PARAMETER :: M5N3RDze = 1416 - INTEGER(IntKi), PARAMETER :: M5N4RDze = 1417 - INTEGER(IntKi), PARAMETER :: M5N5RDze = 1418 - INTEGER(IntKi), PARAMETER :: M5N6RDze = 1419 - INTEGER(IntKi), PARAMETER :: M5N7RDze = 1420 - INTEGER(IntKi), PARAMETER :: M5N8RDze = 1421 - INTEGER(IntKi), PARAMETER :: M5N9RDze = 1422 - INTEGER(IntKi), PARAMETER :: M6N1RDze = 1423 - INTEGER(IntKi), PARAMETER :: M6N2RDze = 1424 - INTEGER(IntKi), PARAMETER :: M6N3RDze = 1425 - INTEGER(IntKi), PARAMETER :: M6N4RDze = 1426 - INTEGER(IntKi), PARAMETER :: M6N5RDze = 1427 - INTEGER(IntKi), PARAMETER :: M6N6RDze = 1428 - INTEGER(IntKi), PARAMETER :: M6N7RDze = 1429 - INTEGER(IntKi), PARAMETER :: M6N8RDze = 1430 - INTEGER(IntKi), PARAMETER :: M6N9RDze = 1431 - INTEGER(IntKi), PARAMETER :: M7N1RDze = 1432 - INTEGER(IntKi), PARAMETER :: M7N2RDze = 1433 - INTEGER(IntKi), PARAMETER :: M7N3RDze = 1434 - INTEGER(IntKi), PARAMETER :: M7N4RDze = 1435 - INTEGER(IntKi), PARAMETER :: M7N5RDze = 1436 - INTEGER(IntKi), PARAMETER :: M7N6RDze = 1437 - INTEGER(IntKi), PARAMETER :: M7N7RDze = 1438 - INTEGER(IntKi), PARAMETER :: M7N8RDze = 1439 - INTEGER(IntKi), PARAMETER :: M7N9RDze = 1440 - INTEGER(IntKi), PARAMETER :: M8N1RDze = 1441 - INTEGER(IntKi), PARAMETER :: M8N2RDze = 1442 - INTEGER(IntKi), PARAMETER :: M8N3RDze = 1443 - INTEGER(IntKi), PARAMETER :: M8N4RDze = 1444 - INTEGER(IntKi), PARAMETER :: M8N5RDze = 1445 - INTEGER(IntKi), PARAMETER :: M8N6RDze = 1446 - INTEGER(IntKi), PARAMETER :: M8N7RDze = 1447 - INTEGER(IntKi), PARAMETER :: M8N8RDze = 1448 - INTEGER(IntKi), PARAMETER :: M8N9RDze = 1449 - INTEGER(IntKi), PARAMETER :: M9N1RDze = 1450 - INTEGER(IntKi), PARAMETER :: M9N2RDze = 1451 - INTEGER(IntKi), PARAMETER :: M9N3RDze = 1452 - INTEGER(IntKi), PARAMETER :: M9N4RDze = 1453 - INTEGER(IntKi), PARAMETER :: M9N5RDze = 1454 - INTEGER(IntKi), PARAMETER :: M9N6RDze = 1455 - INTEGER(IntKi), PARAMETER :: M9N7RDze = 1456 - INTEGER(IntKi), PARAMETER :: M9N8RDze = 1457 - INTEGER(IntKi), PARAMETER :: M9N9RDze = 1458 - - - ! Accelerations: - - INTEGER(IntKi), PARAMETER :: M1N1TAxe = 1459 - INTEGER(IntKi), PARAMETER :: M1N2TAxe = 1460 - INTEGER(IntKi), PARAMETER :: M1N3TAxe = 1461 - INTEGER(IntKi), PARAMETER :: M1N4TAxe = 1462 - INTEGER(IntKi), PARAMETER :: M1N5TAxe = 1463 - INTEGER(IntKi), PARAMETER :: M1N6TAxe = 1464 - INTEGER(IntKi), PARAMETER :: M1N7TAxe = 1465 - INTEGER(IntKi), PARAMETER :: M1N8TAxe = 1466 - INTEGER(IntKi), PARAMETER :: M1N9TAxe = 1467 - INTEGER(IntKi), PARAMETER :: M2N1TAxe = 1468 - INTEGER(IntKi), PARAMETER :: M2N2TAxe = 1469 - INTEGER(IntKi), PARAMETER :: M2N3TAxe = 1470 - INTEGER(IntKi), PARAMETER :: M2N4TAxe = 1471 - INTEGER(IntKi), PARAMETER :: M2N5TAxe = 1472 - INTEGER(IntKi), PARAMETER :: M2N6TAxe = 1473 - INTEGER(IntKi), PARAMETER :: M2N7TAxe = 1474 - INTEGER(IntKi), PARAMETER :: M2N8TAxe = 1475 - INTEGER(IntKi), PARAMETER :: M2N9TAxe = 1476 - INTEGER(IntKi), PARAMETER :: M3N1TAxe = 1477 - INTEGER(IntKi), PARAMETER :: M3N2TAxe = 1478 - INTEGER(IntKi), PARAMETER :: M3N3TAxe = 1479 - INTEGER(IntKi), PARAMETER :: M3N4TAxe = 1480 - INTEGER(IntKi), PARAMETER :: M3N5TAxe = 1481 - INTEGER(IntKi), PARAMETER :: M3N6TAxe = 1482 - INTEGER(IntKi), PARAMETER :: M3N7TAxe = 1483 - INTEGER(IntKi), PARAMETER :: M3N8TAxe = 1484 - INTEGER(IntKi), PARAMETER :: M3N9TAxe = 1485 - INTEGER(IntKi), PARAMETER :: M4N1TAxe = 1486 - INTEGER(IntKi), PARAMETER :: M4N2TAxe = 1487 - INTEGER(IntKi), PARAMETER :: M4N3TAxe = 1488 - INTEGER(IntKi), PARAMETER :: M4N4TAxe = 1489 - INTEGER(IntKi), PARAMETER :: M4N5TAxe = 1490 - INTEGER(IntKi), PARAMETER :: M4N6TAxe = 1491 - INTEGER(IntKi), PARAMETER :: M4N7TAxe = 1492 - INTEGER(IntKi), PARAMETER :: M4N8TAxe = 1493 - INTEGER(IntKi), PARAMETER :: M4N9TAxe = 1494 - INTEGER(IntKi), PARAMETER :: M5N1TAxe = 1495 - INTEGER(IntKi), PARAMETER :: M5N2TAxe = 1496 - INTEGER(IntKi), PARAMETER :: M5N3TAxe = 1497 - INTEGER(IntKi), PARAMETER :: M5N4TAxe = 1498 - INTEGER(IntKi), PARAMETER :: M5N5TAxe = 1499 - INTEGER(IntKi), PARAMETER :: M5N6TAxe = 1500 - INTEGER(IntKi), PARAMETER :: M5N7TAxe = 1501 - INTEGER(IntKi), PARAMETER :: M5N8TAxe = 1502 - INTEGER(IntKi), PARAMETER :: M5N9TAxe = 1503 - INTEGER(IntKi), PARAMETER :: M6N1TAxe = 1504 - INTEGER(IntKi), PARAMETER :: M6N2TAxe = 1505 - INTEGER(IntKi), PARAMETER :: M6N3TAxe = 1506 - INTEGER(IntKi), PARAMETER :: M6N4TAxe = 1507 - INTEGER(IntKi), PARAMETER :: M6N5TAxe = 1508 - INTEGER(IntKi), PARAMETER :: M6N6TAxe = 1509 - INTEGER(IntKi), PARAMETER :: M6N7TAxe = 1510 - INTEGER(IntKi), PARAMETER :: M6N8TAxe = 1511 - INTEGER(IntKi), PARAMETER :: M6N9TAxe = 1512 - INTEGER(IntKi), PARAMETER :: M7N1TAxe = 1513 - INTEGER(IntKi), PARAMETER :: M7N2TAxe = 1514 - INTEGER(IntKi), PARAMETER :: M7N3TAxe = 1515 - INTEGER(IntKi), PARAMETER :: M7N4TAxe = 1516 - INTEGER(IntKi), PARAMETER :: M7N5TAxe = 1517 - INTEGER(IntKi), PARAMETER :: M7N6TAxe = 1518 - INTEGER(IntKi), PARAMETER :: M7N7TAxe = 1519 - INTEGER(IntKi), PARAMETER :: M7N8TAxe = 1520 - INTEGER(IntKi), PARAMETER :: M7N9TAxe = 1521 - INTEGER(IntKi), PARAMETER :: M8N1TAxe = 1522 - INTEGER(IntKi), PARAMETER :: M8N2TAxe = 1523 - INTEGER(IntKi), PARAMETER :: M8N3TAxe = 1524 - INTEGER(IntKi), PARAMETER :: M8N4TAxe = 1525 - INTEGER(IntKi), PARAMETER :: M8N5TAxe = 1526 - INTEGER(IntKi), PARAMETER :: M8N6TAxe = 1527 - INTEGER(IntKi), PARAMETER :: M8N7TAxe = 1528 - INTEGER(IntKi), PARAMETER :: M8N8TAxe = 1529 - INTEGER(IntKi), PARAMETER :: M8N9TAxe = 1530 - INTEGER(IntKi), PARAMETER :: M9N1TAxe = 1531 - INTEGER(IntKi), PARAMETER :: M9N2TAxe = 1532 - INTEGER(IntKi), PARAMETER :: M9N3TAxe = 1533 - INTEGER(IntKi), PARAMETER :: M9N4TAxe = 1534 - INTEGER(IntKi), PARAMETER :: M9N5TAxe = 1535 - INTEGER(IntKi), PARAMETER :: M9N6TAxe = 1536 - INTEGER(IntKi), PARAMETER :: M9N7TAxe = 1537 - INTEGER(IntKi), PARAMETER :: M9N8TAxe = 1538 - INTEGER(IntKi), PARAMETER :: M9N9TAxe = 1539 - INTEGER(IntKi), PARAMETER :: M1N1TAye = 1540 - INTEGER(IntKi), PARAMETER :: M1N2TAye = 1541 - INTEGER(IntKi), PARAMETER :: M1N3TAye = 1542 - INTEGER(IntKi), PARAMETER :: M1N4TAye = 1543 - INTEGER(IntKi), PARAMETER :: M1N5TAye = 1544 - INTEGER(IntKi), PARAMETER :: M1N6TAye = 1545 - INTEGER(IntKi), PARAMETER :: M1N7TAye = 1546 - INTEGER(IntKi), PARAMETER :: M1N8TAye = 1547 - INTEGER(IntKi), PARAMETER :: M1N9TAye = 1548 - INTEGER(IntKi), PARAMETER :: M2N1TAye = 1549 - INTEGER(IntKi), PARAMETER :: M2N2TAye = 1550 - INTEGER(IntKi), PARAMETER :: M2N3TAye = 1551 - INTEGER(IntKi), PARAMETER :: M2N4TAye = 1552 - INTEGER(IntKi), PARAMETER :: M2N5TAye = 1553 - INTEGER(IntKi), PARAMETER :: M2N6TAye = 1554 - INTEGER(IntKi), PARAMETER :: M2N7TAye = 1555 - INTEGER(IntKi), PARAMETER :: M2N8TAye = 1556 - INTEGER(IntKi), PARAMETER :: M2N9TAye = 1557 - INTEGER(IntKi), PARAMETER :: M3N1TAye = 1558 - INTEGER(IntKi), PARAMETER :: M3N2TAye = 1559 - INTEGER(IntKi), PARAMETER :: M3N3TAye = 1560 - INTEGER(IntKi), PARAMETER :: M3N4TAye = 1561 - INTEGER(IntKi), PARAMETER :: M3N5TAye = 1562 - INTEGER(IntKi), PARAMETER :: M3N6TAye = 1563 - INTEGER(IntKi), PARAMETER :: M3N7TAye = 1564 - INTEGER(IntKi), PARAMETER :: M3N8TAye = 1565 - INTEGER(IntKi), PARAMETER :: M3N9TAye = 1566 - INTEGER(IntKi), PARAMETER :: M4N1TAye = 1567 - INTEGER(IntKi), PARAMETER :: M4N2TAye = 1568 - INTEGER(IntKi), PARAMETER :: M4N3TAye = 1569 - INTEGER(IntKi), PARAMETER :: M4N4TAye = 1570 - INTEGER(IntKi), PARAMETER :: M4N5TAye = 1571 - INTEGER(IntKi), PARAMETER :: M4N6TAye = 1572 - INTEGER(IntKi), PARAMETER :: M4N7TAye = 1573 - INTEGER(IntKi), PARAMETER :: M4N8TAye = 1574 - INTEGER(IntKi), PARAMETER :: M4N9TAye = 1575 - INTEGER(IntKi), PARAMETER :: M5N1TAye = 1576 - INTEGER(IntKi), PARAMETER :: M5N2TAye = 1577 - INTEGER(IntKi), PARAMETER :: M5N3TAye = 1578 - INTEGER(IntKi), PARAMETER :: M5N4TAye = 1579 - INTEGER(IntKi), PARAMETER :: M5N5TAye = 1580 - INTEGER(IntKi), PARAMETER :: M5N6TAye = 1581 - INTEGER(IntKi), PARAMETER :: M5N7TAye = 1582 - INTEGER(IntKi), PARAMETER :: M5N8TAye = 1583 - INTEGER(IntKi), PARAMETER :: M5N9TAye = 1584 - INTEGER(IntKi), PARAMETER :: M6N1TAye = 1585 - INTEGER(IntKi), PARAMETER :: M6N2TAye = 1586 - INTEGER(IntKi), PARAMETER :: M6N3TAye = 1587 - INTEGER(IntKi), PARAMETER :: M6N4TAye = 1588 - INTEGER(IntKi), PARAMETER :: M6N5TAye = 1589 - INTEGER(IntKi), PARAMETER :: M6N6TAye = 1590 - INTEGER(IntKi), PARAMETER :: M6N7TAye = 1591 - INTEGER(IntKi), PARAMETER :: M6N8TAye = 1592 - INTEGER(IntKi), PARAMETER :: M6N9TAye = 1593 - INTEGER(IntKi), PARAMETER :: M7N1TAye = 1594 - INTEGER(IntKi), PARAMETER :: M7N2TAye = 1595 - INTEGER(IntKi), PARAMETER :: M7N3TAye = 1596 - INTEGER(IntKi), PARAMETER :: M7N4TAye = 1597 - INTEGER(IntKi), PARAMETER :: M7N5TAye = 1598 - INTEGER(IntKi), PARAMETER :: M7N6TAye = 1599 - INTEGER(IntKi), PARAMETER :: M7N7TAye = 1600 - INTEGER(IntKi), PARAMETER :: M7N8TAye = 1601 - INTEGER(IntKi), PARAMETER :: M7N9TAye = 1602 - INTEGER(IntKi), PARAMETER :: M8N1TAye = 1603 - INTEGER(IntKi), PARAMETER :: M8N2TAye = 1604 - INTEGER(IntKi), PARAMETER :: M8N3TAye = 1605 - INTEGER(IntKi), PARAMETER :: M8N4TAye = 1606 - INTEGER(IntKi), PARAMETER :: M8N5TAye = 1607 - INTEGER(IntKi), PARAMETER :: M8N6TAye = 1608 - INTEGER(IntKi), PARAMETER :: M8N7TAye = 1609 - INTEGER(IntKi), PARAMETER :: M8N8TAye = 1610 - INTEGER(IntKi), PARAMETER :: M8N9TAye = 1611 - INTEGER(IntKi), PARAMETER :: M9N1TAye = 1612 - INTEGER(IntKi), PARAMETER :: M9N2TAye = 1613 - INTEGER(IntKi), PARAMETER :: M9N3TAye = 1614 - INTEGER(IntKi), PARAMETER :: M9N4TAye = 1615 - INTEGER(IntKi), PARAMETER :: M9N5TAye = 1616 - INTEGER(IntKi), PARAMETER :: M9N6TAye = 1617 - INTEGER(IntKi), PARAMETER :: M9N7TAye = 1618 - INTEGER(IntKi), PARAMETER :: M9N8TAye = 1619 - INTEGER(IntKi), PARAMETER :: M9N9TAye = 1620 - INTEGER(IntKi), PARAMETER :: M1N1TAze = 1621 - INTEGER(IntKi), PARAMETER :: M1N2TAze = 1622 - INTEGER(IntKi), PARAMETER :: M1N3TAze = 1623 - INTEGER(IntKi), PARAMETER :: M1N4TAze = 1624 - INTEGER(IntKi), PARAMETER :: M1N5TAze = 1625 - INTEGER(IntKi), PARAMETER :: M1N6TAze = 1626 - INTEGER(IntKi), PARAMETER :: M1N7TAze = 1627 - INTEGER(IntKi), PARAMETER :: M1N8TAze = 1628 - INTEGER(IntKi), PARAMETER :: M1N9TAze = 1629 - INTEGER(IntKi), PARAMETER :: M2N1TAze = 1630 - INTEGER(IntKi), PARAMETER :: M2N2TAze = 1631 - INTEGER(IntKi), PARAMETER :: M2N3TAze = 1632 - INTEGER(IntKi), PARAMETER :: M2N4TAze = 1633 - INTEGER(IntKi), PARAMETER :: M2N5TAze = 1634 - INTEGER(IntKi), PARAMETER :: M2N6TAze = 1635 - INTEGER(IntKi), PARAMETER :: M2N7TAze = 1636 - INTEGER(IntKi), PARAMETER :: M2N8TAze = 1637 - INTEGER(IntKi), PARAMETER :: M2N9TAze = 1638 - INTEGER(IntKi), PARAMETER :: M3N1TAze = 1639 - INTEGER(IntKi), PARAMETER :: M3N2TAze = 1640 - INTEGER(IntKi), PARAMETER :: M3N3TAze = 1641 - INTEGER(IntKi), PARAMETER :: M3N4TAze = 1642 - INTEGER(IntKi), PARAMETER :: M3N5TAze = 1643 - INTEGER(IntKi), PARAMETER :: M3N6TAze = 1644 - INTEGER(IntKi), PARAMETER :: M3N7TAze = 1645 - INTEGER(IntKi), PARAMETER :: M3N8TAze = 1646 - INTEGER(IntKi), PARAMETER :: M3N9TAze = 1647 - INTEGER(IntKi), PARAMETER :: M4N1TAze = 1648 - INTEGER(IntKi), PARAMETER :: M4N2TAze = 1649 - INTEGER(IntKi), PARAMETER :: M4N3TAze = 1650 - INTEGER(IntKi), PARAMETER :: M4N4TAze = 1651 - INTEGER(IntKi), PARAMETER :: M4N5TAze = 1652 - INTEGER(IntKi), PARAMETER :: M4N6TAze = 1653 - INTEGER(IntKi), PARAMETER :: M4N7TAze = 1654 - INTEGER(IntKi), PARAMETER :: M4N8TAze = 1655 - INTEGER(IntKi), PARAMETER :: M4N9TAze = 1656 - INTEGER(IntKi), PARAMETER :: M5N1TAze = 1657 - INTEGER(IntKi), PARAMETER :: M5N2TAze = 1658 - INTEGER(IntKi), PARAMETER :: M5N3TAze = 1659 - INTEGER(IntKi), PARAMETER :: M5N4TAze = 1660 - INTEGER(IntKi), PARAMETER :: M5N5TAze = 1661 - INTEGER(IntKi), PARAMETER :: M5N6TAze = 1662 - INTEGER(IntKi), PARAMETER :: M5N7TAze = 1663 - INTEGER(IntKi), PARAMETER :: M5N8TAze = 1664 - INTEGER(IntKi), PARAMETER :: M5N9TAze = 1665 - INTEGER(IntKi), PARAMETER :: M6N1TAze = 1666 - INTEGER(IntKi), PARAMETER :: M6N2TAze = 1667 - INTEGER(IntKi), PARAMETER :: M6N3TAze = 1668 - INTEGER(IntKi), PARAMETER :: M6N4TAze = 1669 - INTEGER(IntKi), PARAMETER :: M6N5TAze = 1670 - INTEGER(IntKi), PARAMETER :: M6N6TAze = 1671 - INTEGER(IntKi), PARAMETER :: M6N7TAze = 1672 - INTEGER(IntKi), PARAMETER :: M6N8TAze = 1673 - INTEGER(IntKi), PARAMETER :: M6N9TAze = 1674 - INTEGER(IntKi), PARAMETER :: M7N1TAze = 1675 - INTEGER(IntKi), PARAMETER :: M7N2TAze = 1676 - INTEGER(IntKi), PARAMETER :: M7N3TAze = 1677 - INTEGER(IntKi), PARAMETER :: M7N4TAze = 1678 - INTEGER(IntKi), PARAMETER :: M7N5TAze = 1679 - INTEGER(IntKi), PARAMETER :: M7N6TAze = 1680 - INTEGER(IntKi), PARAMETER :: M7N7TAze = 1681 - INTEGER(IntKi), PARAMETER :: M7N8TAze = 1682 - INTEGER(IntKi), PARAMETER :: M7N9TAze = 1683 - INTEGER(IntKi), PARAMETER :: M8N1TAze = 1684 - INTEGER(IntKi), PARAMETER :: M8N2TAze = 1685 - INTEGER(IntKi), PARAMETER :: M8N3TAze = 1686 - INTEGER(IntKi), PARAMETER :: M8N4TAze = 1687 - INTEGER(IntKi), PARAMETER :: M8N5TAze = 1688 - INTEGER(IntKi), PARAMETER :: M8N6TAze = 1689 - INTEGER(IntKi), PARAMETER :: M8N7TAze = 1690 - INTEGER(IntKi), PARAMETER :: M8N8TAze = 1691 - INTEGER(IntKi), PARAMETER :: M8N9TAze = 1692 - INTEGER(IntKi), PARAMETER :: M9N1TAze = 1693 - INTEGER(IntKi), PARAMETER :: M9N2TAze = 1694 - INTEGER(IntKi), PARAMETER :: M9N3TAze = 1695 - INTEGER(IntKi), PARAMETER :: M9N4TAze = 1696 - INTEGER(IntKi), PARAMETER :: M9N5TAze = 1697 - INTEGER(IntKi), PARAMETER :: M9N6TAze = 1698 - INTEGER(IntKi), PARAMETER :: M9N7TAze = 1699 - INTEGER(IntKi), PARAMETER :: M9N8TAze = 1700 - INTEGER(IntKi), PARAMETER :: M9N9TAze = 1701 - INTEGER(IntKi), PARAMETER :: M1N1RAxe = 1702 - INTEGER(IntKi), PARAMETER :: M1N2RAxe = 1703 - INTEGER(IntKi), PARAMETER :: M1N3RAxe = 1704 - INTEGER(IntKi), PARAMETER :: M1N4RAxe = 1705 - INTEGER(IntKi), PARAMETER :: M1N5RAxe = 1706 - INTEGER(IntKi), PARAMETER :: M1N6RAxe = 1707 - INTEGER(IntKi), PARAMETER :: M1N7RAxe = 1708 - INTEGER(IntKi), PARAMETER :: M1N8RAxe = 1709 - INTEGER(IntKi), PARAMETER :: M1N9RAxe = 1710 - INTEGER(IntKi), PARAMETER :: M2N1RAxe = 1711 - INTEGER(IntKi), PARAMETER :: M2N2RAxe = 1712 - INTEGER(IntKi), PARAMETER :: M2N3RAxe = 1713 - INTEGER(IntKi), PARAMETER :: M2N4RAxe = 1714 - INTEGER(IntKi), PARAMETER :: M2N5RAxe = 1715 - INTEGER(IntKi), PARAMETER :: M2N6RAxe = 1716 - INTEGER(IntKi), PARAMETER :: M2N7RAxe = 1717 - INTEGER(IntKi), PARAMETER :: M2N8RAxe = 1718 - INTEGER(IntKi), PARAMETER :: M2N9RAxe = 1719 - INTEGER(IntKi), PARAMETER :: M3N1RAxe = 1720 - INTEGER(IntKi), PARAMETER :: M3N2RAxe = 1721 - INTEGER(IntKi), PARAMETER :: M3N3RAxe = 1722 - INTEGER(IntKi), PARAMETER :: M3N4RAxe = 1723 - INTEGER(IntKi), PARAMETER :: M3N5RAxe = 1724 - INTEGER(IntKi), PARAMETER :: M3N6RAxe = 1725 - INTEGER(IntKi), PARAMETER :: M3N7RAxe = 1726 - INTEGER(IntKi), PARAMETER :: M3N8RAxe = 1727 - INTEGER(IntKi), PARAMETER :: M3N9RAxe = 1728 - INTEGER(IntKi), PARAMETER :: M4N1RAxe = 1729 - INTEGER(IntKi), PARAMETER :: M4N2RAxe = 1730 - INTEGER(IntKi), PARAMETER :: M4N3RAxe = 1731 - INTEGER(IntKi), PARAMETER :: M4N4RAxe = 1732 - INTEGER(IntKi), PARAMETER :: M4N5RAxe = 1733 - INTEGER(IntKi), PARAMETER :: M4N6RAxe = 1734 - INTEGER(IntKi), PARAMETER :: M4N7RAxe = 1735 - INTEGER(IntKi), PARAMETER :: M4N8RAxe = 1736 - INTEGER(IntKi), PARAMETER :: M4N9RAxe = 1737 - INTEGER(IntKi), PARAMETER :: M5N1RAxe = 1738 - INTEGER(IntKi), PARAMETER :: M5N2RAxe = 1739 - INTEGER(IntKi), PARAMETER :: M5N3RAxe = 1740 - INTEGER(IntKi), PARAMETER :: M5N4RAxe = 1741 - INTEGER(IntKi), PARAMETER :: M5N5RAxe = 1742 - INTEGER(IntKi), PARAMETER :: M5N6RAxe = 1743 - INTEGER(IntKi), PARAMETER :: M5N7RAxe = 1744 - INTEGER(IntKi), PARAMETER :: M5N8RAxe = 1745 - INTEGER(IntKi), PARAMETER :: M5N9RAxe = 1746 - INTEGER(IntKi), PARAMETER :: M6N1RAxe = 1747 - INTEGER(IntKi), PARAMETER :: M6N2RAxe = 1748 - INTEGER(IntKi), PARAMETER :: M6N3RAxe = 1749 - INTEGER(IntKi), PARAMETER :: M6N4RAxe = 1750 - INTEGER(IntKi), PARAMETER :: M6N5RAxe = 1751 - INTEGER(IntKi), PARAMETER :: M6N6RAxe = 1752 - INTEGER(IntKi), PARAMETER :: M6N7RAxe = 1753 - INTEGER(IntKi), PARAMETER :: M6N8RAxe = 1754 - INTEGER(IntKi), PARAMETER :: M6N9RAxe = 1755 - INTEGER(IntKi), PARAMETER :: M7N1RAxe = 1756 - INTEGER(IntKi), PARAMETER :: M7N2RAxe = 1757 - INTEGER(IntKi), PARAMETER :: M7N3RAxe = 1758 - INTEGER(IntKi), PARAMETER :: M7N4RAxe = 1759 - INTEGER(IntKi), PARAMETER :: M7N5RAxe = 1760 - INTEGER(IntKi), PARAMETER :: M7N6RAxe = 1761 - INTEGER(IntKi), PARAMETER :: M7N7RAxe = 1762 - INTEGER(IntKi), PARAMETER :: M7N8RAxe = 1763 - INTEGER(IntKi), PARAMETER :: M7N9RAxe = 1764 - INTEGER(IntKi), PARAMETER :: M8N1RAxe = 1765 - INTEGER(IntKi), PARAMETER :: M8N2RAxe = 1766 - INTEGER(IntKi), PARAMETER :: M8N3RAxe = 1767 - INTEGER(IntKi), PARAMETER :: M8N4RAxe = 1768 - INTEGER(IntKi), PARAMETER :: M8N5RAxe = 1769 - INTEGER(IntKi), PARAMETER :: M8N6RAxe = 1770 - INTEGER(IntKi), PARAMETER :: M8N7RAxe = 1771 - INTEGER(IntKi), PARAMETER :: M8N8RAxe = 1772 - INTEGER(IntKi), PARAMETER :: M8N9RAxe = 1773 - INTEGER(IntKi), PARAMETER :: M9N1RAxe = 1774 - INTEGER(IntKi), PARAMETER :: M9N2RAxe = 1775 - INTEGER(IntKi), PARAMETER :: M9N3RAxe = 1776 - INTEGER(IntKi), PARAMETER :: M9N4RAxe = 1777 - INTEGER(IntKi), PARAMETER :: M9N5RAxe = 1778 - INTEGER(IntKi), PARAMETER :: M9N6RAxe = 1779 - INTEGER(IntKi), PARAMETER :: M9N7RAxe = 1780 - INTEGER(IntKi), PARAMETER :: M9N8RAxe = 1781 - INTEGER(IntKi), PARAMETER :: M9N9RAxe = 1782 - INTEGER(IntKi), PARAMETER :: M1N1RAye = 1783 - INTEGER(IntKi), PARAMETER :: M1N2RAye = 1784 - INTEGER(IntKi), PARAMETER :: M1N3RAye = 1785 - INTEGER(IntKi), PARAMETER :: M1N4RAye = 1786 - INTEGER(IntKi), PARAMETER :: M1N5RAye = 1787 - INTEGER(IntKi), PARAMETER :: M1N6RAye = 1788 - INTEGER(IntKi), PARAMETER :: M1N7RAye = 1789 - INTEGER(IntKi), PARAMETER :: M1N8RAye = 1790 - INTEGER(IntKi), PARAMETER :: M1N9RAye = 1791 - INTEGER(IntKi), PARAMETER :: M2N1RAye = 1792 - INTEGER(IntKi), PARAMETER :: M2N2RAye = 1793 - INTEGER(IntKi), PARAMETER :: M2N3RAye = 1794 - INTEGER(IntKi), PARAMETER :: M2N4RAye = 1795 - INTEGER(IntKi), PARAMETER :: M2N5RAye = 1796 - INTEGER(IntKi), PARAMETER :: M2N6RAye = 1797 - INTEGER(IntKi), PARAMETER :: M2N7RAye = 1798 - INTEGER(IntKi), PARAMETER :: M2N8RAye = 1799 - INTEGER(IntKi), PARAMETER :: M2N9RAye = 1800 - INTEGER(IntKi), PARAMETER :: M3N1RAye = 1801 - INTEGER(IntKi), PARAMETER :: M3N2RAye = 1802 - INTEGER(IntKi), PARAMETER :: M3N3RAye = 1803 - INTEGER(IntKi), PARAMETER :: M3N4RAye = 1804 - INTEGER(IntKi), PARAMETER :: M3N5RAye = 1805 - INTEGER(IntKi), PARAMETER :: M3N6RAye = 1806 - INTEGER(IntKi), PARAMETER :: M3N7RAye = 1807 - INTEGER(IntKi), PARAMETER :: M3N8RAye = 1808 - INTEGER(IntKi), PARAMETER :: M3N9RAye = 1809 - INTEGER(IntKi), PARAMETER :: M4N1RAye = 1810 - INTEGER(IntKi), PARAMETER :: M4N2RAye = 1811 - INTEGER(IntKi), PARAMETER :: M4N3RAye = 1812 - INTEGER(IntKi), PARAMETER :: M4N4RAye = 1813 - INTEGER(IntKi), PARAMETER :: M4N5RAye = 1814 - INTEGER(IntKi), PARAMETER :: M4N6RAye = 1815 - INTEGER(IntKi), PARAMETER :: M4N7RAye = 1816 - INTEGER(IntKi), PARAMETER :: M4N8RAye = 1817 - INTEGER(IntKi), PARAMETER :: M4N9RAye = 1818 - INTEGER(IntKi), PARAMETER :: M5N1RAye = 1819 - INTEGER(IntKi), PARAMETER :: M5N2RAye = 1820 - INTEGER(IntKi), PARAMETER :: M5N3RAye = 1821 - INTEGER(IntKi), PARAMETER :: M5N4RAye = 1822 - INTEGER(IntKi), PARAMETER :: M5N5RAye = 1823 - INTEGER(IntKi), PARAMETER :: M5N6RAye = 1824 - INTEGER(IntKi), PARAMETER :: M5N7RAye = 1825 - INTEGER(IntKi), PARAMETER :: M5N8RAye = 1826 - INTEGER(IntKi), PARAMETER :: M5N9RAye = 1827 - INTEGER(IntKi), PARAMETER :: M6N1RAye = 1828 - INTEGER(IntKi), PARAMETER :: M6N2RAye = 1829 - INTEGER(IntKi), PARAMETER :: M6N3RAye = 1830 - INTEGER(IntKi), PARAMETER :: M6N4RAye = 1831 - INTEGER(IntKi), PARAMETER :: M6N5RAye = 1832 - INTEGER(IntKi), PARAMETER :: M6N6RAye = 1833 - INTEGER(IntKi), PARAMETER :: M6N7RAye = 1834 - INTEGER(IntKi), PARAMETER :: M6N8RAye = 1835 - INTEGER(IntKi), PARAMETER :: M6N9RAye = 1836 - INTEGER(IntKi), PARAMETER :: M7N1RAye = 1837 - INTEGER(IntKi), PARAMETER :: M7N2RAye = 1838 - INTEGER(IntKi), PARAMETER :: M7N3RAye = 1839 - INTEGER(IntKi), PARAMETER :: M7N4RAye = 1840 - INTEGER(IntKi), PARAMETER :: M7N5RAye = 1841 - INTEGER(IntKi), PARAMETER :: M7N6RAye = 1842 - INTEGER(IntKi), PARAMETER :: M7N7RAye = 1843 - INTEGER(IntKi), PARAMETER :: M7N8RAye = 1844 - INTEGER(IntKi), PARAMETER :: M7N9RAye = 1845 - INTEGER(IntKi), PARAMETER :: M8N1RAye = 1846 - INTEGER(IntKi), PARAMETER :: M8N2RAye = 1847 - INTEGER(IntKi), PARAMETER :: M8N3RAye = 1848 - INTEGER(IntKi), PARAMETER :: M8N4RAye = 1849 - INTEGER(IntKi), PARAMETER :: M8N5RAye = 1850 - INTEGER(IntKi), PARAMETER :: M8N6RAye = 1851 - INTEGER(IntKi), PARAMETER :: M8N7RAye = 1852 - INTEGER(IntKi), PARAMETER :: M8N8RAye = 1853 - INTEGER(IntKi), PARAMETER :: M8N9RAye = 1854 - INTEGER(IntKi), PARAMETER :: M9N1RAye = 1855 - INTEGER(IntKi), PARAMETER :: M9N2RAye = 1856 - INTEGER(IntKi), PARAMETER :: M9N3RAye = 1857 - INTEGER(IntKi), PARAMETER :: M9N4RAye = 1858 - INTEGER(IntKi), PARAMETER :: M9N5RAye = 1859 - INTEGER(IntKi), PARAMETER :: M9N6RAye = 1860 - INTEGER(IntKi), PARAMETER :: M9N7RAye = 1861 - INTEGER(IntKi), PARAMETER :: M9N8RAye = 1862 - INTEGER(IntKi), PARAMETER :: M9N9RAye = 1863 - INTEGER(IntKi), PARAMETER :: M1N1RAze = 1864 - INTEGER(IntKi), PARAMETER :: M1N2RAze = 1865 - INTEGER(IntKi), PARAMETER :: M1N3RAze = 1866 - INTEGER(IntKi), PARAMETER :: M1N4RAze = 1867 - INTEGER(IntKi), PARAMETER :: M1N5RAze = 1868 - INTEGER(IntKi), PARAMETER :: M1N6RAze = 1869 - INTEGER(IntKi), PARAMETER :: M1N7RAze = 1870 - INTEGER(IntKi), PARAMETER :: M1N8RAze = 1871 - INTEGER(IntKi), PARAMETER :: M1N9RAze = 1872 - INTEGER(IntKi), PARAMETER :: M2N1RAze = 1873 - INTEGER(IntKi), PARAMETER :: M2N2RAze = 1874 - INTEGER(IntKi), PARAMETER :: M2N3RAze = 1875 - INTEGER(IntKi), PARAMETER :: M2N4RAze = 1876 - INTEGER(IntKi), PARAMETER :: M2N5RAze = 1877 - INTEGER(IntKi), PARAMETER :: M2N6RAze = 1878 - INTEGER(IntKi), PARAMETER :: M2N7RAze = 1879 - INTEGER(IntKi), PARAMETER :: M2N8RAze = 1880 - INTEGER(IntKi), PARAMETER :: M2N9RAze = 1881 - INTEGER(IntKi), PARAMETER :: M3N1RAze = 1882 - INTEGER(IntKi), PARAMETER :: M3N2RAze = 1883 - INTEGER(IntKi), PARAMETER :: M3N3RAze = 1884 - INTEGER(IntKi), PARAMETER :: M3N4RAze = 1885 - INTEGER(IntKi), PARAMETER :: M3N5RAze = 1886 - INTEGER(IntKi), PARAMETER :: M3N6RAze = 1887 - INTEGER(IntKi), PARAMETER :: M3N7RAze = 1888 - INTEGER(IntKi), PARAMETER :: M3N8RAze = 1889 - INTEGER(IntKi), PARAMETER :: M3N9RAze = 1890 - INTEGER(IntKi), PARAMETER :: M4N1RAze = 1891 - INTEGER(IntKi), PARAMETER :: M4N2RAze = 1892 - INTEGER(IntKi), PARAMETER :: M4N3RAze = 1893 - INTEGER(IntKi), PARAMETER :: M4N4RAze = 1894 - INTEGER(IntKi), PARAMETER :: M4N5RAze = 1895 - INTEGER(IntKi), PARAMETER :: M4N6RAze = 1896 - INTEGER(IntKi), PARAMETER :: M4N7RAze = 1897 - INTEGER(IntKi), PARAMETER :: M4N8RAze = 1898 - INTEGER(IntKi), PARAMETER :: M4N9RAze = 1899 - INTEGER(IntKi), PARAMETER :: M5N1RAze = 1900 - INTEGER(IntKi), PARAMETER :: M5N2RAze = 1901 - INTEGER(IntKi), PARAMETER :: M5N3RAze = 1902 - INTEGER(IntKi), PARAMETER :: M5N4RAze = 1903 - INTEGER(IntKi), PARAMETER :: M5N5RAze = 1904 - INTEGER(IntKi), PARAMETER :: M5N6RAze = 1905 - INTEGER(IntKi), PARAMETER :: M5N7RAze = 1906 - INTEGER(IntKi), PARAMETER :: M5N8RAze = 1907 - INTEGER(IntKi), PARAMETER :: M5N9RAze = 1908 - INTEGER(IntKi), PARAMETER :: M6N1RAze = 1909 - INTEGER(IntKi), PARAMETER :: M6N2RAze = 1910 - INTEGER(IntKi), PARAMETER :: M6N3RAze = 1911 - INTEGER(IntKi), PARAMETER :: M6N4RAze = 1912 - INTEGER(IntKi), PARAMETER :: M6N5RAze = 1913 - INTEGER(IntKi), PARAMETER :: M6N6RAze = 1914 - INTEGER(IntKi), PARAMETER :: M6N7RAze = 1915 - INTEGER(IntKi), PARAMETER :: M6N8RAze = 1916 - INTEGER(IntKi), PARAMETER :: M6N9RAze = 1917 - INTEGER(IntKi), PARAMETER :: M7N1RAze = 1918 - INTEGER(IntKi), PARAMETER :: M7N2RAze = 1919 - INTEGER(IntKi), PARAMETER :: M7N3RAze = 1920 - INTEGER(IntKi), PARAMETER :: M7N4RAze = 1921 - INTEGER(IntKi), PARAMETER :: M7N5RAze = 1922 - INTEGER(IntKi), PARAMETER :: M7N6RAze = 1923 - INTEGER(IntKi), PARAMETER :: M7N7RAze = 1924 - INTEGER(IntKi), PARAMETER :: M7N8RAze = 1925 - INTEGER(IntKi), PARAMETER :: M7N9RAze = 1926 - INTEGER(IntKi), PARAMETER :: M8N1RAze = 1927 - INTEGER(IntKi), PARAMETER :: M8N2RAze = 1928 - INTEGER(IntKi), PARAMETER :: M8N3RAze = 1929 - INTEGER(IntKi), PARAMETER :: M8N4RAze = 1930 - INTEGER(IntKi), PARAMETER :: M8N5RAze = 1931 - INTEGER(IntKi), PARAMETER :: M8N6RAze = 1932 - INTEGER(IntKi), PARAMETER :: M8N7RAze = 1933 - INTEGER(IntKi), PARAMETER :: M8N8RAze = 1934 - INTEGER(IntKi), PARAMETER :: M8N9RAze = 1935 - INTEGER(IntKi), PARAMETER :: M9N1RAze = 1936 - INTEGER(IntKi), PARAMETER :: M9N2RAze = 1937 - INTEGER(IntKi), PARAMETER :: M9N3RAze = 1938 - INTEGER(IntKi), PARAMETER :: M9N4RAze = 1939 - INTEGER(IntKi), PARAMETER :: M9N5RAze = 1940 - INTEGER(IntKi), PARAMETER :: M9N6RAze = 1941 - INTEGER(IntKi), PARAMETER :: M9N7RAze = 1942 - INTEGER(IntKi), PARAMETER :: M9N8RAze = 1943 - INTEGER(IntKi), PARAMETER :: M9N9RAze = 1944 - - - ! Reactions: - - INTEGER(IntKi), PARAMETER :: ReactFXss = 1945 - INTEGER(IntKi), PARAMETER :: ReactFYss = 1946 - INTEGER(IntKi), PARAMETER :: ReactFZss = 1947 - INTEGER(IntKi), PARAMETER :: ReactMXss = 1948 - INTEGER(IntKi), PARAMETER :: ReactMYss = 1949 - INTEGER(IntKi), PARAMETER :: ReactMZss = 1950 - INTEGER(IntKi), PARAMETER :: IntfFXss = 1951 - INTEGER(IntKi), PARAMETER :: IntfFYss = 1952 - INTEGER(IntKi), PARAMETER :: IntfFZss = 1953 - INTEGER(IntKi), PARAMETER :: IntfMXss = 1954 - INTEGER(IntKi), PARAMETER :: IntfMYss = 1955 - INTEGER(IntKi), PARAMETER :: IntfMZss = 1956 - - - ! Interface Deflections: - - INTEGER(IntKi), PARAMETER :: IntfTDXss = 1957 - INTEGER(IntKi), PARAMETER :: IntfTDYss = 1958 - INTEGER(IntKi), PARAMETER :: IntfTDZss = 1959 - INTEGER(IntKi), PARAMETER :: IntfRDXss = 1960 - INTEGER(IntKi), PARAMETER :: IntfRDYss = 1961 - INTEGER(IntKi), PARAMETER :: IntfRDZss = 1962 - - - ! Interface Accelerations: - - INTEGER(IntKi), PARAMETER :: IntfTAXss = 1963 - INTEGER(IntKi), PARAMETER :: IntfTAYss = 1964 - INTEGER(IntKi), PARAMETER :: IntfTAZss = 1965 - INTEGER(IntKi), PARAMETER :: IntfRAXss = 1966 - INTEGER(IntKi), PARAMETER :: IntfRAYss = 1967 - INTEGER(IntKi), PARAMETER :: IntfRAZss = 1968 - - - ! Modal Parameters: - - INTEGER(IntKi), PARAMETER :: SSqm01 = 1969 - INTEGER(IntKi), PARAMETER :: SSqm02 = 1970 - INTEGER(IntKi), PARAMETER :: SSqm03 = 1971 - INTEGER(IntKi), PARAMETER :: SSqm04 = 1972 - INTEGER(IntKi), PARAMETER :: SSqm05 = 1973 - INTEGER(IntKi), PARAMETER :: SSqm06 = 1974 - INTEGER(IntKi), PARAMETER :: SSqm07 = 1975 - INTEGER(IntKi), PARAMETER :: SSqm08 = 1976 - INTEGER(IntKi), PARAMETER :: SSqm09 = 1977 - INTEGER(IntKi), PARAMETER :: SSqm10 = 1978 - INTEGER(IntKi), PARAMETER :: SSqm11 = 1979 - INTEGER(IntKi), PARAMETER :: SSqm12 = 1980 - INTEGER(IntKi), PARAMETER :: SSqm13 = 1981 - INTEGER(IntKi), PARAMETER :: SSqm14 = 1982 - INTEGER(IntKi), PARAMETER :: SSqm15 = 1983 - INTEGER(IntKi), PARAMETER :: SSqm16 = 1984 - INTEGER(IntKi), PARAMETER :: SSqm17 = 1985 - INTEGER(IntKi), PARAMETER :: SSqm18 = 1986 - INTEGER(IntKi), PARAMETER :: SSqm19 = 1987 - INTEGER(IntKi), PARAMETER :: SSqm20 = 1988 - INTEGER(IntKi), PARAMETER :: SSqm21 = 1989 - INTEGER(IntKi), PARAMETER :: SSqm22 = 1990 - INTEGER(IntKi), PARAMETER :: SSqm23 = 1991 - INTEGER(IntKi), PARAMETER :: SSqm24 = 1992 - INTEGER(IntKi), PARAMETER :: SSqm25 = 1993 - INTEGER(IntKi), PARAMETER :: SSqm26 = 1994 - INTEGER(IntKi), PARAMETER :: SSqm27 = 1995 - INTEGER(IntKi), PARAMETER :: SSqm28 = 1996 - INTEGER(IntKi), PARAMETER :: SSqm29 = 1997 - INTEGER(IntKi), PARAMETER :: SSqm30 = 1998 - INTEGER(IntKi), PARAMETER :: SSqm31 = 1999 - INTEGER(IntKi), PARAMETER :: SSqm32 = 2000 - INTEGER(IntKi), PARAMETER :: SSqm33 = 2001 - INTEGER(IntKi), PARAMETER :: SSqm34 = 2002 - INTEGER(IntKi), PARAMETER :: SSqm35 = 2003 - INTEGER(IntKi), PARAMETER :: SSqm36 = 2004 - INTEGER(IntKi), PARAMETER :: SSqm37 = 2005 - INTEGER(IntKi), PARAMETER :: SSqm38 = 2006 - INTEGER(IntKi), PARAMETER :: SSqm39 = 2007 - INTEGER(IntKi), PARAMETER :: SSqm40 = 2008 - INTEGER(IntKi), PARAMETER :: SSqm41 = 2009 - INTEGER(IntKi), PARAMETER :: SSqm42 = 2010 - INTEGER(IntKi), PARAMETER :: SSqm43 = 2011 - INTEGER(IntKi), PARAMETER :: SSqm44 = 2012 - INTEGER(IntKi), PARAMETER :: SSqm45 = 2013 - INTEGER(IntKi), PARAMETER :: SSqm46 = 2014 - INTEGER(IntKi), PARAMETER :: SSqm47 = 2015 - INTEGER(IntKi), PARAMETER :: SSqm48 = 2016 - INTEGER(IntKi), PARAMETER :: SSqm49 = 2017 - INTEGER(IntKi), PARAMETER :: SSqm50 = 2018 - INTEGER(IntKi), PARAMETER :: SSqm51 = 2019 - INTEGER(IntKi), PARAMETER :: SSqm52 = 2020 - INTEGER(IntKi), PARAMETER :: SSqm53 = 2021 - INTEGER(IntKi), PARAMETER :: SSqm54 = 2022 - INTEGER(IntKi), PARAMETER :: SSqm55 = 2023 - INTEGER(IntKi), PARAMETER :: SSqm56 = 2024 - INTEGER(IntKi), PARAMETER :: SSqm57 = 2025 - INTEGER(IntKi), PARAMETER :: SSqm58 = 2026 - INTEGER(IntKi), PARAMETER :: SSqm59 = 2027 - INTEGER(IntKi), PARAMETER :: SSqm60 = 2028 - INTEGER(IntKi), PARAMETER :: SSqm61 = 2029 - INTEGER(IntKi), PARAMETER :: SSqm62 = 2030 - INTEGER(IntKi), PARAMETER :: SSqm63 = 2031 - INTEGER(IntKi), PARAMETER :: SSqm64 = 2032 - INTEGER(IntKi), PARAMETER :: SSqm65 = 2033 - INTEGER(IntKi), PARAMETER :: SSqm66 = 2034 - INTEGER(IntKi), PARAMETER :: SSqm67 = 2035 - INTEGER(IntKi), PARAMETER :: SSqm68 = 2036 - INTEGER(IntKi), PARAMETER :: SSqm69 = 2037 - INTEGER(IntKi), PARAMETER :: SSqm70 = 2038 - INTEGER(IntKi), PARAMETER :: SSqm71 = 2039 - INTEGER(IntKi), PARAMETER :: SSqm72 = 2040 - INTEGER(IntKi), PARAMETER :: SSqm73 = 2041 - INTEGER(IntKi), PARAMETER :: SSqm74 = 2042 - INTEGER(IntKi), PARAMETER :: SSqm75 = 2043 - INTEGER(IntKi), PARAMETER :: SSqm76 = 2044 - INTEGER(IntKi), PARAMETER :: SSqm77 = 2045 - INTEGER(IntKi), PARAMETER :: SSqm78 = 2046 - INTEGER(IntKi), PARAMETER :: SSqm79 = 2047 - INTEGER(IntKi), PARAMETER :: SSqm80 = 2048 - INTEGER(IntKi), PARAMETER :: SSqm81 = 2049 - INTEGER(IntKi), PARAMETER :: SSqm82 = 2050 - INTEGER(IntKi), PARAMETER :: SSqm83 = 2051 - INTEGER(IntKi), PARAMETER :: SSqm84 = 2052 - INTEGER(IntKi), PARAMETER :: SSqm85 = 2053 - INTEGER(IntKi), PARAMETER :: SSqm86 = 2054 - INTEGER(IntKi), PARAMETER :: SSqm87 = 2055 - INTEGER(IntKi), PARAMETER :: SSqm88 = 2056 - INTEGER(IntKi), PARAMETER :: SSqm89 = 2057 - INTEGER(IntKi), PARAMETER :: SSqm90 = 2058 - INTEGER(IntKi), PARAMETER :: SSqm91 = 2059 - INTEGER(IntKi), PARAMETER :: SSqm92 = 2060 - INTEGER(IntKi), PARAMETER :: SSqm93 = 2061 - INTEGER(IntKi), PARAMETER :: SSqm94 = 2062 - INTEGER(IntKi), PARAMETER :: SSqm95 = 2063 - INTEGER(IntKi), PARAMETER :: SSqm96 = 2064 - INTEGER(IntKi), PARAMETER :: SSqm97 = 2065 - INTEGER(IntKi), PARAMETER :: SSqm98 = 2066 - INTEGER(IntKi), PARAMETER :: SSqm99 = 2067 - INTEGER(IntKi), PARAMETER :: SSqmd01 = 2068 - INTEGER(IntKi), PARAMETER :: SSqmd02 = 2069 - INTEGER(IntKi), PARAMETER :: SSqmd03 = 2070 - INTEGER(IntKi), PARAMETER :: SSqmd04 = 2071 - INTEGER(IntKi), PARAMETER :: SSqmd05 = 2072 - INTEGER(IntKi), PARAMETER :: SSqmd06 = 2073 - INTEGER(IntKi), PARAMETER :: SSqmd07 = 2074 - INTEGER(IntKi), PARAMETER :: SSqmd08 = 2075 - INTEGER(IntKi), PARAMETER :: SSqmd09 = 2076 - INTEGER(IntKi), PARAMETER :: SSqmd10 = 2077 - INTEGER(IntKi), PARAMETER :: SSqmd11 = 2078 - INTEGER(IntKi), PARAMETER :: SSqmd12 = 2079 - INTEGER(IntKi), PARAMETER :: SSqmd13 = 2080 - INTEGER(IntKi), PARAMETER :: SSqmd14 = 2081 - INTEGER(IntKi), PARAMETER :: SSqmd15 = 2082 - INTEGER(IntKi), PARAMETER :: SSqmd16 = 2083 - INTEGER(IntKi), PARAMETER :: SSqmd17 = 2084 - INTEGER(IntKi), PARAMETER :: SSqmd18 = 2085 - INTEGER(IntKi), PARAMETER :: SSqmd19 = 2086 - INTEGER(IntKi), PARAMETER :: SSqmd20 = 2087 - INTEGER(IntKi), PARAMETER :: SSqmd21 = 2088 - INTEGER(IntKi), PARAMETER :: SSqmd22 = 2089 - INTEGER(IntKi), PARAMETER :: SSqmd23 = 2090 - INTEGER(IntKi), PARAMETER :: SSqmd24 = 2091 - INTEGER(IntKi), PARAMETER :: SSqmd25 = 2092 - INTEGER(IntKi), PARAMETER :: SSqmd26 = 2093 - INTEGER(IntKi), PARAMETER :: SSqmd27 = 2094 - INTEGER(IntKi), PARAMETER :: SSqmd28 = 2095 - INTEGER(IntKi), PARAMETER :: SSqmd29 = 2096 - INTEGER(IntKi), PARAMETER :: SSqmd30 = 2097 - INTEGER(IntKi), PARAMETER :: SSqmd31 = 2098 - INTEGER(IntKi), PARAMETER :: SSqmd32 = 2099 - INTEGER(IntKi), PARAMETER :: SSqmd33 = 2100 - INTEGER(IntKi), PARAMETER :: SSqmd34 = 2101 - INTEGER(IntKi), PARAMETER :: SSqmd35 = 2102 - INTEGER(IntKi), PARAMETER :: SSqmd36 = 2103 - INTEGER(IntKi), PARAMETER :: SSqmd37 = 2104 - INTEGER(IntKi), PARAMETER :: SSqmd38 = 2105 - INTEGER(IntKi), PARAMETER :: SSqmd39 = 2106 - INTEGER(IntKi), PARAMETER :: SSqmd40 = 2107 - INTEGER(IntKi), PARAMETER :: SSqmd41 = 2108 - INTEGER(IntKi), PARAMETER :: SSqmd42 = 2109 - INTEGER(IntKi), PARAMETER :: SSqmd43 = 2110 - INTEGER(IntKi), PARAMETER :: SSqmd44 = 2111 - INTEGER(IntKi), PARAMETER :: SSqmd45 = 2112 - INTEGER(IntKi), PARAMETER :: SSqmd46 = 2113 - INTEGER(IntKi), PARAMETER :: SSqmd47 = 2114 - INTEGER(IntKi), PARAMETER :: SSqmd48 = 2115 - INTEGER(IntKi), PARAMETER :: SSqmd49 = 2116 - INTEGER(IntKi), PARAMETER :: SSqmd50 = 2117 - INTEGER(IntKi), PARAMETER :: SSqmd51 = 2118 - INTEGER(IntKi), PARAMETER :: SSqmd52 = 2119 - INTEGER(IntKi), PARAMETER :: SSqmd53 = 2120 - INTEGER(IntKi), PARAMETER :: SSqmd54 = 2121 - INTEGER(IntKi), PARAMETER :: SSqmd55 = 2122 - INTEGER(IntKi), PARAMETER :: SSqmd56 = 2123 - INTEGER(IntKi), PARAMETER :: SSqmd57 = 2124 - INTEGER(IntKi), PARAMETER :: SSqmd58 = 2125 - INTEGER(IntKi), PARAMETER :: SSqmd59 = 2126 - INTEGER(IntKi), PARAMETER :: SSqmd60 = 2127 - INTEGER(IntKi), PARAMETER :: SSqmd61 = 2128 - INTEGER(IntKi), PARAMETER :: SSqmd62 = 2129 - INTEGER(IntKi), PARAMETER :: SSqmd63 = 2130 - INTEGER(IntKi), PARAMETER :: SSqmd64 = 2131 - INTEGER(IntKi), PARAMETER :: SSqmd65 = 2132 - INTEGER(IntKi), PARAMETER :: SSqmd66 = 2133 - INTEGER(IntKi), PARAMETER :: SSqmd67 = 2134 - INTEGER(IntKi), PARAMETER :: SSqmd68 = 2135 - INTEGER(IntKi), PARAMETER :: SSqmd69 = 2136 - INTEGER(IntKi), PARAMETER :: SSqmd70 = 2137 - INTEGER(IntKi), PARAMETER :: SSqmd71 = 2138 - INTEGER(IntKi), PARAMETER :: SSqmd72 = 2139 - INTEGER(IntKi), PARAMETER :: SSqmd73 = 2140 - INTEGER(IntKi), PARAMETER :: SSqmd74 = 2141 - INTEGER(IntKi), PARAMETER :: SSqmd75 = 2142 - INTEGER(IntKi), PARAMETER :: SSqmd76 = 2143 - INTEGER(IntKi), PARAMETER :: SSqmd77 = 2144 - INTEGER(IntKi), PARAMETER :: SSqmd78 = 2145 - INTEGER(IntKi), PARAMETER :: SSqmd79 = 2146 - INTEGER(IntKi), PARAMETER :: SSqmd80 = 2147 - INTEGER(IntKi), PARAMETER :: SSqmd81 = 2148 - INTEGER(IntKi), PARAMETER :: SSqmd82 = 2149 - INTEGER(IntKi), PARAMETER :: SSqmd83 = 2150 - INTEGER(IntKi), PARAMETER :: SSqmd84 = 2151 - INTEGER(IntKi), PARAMETER :: SSqmd85 = 2152 - INTEGER(IntKi), PARAMETER :: SSqmd86 = 2153 - INTEGER(IntKi), PARAMETER :: SSqmd87 = 2154 - INTEGER(IntKi), PARAMETER :: SSqmd88 = 2155 - INTEGER(IntKi), PARAMETER :: SSqmd89 = 2156 - INTEGER(IntKi), PARAMETER :: SSqmd90 = 2157 - INTEGER(IntKi), PARAMETER :: SSqmd91 = 2158 - INTEGER(IntKi), PARAMETER :: SSqmd92 = 2159 - INTEGER(IntKi), PARAMETER :: SSqmd93 = 2160 - INTEGER(IntKi), PARAMETER :: SSqmd94 = 2161 - INTEGER(IntKi), PARAMETER :: SSqmd95 = 2162 - INTEGER(IntKi), PARAMETER :: SSqmd96 = 2163 - INTEGER(IntKi), PARAMETER :: SSqmd97 = 2164 - INTEGER(IntKi), PARAMETER :: SSqmd98 = 2165 - INTEGER(IntKi), PARAMETER :: SSqmd99 = 2166 - INTEGER(IntKi), PARAMETER :: SSqmdd01 = 2167 - INTEGER(IntKi), PARAMETER :: SSqmdd02 = 2168 - INTEGER(IntKi), PARAMETER :: SSqmdd03 = 2169 - INTEGER(IntKi), PARAMETER :: SSqmdd04 = 2170 - INTEGER(IntKi), PARAMETER :: SSqmdd05 = 2171 - INTEGER(IntKi), PARAMETER :: SSqmdd06 = 2172 - INTEGER(IntKi), PARAMETER :: SSqmdd07 = 2173 - INTEGER(IntKi), PARAMETER :: SSqmdd08 = 2174 - INTEGER(IntKi), PARAMETER :: SSqmdd09 = 2175 - INTEGER(IntKi), PARAMETER :: SSqmdd10 = 2176 - INTEGER(IntKi), PARAMETER :: SSqmdd11 = 2177 - INTEGER(IntKi), PARAMETER :: SSqmdd12 = 2178 - INTEGER(IntKi), PARAMETER :: SSqmdd13 = 2179 - INTEGER(IntKi), PARAMETER :: SSqmdd14 = 2180 - INTEGER(IntKi), PARAMETER :: SSqmdd15 = 2181 - INTEGER(IntKi), PARAMETER :: SSqmdd16 = 2182 - INTEGER(IntKi), PARAMETER :: SSqmdd17 = 2183 - INTEGER(IntKi), PARAMETER :: SSqmdd18 = 2184 - INTEGER(IntKi), PARAMETER :: SSqmdd19 = 2185 - INTEGER(IntKi), PARAMETER :: SSqmdd20 = 2186 - INTEGER(IntKi), PARAMETER :: SSqmdd21 = 2187 - INTEGER(IntKi), PARAMETER :: SSqmdd22 = 2188 - INTEGER(IntKi), PARAMETER :: SSqmdd23 = 2189 - INTEGER(IntKi), PARAMETER :: SSqmdd24 = 2190 - INTEGER(IntKi), PARAMETER :: SSqmdd25 = 2191 - INTEGER(IntKi), PARAMETER :: SSqmdd26 = 2192 - INTEGER(IntKi), PARAMETER :: SSqmdd27 = 2193 - INTEGER(IntKi), PARAMETER :: SSqmdd28 = 2194 - INTEGER(IntKi), PARAMETER :: SSqmdd29 = 2195 - INTEGER(IntKi), PARAMETER :: SSqmdd30 = 2196 - INTEGER(IntKi), PARAMETER :: SSqmdd31 = 2197 - INTEGER(IntKi), PARAMETER :: SSqmdd32 = 2198 - INTEGER(IntKi), PARAMETER :: SSqmdd33 = 2199 - INTEGER(IntKi), PARAMETER :: SSqmdd34 = 2200 - INTEGER(IntKi), PARAMETER :: SSqmdd35 = 2201 - INTEGER(IntKi), PARAMETER :: SSqmdd36 = 2202 - INTEGER(IntKi), PARAMETER :: SSqmdd37 = 2203 - INTEGER(IntKi), PARAMETER :: SSqmdd38 = 2204 - INTEGER(IntKi), PARAMETER :: SSqmdd39 = 2205 - INTEGER(IntKi), PARAMETER :: SSqmdd40 = 2206 - INTEGER(IntKi), PARAMETER :: SSqmdd41 = 2207 - INTEGER(IntKi), PARAMETER :: SSqmdd42 = 2208 - INTEGER(IntKi), PARAMETER :: SSqmdd43 = 2209 - INTEGER(IntKi), PARAMETER :: SSqmdd44 = 2210 - INTEGER(IntKi), PARAMETER :: SSqmdd45 = 2211 - INTEGER(IntKi), PARAMETER :: SSqmdd46 = 2212 - INTEGER(IntKi), PARAMETER :: SSqmdd47 = 2213 - INTEGER(IntKi), PARAMETER :: SSqmdd48 = 2214 - INTEGER(IntKi), PARAMETER :: SSqmdd49 = 2215 - INTEGER(IntKi), PARAMETER :: SSqmdd50 = 2216 - INTEGER(IntKi), PARAMETER :: SSqmdd51 = 2217 - INTEGER(IntKi), PARAMETER :: SSqmdd52 = 2218 - INTEGER(IntKi), PARAMETER :: SSqmdd53 = 2219 - INTEGER(IntKi), PARAMETER :: SSqmdd54 = 2220 - INTEGER(IntKi), PARAMETER :: SSqmdd55 = 2221 - INTEGER(IntKi), PARAMETER :: SSqmdd56 = 2222 - INTEGER(IntKi), PARAMETER :: SSqmdd57 = 2223 - INTEGER(IntKi), PARAMETER :: SSqmdd58 = 2224 - INTEGER(IntKi), PARAMETER :: SSqmdd59 = 2225 - INTEGER(IntKi), PARAMETER :: SSqmdd60 = 2226 - INTEGER(IntKi), PARAMETER :: SSqmdd61 = 2227 - INTEGER(IntKi), PARAMETER :: SSqmdd62 = 2228 - INTEGER(IntKi), PARAMETER :: SSqmdd63 = 2229 - INTEGER(IntKi), PARAMETER :: SSqmdd64 = 2230 - INTEGER(IntKi), PARAMETER :: SSqmdd65 = 2231 - INTEGER(IntKi), PARAMETER :: SSqmdd66 = 2232 - INTEGER(IntKi), PARAMETER :: SSqmdd67 = 2233 - INTEGER(IntKi), PARAMETER :: SSqmdd68 = 2234 - INTEGER(IntKi), PARAMETER :: SSqmdd69 = 2235 - INTEGER(IntKi), PARAMETER :: SSqmdd70 = 2236 - INTEGER(IntKi), PARAMETER :: SSqmdd71 = 2237 - INTEGER(IntKi), PARAMETER :: SSqmdd72 = 2238 - INTEGER(IntKi), PARAMETER :: SSqmdd73 = 2239 - INTEGER(IntKi), PARAMETER :: SSqmdd74 = 2240 - INTEGER(IntKi), PARAMETER :: SSqmdd75 = 2241 - INTEGER(IntKi), PARAMETER :: SSqmdd76 = 2242 - INTEGER(IntKi), PARAMETER :: SSqmdd77 = 2243 - INTEGER(IntKi), PARAMETER :: SSqmdd78 = 2244 - INTEGER(IntKi), PARAMETER :: SSqmdd79 = 2245 - INTEGER(IntKi), PARAMETER :: SSqmdd80 = 2246 - INTEGER(IntKi), PARAMETER :: SSqmdd81 = 2247 - INTEGER(IntKi), PARAMETER :: SSqmdd82 = 2248 - INTEGER(IntKi), PARAMETER :: SSqmdd83 = 2249 - INTEGER(IntKi), PARAMETER :: SSqmdd84 = 2250 - INTEGER(IntKi), PARAMETER :: SSqmdd85 = 2251 - INTEGER(IntKi), PARAMETER :: SSqmdd86 = 2252 - INTEGER(IntKi), PARAMETER :: SSqmdd87 = 2253 - INTEGER(IntKi), PARAMETER :: SSqmdd88 = 2254 - INTEGER(IntKi), PARAMETER :: SSqmdd89 = 2255 - INTEGER(IntKi), PARAMETER :: SSqmdd90 = 2256 - INTEGER(IntKi), PARAMETER :: SSqmdd91 = 2257 - INTEGER(IntKi), PARAMETER :: SSqmdd92 = 2258 - INTEGER(IntKi), PARAMETER :: SSqmdd93 = 2259 - INTEGER(IntKi), PARAMETER :: SSqmdd94 = 2260 - INTEGER(IntKi), PARAMETER :: SSqmdd95 = 2261 - INTEGER(IntKi), PARAMETER :: SSqmdd96 = 2262 - INTEGER(IntKi), PARAMETER :: SSqmdd97 = 2263 - INTEGER(IntKi), PARAMETER :: SSqmdd98 = 2264 - INTEGER(IntKi), PARAMETER :: SSqmdd99 = 2265 - - - ! The maximum number of output channels which can be output by the code. - !INTEGER(IntKi), PARAMETER :: MaxOutPts = 2265 - -!End of code generated by Matlab script - - INTEGER, PARAMETER :: MNfmKe(6,9,9) = reshape((/ M1N1FKxe,M1N1FKye,M1N1FKze,M1N1MKxe,M1N1MKye,M1N1MKze, & - M1N2FKxe,M1N2FKye,M1N2FKze,M1N2MKxe,M1N2MKye,M1N2MKze, & - M1N3FKxe,M1N3FKye,M1N3FKze,M1N3MKxe,M1N3MKye,M1N3MKze, & - M1N4FKxe,M1N4FKye,M1N4FKze,M1N4MKxe,M1N4MKye,M1N4MKze, & - M1N5FKxe,M1N5FKye,M1N5FKze,M1N5MKxe,M1N5MKye,M1N5MKze, & - M1N6FKxe,M1N6FKye,M1N6FKze,M1N6MKxe,M1N6MKye,M1N6MKze, & - M1N7FKxe,M1N7FKye,M1N7FKze,M1N7MKxe,M1N7MKye,M1N7MKze, & - M1N8FKxe,M1N8FKye,M1N8FKze,M1N8MKxe,M1N8MKye,M1N8MKze, & - M1N9FKxe,M1N9FKye,M1N9FKze,M1N9MKxe,M1N9MKye,M1N9MKze, & - M2N1FKxe,M2N1FKye,M2N1FKze,M2N1MKxe,M2N1MKye,M2N1MKze, & - M2N2FKxe,M2N2FKye,M2N2FKze,M2N2MKxe,M2N2MKye,M2N2MKze, & - M2N3FKxe,M2N3FKye,M2N3FKze,M2N3MKxe,M2N3MKye,M2N3MKze, & - M2N4FKxe,M2N4FKye,M2N4FKze,M2N4MKxe,M2N4MKye,M2N4MKze, & - M2N5FKxe,M2N5FKye,M2N5FKze,M2N5MKxe,M2N5MKye,M2N5MKze, & - M2N6FKxe,M2N6FKye,M2N6FKze,M2N6MKxe,M2N6MKye,M2N6MKze, & - M2N7FKxe,M2N7FKye,M2N7FKze,M2N7MKxe,M2N7MKye,M2N7MKze, & - M2N8FKxe,M2N8FKye,M2N8FKze,M2N8MKxe,M2N8MKye,M2N8MKze, & - M2N9FKxe,M2N9FKye,M2N9FKze,M2N9MKxe,M2N9MKye,M2N9MKze, & - M3N1FKxe,M3N1FKye,M3N1FKze,M3N1MKxe,M3N1MKye,M3N1MKze, & - M3N2FKxe,M3N2FKye,M3N2FKze,M3N2MKxe,M3N2MKye,M3N2MKze, & - M3N3FKxe,M3N3FKye,M3N3FKze,M3N3MKxe,M3N3MKye,M3N3MKze, & - M3N4FKxe,M3N4FKye,M3N4FKze,M3N4MKxe,M3N4MKye,M3N4MKze, & - M3N5FKxe,M3N5FKye,M3N5FKze,M3N5MKxe,M3N5MKye,M3N5MKze, & - M3N6FKxe,M3N6FKye,M3N6FKze,M3N6MKxe,M3N6MKye,M3N6MKze, & - M3N7FKxe,M3N7FKye,M3N7FKze,M3N7MKxe,M3N7MKye,M3N7MKze, & - M3N8FKxe,M3N8FKye,M3N8FKze,M3N8MKxe,M3N8MKye,M3N8MKze, & - M3N9FKxe,M3N9FKye,M3N9FKze,M3N9MKxe,M3N9MKye,M3N9MKze, & - M4N1FKxe,M4N1FKye,M4N1FKze,M4N1MKxe,M4N1MKye,M4N1MKze, & - M4N2FKxe,M4N2FKye,M4N2FKze,M4N2MKxe,M4N2MKye,M4N2MKze, & - M4N3FKxe,M4N3FKye,M4N3FKze,M4N3MKxe,M4N3MKye,M4N3MKze, & - M4N4FKxe,M4N4FKye,M4N4FKze,M4N4MKxe,M4N4MKye,M4N4MKze, & - M4N5FKxe,M4N5FKye,M4N5FKze,M4N5MKxe,M4N5MKye,M4N5MKze, & - M4N6FKxe,M4N6FKye,M4N6FKze,M4N6MKxe,M4N6MKye,M4N6MKze, & - M4N7FKxe,M4N7FKye,M4N7FKze,M4N7MKxe,M4N7MKye,M4N7MKze, & - M4N8FKxe,M4N8FKye,M4N8FKze,M4N8MKxe,M4N8MKye,M4N8MKze, & - M4N9FKxe,M4N9FKye,M4N9FKze,M4N9MKxe,M4N9MKye,M4N9MKze, & - M5N1FKxe,M5N1FKye,M5N1FKze,M5N1MKxe,M5N1MKye,M5N1MKze, & - M5N2FKxe,M5N2FKye,M5N2FKze,M5N2MKxe,M5N2MKye,M5N2MKze, & - M5N3FKxe,M5N3FKye,M5N3FKze,M5N3MKxe,M5N3MKye,M5N3MKze, & - M5N4FKxe,M5N4FKye,M5N4FKze,M5N4MKxe,M5N4MKye,M5N4MKze, & - M5N5FKxe,M5N5FKye,M5N5FKze,M5N5MKxe,M5N5MKye,M5N5MKze, & - M5N6FKxe,M5N6FKye,M5N6FKze,M5N6MKxe,M5N6MKye,M5N6MKze, & - M5N7FKxe,M5N7FKye,M5N7FKze,M5N7MKxe,M5N7MKye,M5N7MKze, & - M5N8FKxe,M5N8FKye,M5N8FKze,M5N8MKxe,M5N8MKye,M5N8MKze, & - M5N9FKxe,M5N9FKye,M5N9FKze,M5N9MKxe,M5N9MKye,M5N9MKze, & - M6N1FKxe,M6N1FKye,M6N1FKze,M6N1MKxe,M6N1MKye,M6N1MKze, & - M6N2FKxe,M6N2FKye,M6N2FKze,M6N2MKxe,M6N2MKye,M6N2MKze, & - M6N3FKxe,M6N3FKye,M6N3FKze,M6N3MKxe,M6N3MKye,M6N3MKze, & - M6N4FKxe,M6N4FKye,M6N4FKze,M6N4MKxe,M6N4MKye,M6N4MKze, & - M6N5FKxe,M6N5FKye,M6N5FKze,M6N5MKxe,M6N5MKye,M6N5MKze, & - M6N6FKxe,M6N6FKye,M6N6FKze,M6N6MKxe,M6N6MKye,M6N6MKze, & - M6N7FKxe,M6N7FKye,M6N7FKze,M6N7MKxe,M6N7MKye,M6N7MKze, & - M6N8FKxe,M6N8FKye,M6N8FKze,M6N8MKxe,M6N8MKye,M6N8MKze, & - M6N9FKxe,M6N9FKye,M6N9FKze,M6N9MKxe,M6N9MKye,M6N9MKze, & - M7N1FKxe,M7N1FKye,M7N1FKze,M7N1MKxe,M7N1MKye,M7N1MKze, & - M7N2FKxe,M7N2FKye,M7N2FKze,M7N2MKxe,M7N2MKye,M7N2MKze, & - M7N3FKxe,M7N3FKye,M7N3FKze,M7N3MKxe,M7N3MKye,M7N3MKze, & - M7N4FKxe,M7N4FKye,M7N4FKze,M7N4MKxe,M7N4MKye,M7N4MKze, & - M7N5FKxe,M7N5FKye,M7N5FKze,M7N5MKxe,M7N5MKye,M7N5MKze, & - M7N6FKxe,M7N6FKye,M7N6FKze,M7N6MKxe,M7N6MKye,M7N6MKze, & - M7N7FKxe,M7N7FKye,M7N7FKze,M7N7MKxe,M7N7MKye,M7N7MKze, & - M7N8FKxe,M7N8FKye,M7N8FKze,M7N8MKxe,M7N8MKye,M7N8MKze, & - M7N9FKxe,M7N9FKye,M7N9FKze,M7N9MKxe,M7N9MKye,M7N9MKze, & - M8N1FKxe,M8N1FKye,M8N1FKze,M8N1MKxe,M8N1MKye,M8N1MKze, & - M8N2FKxe,M8N2FKye,M8N2FKze,M8N2MKxe,M8N2MKye,M8N2MKze, & - M8N3FKxe,M8N3FKye,M8N3FKze,M8N3MKxe,M8N3MKye,M8N3MKze, & - M8N4FKxe,M8N4FKye,M8N4FKze,M8N4MKxe,M8N4MKye,M8N4MKze, & - M8N5FKxe,M8N5FKye,M8N5FKze,M8N5MKxe,M8N5MKye,M8N5MKze, & - M8N6FKxe,M8N6FKye,M8N6FKze,M8N6MKxe,M8N6MKye,M8N6MKze, & - M8N7FKxe,M8N7FKye,M8N7FKze,M8N7MKxe,M8N7MKye,M8N7MKze, & - M8N8FKxe,M8N8FKye,M8N8FKze,M8N8MKxe,M8N8MKye,M8N8MKze, & - M8N9FKxe,M8N9FKye,M8N9FKze,M8N9MKxe,M8N9MKye,M8N9MKze, & - M9N1FKxe,M9N1FKye,M9N1FKze,M9N1MKxe,M9N1MKye,M9N1MKze, & - M9N2FKxe,M9N2FKye,M9N2FKze,M9N2MKxe,M9N2MKye,M9N2MKze, & - M9N3FKxe,M9N3FKye,M9N3FKze,M9N3MKxe,M9N3MKye,M9N3MKze, & - M9N4FKxe,M9N4FKye,M9N4FKze,M9N4MKxe,M9N4MKye,M9N4MKze, & - M9N5FKxe,M9N5FKye,M9N5FKze,M9N5MKxe,M9N5MKye,M9N5MKze, & - M9N6FKxe,M9N6FKye,M9N6FKze,M9N6MKxe,M9N6MKye,M9N6MKze, & - M9N7FKxe,M9N7FKye,M9N7FKze,M9N7MKxe,M9N7MKye,M9N7MKze, & - M9N8FKxe,M9N8FKye,M9N8FKze,M9N8MKxe,M9N8MKye,M9N8MKze, & - M9N9FKxe,M9N9FKye,M9N9FKze,M9N9MKxe,M9N9MKye,M9N9MKze /),(/6,9,9/)) - - - - INTEGER, PARAMETER :: MNfmMe(6,9,9) = reshape((/ M1N1FMxe,M1N1FMye,M1N1FMze,M1N1MMxe,M1N1MMye,M1N1MMze, & - M1N2FMxe,M1N2FMye,M1N2FMze,M1N2MMxe,M1N2MMye,M1N2MMze, & - M1N3FMxe,M1N3FMye,M1N3FMze,M1N3MMxe,M1N3MMye,M1N3MMze, & - M1N4FMxe,M1N4FMye,M1N4FMze,M1N4MMxe,M1N4MMye,M1N4MMze, & - M1N5FMxe,M1N5FMye,M1N5FMze,M1N5MMxe,M1N5MMye,M1N5MMze, & - M1N6FMxe,M1N6FMye,M1N6FMze,M1N6MMxe,M1N6MMye,M1N6MMze, & - M1N7FMxe,M1N7FMye,M1N7FMze,M1N7MMxe,M1N7MMye,M1N7MMze, & - M1N8FMxe,M1N8FMye,M1N8FMze,M1N8MMxe,M1N8MMye,M1N8MMze, & - M1N9FMxe,M1N9FMye,M1N9FMze,M1N9MMxe,M1N9MMye,M1N9MMze, & - M2N1FMxe,M2N1FMye,M2N1FMze,M2N1MMxe,M2N1MMye,M2N1MMze, & - M2N2FMxe,M2N2FMye,M2N2FMze,M2N2MMxe,M2N2MMye,M2N2MMze, & - M2N3FMxe,M2N3FMye,M2N3FMze,M2N3MMxe,M2N3MMye,M2N3MMze, & - M2N4FMxe,M2N4FMye,M2N4FMze,M2N4MMxe,M2N4MMye,M2N4MMze, & - M2N5FMxe,M2N5FMye,M2N5FMze,M2N5MMxe,M2N5MMye,M2N5MMze, & - M2N6FMxe,M2N6FMye,M2N6FMze,M2N6MMxe,M2N6MMye,M2N6MMze, & - M2N7FMxe,M2N7FMye,M2N7FMze,M2N7MMxe,M2N7MMye,M2N7MMze, & - M2N8FMxe,M2N8FMye,M2N8FMze,M2N8MMxe,M2N8MMye,M2N8MMze, & - M2N9FMxe,M2N9FMye,M2N9FMze,M2N9MMxe,M2N9MMye,M2N9MMze, & - M3N1FMxe,M3N1FMye,M3N1FMze,M3N1MMxe,M3N1MMye,M3N1MMze, & - M3N2FMxe,M3N2FMye,M3N2FMze,M3N2MMxe,M3N2MMye,M3N2MMze, & - M3N3FMxe,M3N3FMye,M3N3FMze,M3N3MMxe,M3N3MMye,M3N3MMze, & - M3N4FMxe,M3N4FMye,M3N4FMze,M3N4MMxe,M3N4MMye,M3N4MMze, & - M3N5FMxe,M3N5FMye,M3N5FMze,M3N5MMxe,M3N5MMye,M3N5MMze, & - M3N6FMxe,M3N6FMye,M3N6FMze,M3N6MMxe,M3N6MMye,M3N6MMze, & - M3N7FMxe,M3N7FMye,M3N7FMze,M3N7MMxe,M3N7MMye,M3N7MMze, & - M3N8FMxe,M3N8FMye,M3N8FMze,M3N8MMxe,M3N8MMye,M3N8MMze, & - M3N9FMxe,M3N9FMye,M3N9FMze,M3N9MMxe,M3N9MMye,M3N9MMze, & - M4N1FMxe,M4N1FMye,M4N1FMze,M4N1MMxe,M4N1MMye,M4N1MMze, & - M4N2FMxe,M4N2FMye,M4N2FMze,M4N2MMxe,M4N2MMye,M4N2MMze, & - M4N3FMxe,M4N3FMye,M4N3FMze,M4N3MMxe,M4N3MMye,M4N3MMze, & - M4N4FMxe,M4N4FMye,M4N4FMze,M4N4MMxe,M4N4MMye,M4N4MMze, & - M4N5FMxe,M4N5FMye,M4N5FMze,M4N5MMxe,M4N5MMye,M4N5MMze, & - M4N6FMxe,M4N6FMye,M4N6FMze,M4N6MMxe,M4N6MMye,M4N6MMze, & - M4N7FMxe,M4N7FMye,M4N7FMze,M4N7MMxe,M4N7MMye,M4N7MMze, & - M4N8FMxe,M4N8FMye,M4N8FMze,M4N8MMxe,M4N8MMye,M4N8MMze, & - M4N9FMxe,M4N9FMye,M4N9FMze,M4N9MMxe,M4N9MMye,M4N9MMze, & - M5N1FMxe,M5N1FMye,M5N1FMze,M5N1MMxe,M5N1MMye,M5N1MMze, & - M5N2FMxe,M5N2FMye,M5N2FMze,M5N2MMxe,M5N2MMye,M5N2MMze, & - M5N3FMxe,M5N3FMye,M5N3FMze,M5N3MMxe,M5N3MMye,M5N3MMze, & - M5N4FMxe,M5N4FMye,M5N4FMze,M5N4MMxe,M5N4MMye,M5N4MMze, & - M5N5FMxe,M5N5FMye,M5N5FMze,M5N5MMxe,M5N5MMye,M5N5MMze, & - M5N6FMxe,M5N6FMye,M5N6FMze,M5N6MMxe,M5N6MMye,M5N6MMze, & - M5N7FMxe,M5N7FMye,M5N7FMze,M5N7MMxe,M5N7MMye,M5N7MMze, & - M5N8FMxe,M5N8FMye,M5N8FMze,M5N8MMxe,M5N8MMye,M5N8MMze, & - M5N9FMxe,M5N9FMye,M5N9FMze,M5N9MMxe,M5N9MMye,M5N9MMze, & - M6N1FMxe,M6N1FMye,M6N1FMze,M6N1MMxe,M6N1MMye,M6N1MMze, & - M6N2FMxe,M6N2FMye,M6N2FMze,M6N2MMxe,M6N2MMye,M6N2MMze, & - M6N3FMxe,M6N3FMye,M6N3FMze,M6N3MMxe,M6N3MMye,M6N3MMze, & - M6N4FMxe,M6N4FMye,M6N4FMze,M6N4MMxe,M6N4MMye,M6N4MMze, & - M6N5FMxe,M6N5FMye,M6N5FMze,M6N5MMxe,M6N5MMye,M6N5MMze, & - M6N6FMxe,M6N6FMye,M6N6FMze,M6N6MMxe,M6N6MMye,M6N6MMze, & - M6N7FMxe,M6N7FMye,M6N7FMze,M6N7MMxe,M6N7MMye,M6N7MMze, & - M6N8FMxe,M6N8FMye,M6N8FMze,M6N8MMxe,M6N8MMye,M6N8MMze, & - M6N9FMxe,M6N9FMye,M6N9FMze,M6N9MMxe,M6N9MMye,M6N9MMze, & - M7N1FMxe,M7N1FMye,M7N1FMze,M7N1MMxe,M7N1MMye,M7N1MMze, & - M7N2FMxe,M7N2FMye,M7N2FMze,M7N2MMxe,M7N2MMye,M7N2MMze, & - M7N3FMxe,M7N3FMye,M7N3FMze,M7N3MMxe,M7N3MMye,M7N3MMze, & - M7N4FMxe,M7N4FMye,M7N4FMze,M7N4MMxe,M7N4MMye,M7N4MMze, & - M7N5FMxe,M7N5FMye,M7N5FMze,M7N5MMxe,M7N5MMye,M7N5MMze, & - M7N6FMxe,M7N6FMye,M7N6FMze,M7N6MMxe,M7N6MMye,M7N6MMze, & - M7N7FMxe,M7N7FMye,M7N7FMze,M7N7MMxe,M7N7MMye,M7N7MMze, & - M7N8FMxe,M7N8FMye,M7N8FMze,M7N8MMxe,M7N8MMye,M7N8MMze, & - M7N9FMxe,M7N9FMye,M7N9FMze,M7N9MMxe,M7N9MMye,M7N9MMze, & - M8N1FMxe,M8N1FMye,M8N1FMze,M8N1MMxe,M8N1MMye,M8N1MMze, & - M8N2FMxe,M8N2FMye,M8N2FMze,M8N2MMxe,M8N2MMye,M8N2MMze, & - M8N3FMxe,M8N3FMye,M8N3FMze,M8N3MMxe,M8N3MMye,M8N3MMze, & - M8N4FMxe,M8N4FMye,M8N4FMze,M8N4MMxe,M8N4MMye,M8N4MMze, & - M8N5FMxe,M8N5FMye,M8N5FMze,M8N5MMxe,M8N5MMye,M8N5MMze, & - M8N6FMxe,M8N6FMye,M8N6FMze,M8N6MMxe,M8N6MMye,M8N6MMze, & - M8N7FMxe,M8N7FMye,M8N7FMze,M8N7MMxe,M8N7MMye,M8N7MMze, & - M8N8FMxe,M8N8FMye,M8N8FMze,M8N8MMxe,M8N8MMye,M8N8MMze, & - M8N9FMxe,M8N9FMye,M8N9FMze,M8N9MMxe,M8N9MMye,M8N9MMze, & - M9N1FMxe,M9N1FMye,M9N1FMze,M9N1MMxe,M9N1MMye,M9N1MMze, & - M9N2FMxe,M9N2FMye,M9N2FMze,M9N2MMxe,M9N2MMye,M9N2MMze, & - M9N3FMxe,M9N3FMye,M9N3FMze,M9N3MMxe,M9N3MMye,M9N3MMze, & - M9N4FMxe,M9N4FMye,M9N4FMze,M9N4MMxe,M9N4MMye,M9N4MMze, & - M9N5FMxe,M9N5FMye,M9N5FMze,M9N5MMxe,M9N5MMye,M9N5MMze, & - M9N6FMxe,M9N6FMye,M9N6FMze,M9N6MMxe,M9N6MMye,M9N6MMze, & - M9N7FMxe,M9N7FMye,M9N7FMze,M9N7MMxe,M9N7MMye,M9N7MMze, & - M9N8FMxe,M9N8FMye,M9N8FMze,M9N8MMxe,M9N8MMye,M9N8MMze, & - M9N9FMxe,M9N9FMye,M9N9FMze,M9N9MMxe,M9N9MMye,M9N9MMze /),(/6,9,9/)) - - INTEGER, PARAMETER :: MNTDss(3,9,9) = reshape((/M1N1TDxss,M1N1TDyss,M1N1TDzss, & - M1N2TDxss,M1N2TDyss,M1N2TDzss, & - M1N3TDxss,M1N3TDyss,M1N3TDzss, & - M1N4TDxss,M1N4TDyss,M1N4TDzss, & - M1N5TDxss,M1N5TDyss,M1N5TDzss, & - M1N6TDxss,M1N6TDyss,M1N6TDzss, & - M1N7TDxss,M1N7TDyss,M1N7TDzss, & - M1N8TDxss,M1N8TDyss,M1N8TDzss, & - M1N9TDxss,M1N9TDyss,M1N9TDzss, & - M2N1TDxss,M2N1TDyss,M2N1TDzss, & - M2N2TDxss,M2N2TDyss,M2N2TDzss, & - M2N3TDxss,M2N3TDyss,M2N3TDzss, & - M2N4TDxss,M2N4TDyss,M2N4TDzss, & - M2N5TDxss,M2N5TDyss,M2N5TDzss, & - M2N6TDxss,M2N6TDyss,M2N6TDzss, & - M2N7TDxss,M2N7TDyss,M2N7TDzss, & - M2N8TDxss,M2N8TDyss,M2N8TDzss, & - M2N9TDxss,M2N9TDyss,M2N9TDzss, & - M3N1TDxss,M3N1TDyss,M3N1TDzss, & - M3N2TDxss,M3N2TDyss,M3N2TDzss, & - M3N3TDxss,M3N3TDyss,M3N3TDzss, & - M3N4TDxss,M3N4TDyss,M3N4TDzss, & - M3N5TDxss,M3N5TDyss,M3N5TDzss, & - M3N6TDxss,M3N6TDyss,M3N6TDzss, & - M3N7TDxss,M3N7TDyss,M3N7TDzss, & - M3N8TDxss,M3N8TDyss,M3N8TDzss, & - M3N9TDxss,M3N9TDyss,M3N9TDzss, & - M4N1TDxss,M4N1TDyss,M4N1TDzss, & - M4N2TDxss,M4N2TDyss,M4N2TDzss, & - M4N3TDxss,M4N3TDyss,M4N3TDzss, & - M4N4TDxss,M4N4TDyss,M4N4TDzss, & - M4N5TDxss,M4N5TDyss,M4N5TDzss, & - M4N6TDxss,M4N6TDyss,M4N6TDzss, & - M4N7TDxss,M4N7TDyss,M4N7TDzss, & - M4N8TDxss,M4N8TDyss,M4N8TDzss, & - M4N9TDxss,M4N9TDyss,M4N9TDzss, & - M5N1TDxss,M5N1TDyss,M5N1TDzss, & - M5N2TDxss,M5N2TDyss,M5N2TDzss, & - M5N3TDxss,M5N3TDyss,M5N3TDzss, & - M5N4TDxss,M5N4TDyss,M5N4TDzss, & - M5N5TDxss,M5N5TDyss,M5N5TDzss, & - M5N6TDxss,M5N6TDyss,M5N6TDzss, & - M5N7TDxss,M5N7TDyss,M5N7TDzss, & - M5N8TDxss,M5N8TDyss,M5N8TDzss, & - M5N9TDxss,M5N9TDyss,M5N9TDzss, & - M6N1TDxss,M6N1TDyss,M6N1TDzss, & - M6N2TDxss,M6N2TDyss,M6N2TDzss, & - M6N3TDxss,M6N3TDyss,M6N3TDzss, & - M6N4TDxss,M6N4TDyss,M6N4TDzss, & - M6N5TDxss,M6N5TDyss,M6N5TDzss, & - M6N6TDxss,M6N6TDyss,M6N6TDzss, & - M6N7TDxss,M6N7TDyss,M6N7TDzss, & - M6N8TDxss,M6N8TDyss,M6N8TDzss, & - M6N9TDxss,M6N9TDyss,M6N9TDzss, & - M7N1TDxss,M7N1TDyss,M7N1TDzss, & - M7N2TDxss,M7N2TDyss,M7N2TDzss, & - M7N3TDxss,M7N3TDyss,M7N3TDzss, & - M7N4TDxss,M7N4TDyss,M7N4TDzss, & - M7N5TDxss,M7N5TDyss,M7N5TDzss, & - M7N6TDxss,M7N6TDyss,M7N6TDzss, & - M7N7TDxss,M7N7TDyss,M7N7TDzss, & - M7N8TDxss,M7N8TDyss,M7N8TDzss, & - M7N9TDxss,M7N9TDyss,M7N9TDzss, & - M8N1TDxss,M8N1TDyss,M8N1TDzss, & - M8N2TDxss,M8N2TDyss,M8N2TDzss, & - M8N3TDxss,M8N3TDyss,M8N3TDzss, & - M8N4TDxss,M8N4TDyss,M8N4TDzss, & - M8N5TDxss,M8N5TDyss,M8N5TDzss, & - M8N6TDxss,M8N6TDyss,M8N6TDzss, & - M8N7TDxss,M8N7TDyss,M8N7TDzss, & - M8N8TDxss,M8N8TDyss,M8N8TDzss, & - M8N9TDxss,M8N9TDyss,M8N9TDzss, & - M9N1TDxss,M9N1TDyss,M9N1TDzss, & - M9N2TDxss,M9N2TDyss,M9N2TDzss, & - M9N3TDxss,M9N3TDyss,M9N3TDzss, & - M9N4TDxss,M9N4TDyss,M9N4TDzss, & - M9N5TDxss,M9N5TDyss,M9N5TDzss, & - M9N6TDxss,M9N6TDyss,M9N6TDzss, & - M9N7TDxss,M9N7TDyss,M9N7TDzss, & - M9N8TDxss,M9N8TDyss,M9N8TDzss, & - M9N9TDxss,M9N9TDyss,M9N9TDzss/), (/3,9,9/)) - -INTEGER, PARAMETER :: MNRDe (3,9,9) = reshape((/M1N1RDxe,M1N1RDye,M1N1RDze, & - M1N2RDxe,M1N2RDye,M1N2RDze, & - M1N3RDxe,M1N3RDye,M1N3RDze, & - M1N4RDxe,M1N4RDye,M1N4RDze, & - M1N5RDxe,M1N5RDye,M1N5RDze, & - M1N6RDxe,M1N6RDye,M1N6RDze, & - M1N7RDxe,M1N7RDye,M1N7RDze, & - M1N8RDxe,M1N8RDye,M1N8RDze, & - M1N9RDxe,M1N9RDye,M1N9RDze, & - M2N1RDxe,M2N1RDye,M2N1RDze, & - M2N2RDxe,M2N2RDye,M2N2RDze, & - M2N3RDxe,M2N3RDye,M2N3RDze, & - M2N4RDxe,M2N4RDye,M2N4RDze, & - M2N5RDxe,M2N5RDye,M2N5RDze, & - M2N6RDxe,M2N6RDye,M2N6RDze, & - M2N7RDxe,M2N7RDye,M2N7RDze, & - M2N8RDxe,M2N8RDye,M2N8RDze, & - M2N9RDxe,M2N9RDye,M2N9RDze, & - M3N1RDxe,M3N1RDye,M3N1RDze, & - M3N2RDxe,M3N2RDye,M3N2RDze, & - M3N3RDxe,M3N3RDye,M3N3RDze, & - M3N4RDxe,M3N4RDye,M3N4RDze, & - M3N5RDxe,M3N5RDye,M3N5RDze, & - M3N6RDxe,M3N6RDye,M3N6RDze, & - M3N7RDxe,M3N7RDye,M3N7RDze, & - M3N8RDxe,M3N8RDye,M3N8RDze, & - M3N9RDxe,M3N9RDye,M3N9RDze, & - M4N1RDxe,M4N1RDye,M4N1RDze, & - M4N2RDxe,M4N2RDye,M4N2RDze, & - M4N3RDxe,M4N3RDye,M4N3RDze, & - M4N4RDxe,M4N4RDye,M4N4RDze, & - M4N5RDxe,M4N5RDye,M4N5RDze, & - M4N6RDxe,M4N6RDye,M4N6RDze, & - M4N7RDxe,M4N7RDye,M4N7RDze, & - M4N8RDxe,M4N8RDye,M4N8RDze, & - M4N9RDxe,M4N9RDye,M4N9RDze, & - M5N1RDxe,M5N1RDye,M5N1RDze, & - M5N2RDxe,M5N2RDye,M5N2RDze, & - M5N3RDxe,M5N3RDye,M5N3RDze, & - M5N4RDxe,M5N4RDye,M5N4RDze, & - M5N5RDxe,M5N5RDye,M5N5RDze, & - M5N6RDxe,M5N6RDye,M5N6RDze, & - M5N7RDxe,M5N7RDye,M5N7RDze, & - M5N8RDxe,M5N8RDye,M5N8RDze, & - M5N9RDxe,M5N9RDye,M5N9RDze, & - M6N1RDxe,M6N1RDye,M6N1RDze, & - M6N2RDxe,M6N2RDye,M6N2RDze, & - M6N3RDxe,M6N3RDye,M6N3RDze, & - M6N4RDxe,M6N4RDye,M6N4RDze, & - M6N5RDxe,M6N5RDye,M6N5RDze, & - M6N6RDxe,M6N6RDye,M6N6RDze, & - M6N7RDxe,M6N7RDye,M6N7RDze, & - M6N8RDxe,M6N8RDye,M6N8RDze, & - M6N9RDxe,M6N9RDye,M6N9RDze, & - M7N1RDxe,M7N1RDye,M7N1RDze, & - M7N2RDxe,M7N2RDye,M7N2RDze, & - M7N3RDxe,M7N3RDye,M7N3RDze, & - M7N4RDxe,M7N4RDye,M7N4RDze, & - M7N5RDxe,M7N5RDye,M7N5RDze, & - M7N6RDxe,M7N6RDye,M7N6RDze, & - M7N7RDxe,M7N7RDye,M7N7RDze, & - M7N8RDxe,M7N8RDye,M7N8RDze, & - M7N9RDxe,M7N9RDye,M7N9RDze, & - M8N1RDxe,M8N1RDye,M8N1RDze, & - M8N2RDxe,M8N2RDye,M8N2RDze, & - M8N3RDxe,M8N3RDye,M8N3RDze, & - M8N4RDxe,M8N4RDye,M8N4RDze, & - M8N5RDxe,M8N5RDye,M8N5RDze, & - M8N6RDxe,M8N6RDye,M8N6RDze, & - M8N7RDxe,M8N7RDye,M8N7RDze, & - M8N8RDxe,M8N8RDye,M8N8RDze, & - M8N9RDxe,M8N9RDye,M8N9RDze, & - M9N1RDxe,M9N1RDye,M9N1RDze, & - M9N2RDxe,M9N2RDye,M9N2RDze, & - M9N3RDxe,M9N3RDye,M9N3RDze, & - M9N4RDxe,M9N4RDye,M9N4RDze, & - M9N5RDxe,M9N5RDye,M9N5RDze, & - M9N6RDxe,M9N6RDye,M9N6RDze, & - M9N7RDxe,M9N7RDye,M9N7RDze, & - M9N8RDxe,M9N8RDye,M9N8RDze, & - M9N9RDxe,M9N9RDye,M9N9RDze/), (/3,9,9/)) - - - INTEGER, PARAMETER :: MNTRAe(6,9,9) = reshape( (/M1N1TAxe,M1N1TAye,M1N1TAze,M1N1RAxe,M1N1RAye,M1N1RAze, & - M1N2TAxe,M1N2TAye,M1N2TAze,M1N2RAxe,M1N2RAye,M1N2RAze, & - M1N3TAxe,M1N3TAye,M1N3TAze,M1N3RAxe,M1N3RAye,M1N3RAze, & - M1N4TAxe,M1N4TAye,M1N4TAze,M1N4RAxe,M1N4RAye,M1N4RAze, & - M1N5TAxe,M1N5TAye,M1N5TAze,M1N5RAxe,M1N5RAye,M1N5RAze, & - M1N6TAxe,M1N6TAye,M1N6TAze,M1N6RAxe,M1N6RAye,M1N6RAze, & - M1N7TAxe,M1N7TAye,M1N7TAze,M1N7RAxe,M1N7RAye,M1N7RAze, & - M1N8TAxe,M1N8TAye,M1N8TAze,M1N8RAxe,M1N8RAye,M1N8RAze, & - M1N9TAxe,M1N9TAye,M1N9TAze,M1N9RAxe,M1N9RAye,M1N9RAze, & - M2N1TAxe,M2N1TAye,M2N1TAze,M2N1RAxe,M2N1RAye,M2N1RAze, & - M2N2TAxe,M2N2TAye,M2N2TAze,M2N2RAxe,M2N2RAye,M2N2RAze, & - M2N3TAxe,M2N3TAye,M2N3TAze,M2N3RAxe,M2N3RAye,M2N3RAze, & - M2N4TAxe,M2N4TAye,M2N4TAze,M2N4RAxe,M2N4RAye,M2N4RAze, & - M2N5TAxe,M2N5TAye,M2N5TAze,M2N5RAxe,M2N5RAye,M2N5RAze, & - M2N6TAxe,M2N6TAye,M2N6TAze,M2N6RAxe,M2N6RAye,M2N6RAze, & - M2N7TAxe,M2N7TAye,M2N7TAze,M2N7RAxe,M2N7RAye,M2N7RAze, & - M2N8TAxe,M2N8TAye,M2N8TAze,M2N8RAxe,M2N8RAye,M2N8RAze, & - M2N9TAxe,M2N9TAye,M2N9TAze,M2N9RAxe,M2N9RAye,M2N9RAze, & - M3N1TAxe,M3N1TAye,M3N1TAze,M3N1RAxe,M3N1RAye,M3N1RAze, & - M3N2TAxe,M3N2TAye,M3N2TAze,M3N2RAxe,M3N2RAye,M3N2RAze, & - M3N3TAxe,M3N3TAye,M3N3TAze,M3N3RAxe,M3N3RAye,M3N3RAze, & - M3N4TAxe,M3N4TAye,M3N4TAze,M3N4RAxe,M3N4RAye,M3N4RAze, & - M3N5TAxe,M3N5TAye,M3N5TAze,M3N5RAxe,M3N5RAye,M3N5RAze, & - M3N6TAxe,M3N6TAye,M3N6TAze,M3N6RAxe,M3N6RAye,M3N6RAze, & - M3N7TAxe,M3N7TAye,M3N7TAze,M3N7RAxe,M3N7RAye,M3N7RAze, & - M3N8TAxe,M3N8TAye,M3N8TAze,M3N8RAxe,M3N8RAye,M3N8RAze, & - M3N9TAxe,M3N9TAye,M3N9TAze,M3N9RAxe,M3N9RAye,M3N9RAze, & - M4N1TAxe,M4N1TAye,M4N1TAze,M4N1RAxe,M4N1RAye,M4N1RAze, & - M4N2TAxe,M4N2TAye,M4N2TAze,M4N2RAxe,M4N2RAye,M4N2RAze, & - M4N3TAxe,M4N3TAye,M4N3TAze,M4N3RAxe,M4N3RAye,M4N3RAze, & - M4N4TAxe,M4N4TAye,M4N4TAze,M4N4RAxe,M4N4RAye,M4N4RAze, & - M4N5TAxe,M4N5TAye,M4N5TAze,M4N5RAxe,M4N5RAye,M4N5RAze, & - M4N6TAxe,M4N6TAye,M4N6TAze,M4N6RAxe,M4N6RAye,M4N6RAze, & - M4N7TAxe,M4N7TAye,M4N7TAze,M4N7RAxe,M4N7RAye,M4N7RAze, & - M4N8TAxe,M4N8TAye,M4N8TAze,M4N8RAxe,M4N8RAye,M4N8RAze, & - M4N9TAxe,M4N9TAye,M4N9TAze,M4N9RAxe,M4N9RAye,M4N9RAze, & - M5N1TAxe,M5N1TAye,M5N1TAze,M5N1RAxe,M5N1RAye,M5N1RAze, & - M5N2TAxe,M5N2TAye,M5N2TAze,M5N2RAxe,M5N2RAye,M5N2RAze, & - M5N3TAxe,M5N3TAye,M5N3TAze,M5N3RAxe,M5N3RAye,M5N3RAze, & - M5N4TAxe,M5N4TAye,M5N4TAze,M5N4RAxe,M5N4RAye,M5N4RAze, & - M5N5TAxe,M5N5TAye,M5N5TAze,M5N5RAxe,M5N5RAye,M5N5RAze, & - M5N6TAxe,M5N6TAye,M5N6TAze,M5N6RAxe,M5N6RAye,M5N6RAze, & - M5N7TAxe,M5N7TAye,M5N7TAze,M5N7RAxe,M5N7RAye,M5N7RAze, & - M5N8TAxe,M5N8TAye,M5N8TAze,M5N8RAxe,M5N8RAye,M5N8RAze, & - M5N9TAxe,M5N9TAye,M5N9TAze,M5N9RAxe,M5N9RAye,M5N9RAze, & - M6N1TAxe,M6N1TAye,M6N1TAze,M6N1RAxe,M6N1RAye,M6N1RAze, & - M6N2TAxe,M6N2TAye,M6N2TAze,M6N2RAxe,M6N2RAye,M6N2RAze, & - M6N3TAxe,M6N3TAye,M6N3TAze,M6N3RAxe,M6N3RAye,M6N3RAze, & - M6N4TAxe,M6N4TAye,M6N4TAze,M6N4RAxe,M6N4RAye,M6N4RAze, & - M6N5TAxe,M6N5TAye,M6N5TAze,M6N5RAxe,M6N5RAye,M6N5RAze, & - M6N6TAxe,M6N6TAye,M6N6TAze,M6N6RAxe,M6N6RAye,M6N6RAze, & - M6N7TAxe,M6N7TAye,M6N7TAze,M6N7RAxe,M6N7RAye,M6N7RAze, & - M6N8TAxe,M6N8TAye,M6N8TAze,M6N8RAxe,M6N8RAye,M6N8RAze, & - M6N9TAxe,M6N9TAye,M6N9TAze,M6N9RAxe,M6N9RAye,M6N9RAze, & - M7N1TAxe,M7N1TAye,M7N1TAze,M7N1RAxe,M7N1RAye,M7N1RAze, & - M7N2TAxe,M7N2TAye,M7N2TAze,M7N2RAxe,M7N2RAye,M7N2RAze, & - M7N3TAxe,M7N3TAye,M7N3TAze,M7N3RAxe,M7N3RAye,M7N3RAze, & - M7N4TAxe,M7N4TAye,M7N4TAze,M7N4RAxe,M7N4RAye,M7N4RAze, & - M7N5TAxe,M7N5TAye,M7N5TAze,M7N5RAxe,M7N5RAye,M7N5RAze, & - M7N6TAxe,M7N6TAye,M7N6TAze,M7N6RAxe,M7N6RAye,M7N6RAze, & - M7N7TAxe,M7N7TAye,M7N7TAze,M7N7RAxe,M7N7RAye,M7N7RAze, & - M7N8TAxe,M7N8TAye,M7N8TAze,M7N8RAxe,M7N8RAye,M7N8RAze, & - M7N9TAxe,M7N9TAye,M7N9TAze,M7N9RAxe,M7N9RAye,M7N9RAze, & - M8N1TAxe,M8N1TAye,M8N1TAze,M8N1RAxe,M8N1RAye,M8N1RAze, & - M8N2TAxe,M8N2TAye,M8N2TAze,M8N2RAxe,M8N2RAye,M8N2RAze, & - M8N3TAxe,M8N3TAye,M8N3TAze,M8N3RAxe,M8N3RAye,M8N3RAze, & - M8N4TAxe,M8N4TAye,M8N4TAze,M8N4RAxe,M8N4RAye,M8N4RAze, & - M8N5TAxe,M8N5TAye,M8N5TAze,M8N5RAxe,M8N5RAye,M8N5RAze, & - M8N6TAxe,M8N6TAye,M8N6TAze,M8N6RAxe,M8N6RAye,M8N6RAze, & - M8N7TAxe,M8N7TAye,M8N7TAze,M8N7RAxe,M8N7RAye,M8N7RAze, & - M8N8TAxe,M8N8TAye,M8N8TAze,M8N8RAxe,M8N8RAye,M8N8RAze, & - M8N9TAxe,M8N9TAye,M8N9TAze,M8N9RAxe,M8N9RAye,M8N9RAze, & - M9N1TAxe,M9N1TAye,M9N1TAze,M9N1RAxe,M9N1RAye,M9N1RAze, & - M9N2TAxe,M9N2TAye,M9N2TAze,M9N2RAxe,M9N2RAye,M9N2RAze, & - M9N3TAxe,M9N3TAye,M9N3TAze,M9N3RAxe,M9N3RAye,M9N3RAze, & - M9N4TAxe,M9N4TAye,M9N4TAze,M9N4RAxe,M9N4RAye,M9N4RAze, & - M9N5TAxe,M9N5TAye,M9N5TAze,M9N5RAxe,M9N5RAye,M9N5RAze, & - M9N6TAxe,M9N6TAye,M9N6TAze,M9N6RAxe,M9N6RAye,M9N6RAze, & - M9N7TAxe,M9N7TAye,M9N7TAze,M9N7RAxe,M9N7RAye,M9N7RAze, & - M9N8TAxe,M9N8TAye,M9N8TAze,M9N8RAxe,M9N8RAye,M9N8RAze, & - M9N9TAxe,M9N9TAye,M9N9TAze,M9N9RAxe,M9N9RAye,M9N9RAze/), (/6,9,9/)) - - INTEGER, PARAMETER :: ReactSS(6) = (/ReactFXss, ReactFYss, ReactFZss , & - ReactMXss, ReactMYss, ReactMZss/) - - INTEGER, PARAMETER :: IntfSS(6) = (/IntfFXss, IntfFYss, IntfFZss , & - IntfMXss, IntfMYss, IntfMZss/) - - INTEGER, PARAMETER :: IntfTRss(6) = (/IntfTDXss, IntfTDYss, IntfTDZss , & - IntfRDXss, IntfRDYss, IntfRDZss/) - - INTEGER, PARAMETER :: IntfTRAss(6) = (/IntfTAXss, IntfTAYss, IntfTAZss , & - IntfRAXss, IntfRAYss, IntfRAZss/) - - - - - - - - CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(2265) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically - "INTFFXSS ","INTFFYSS ","INTFFZSS ","INTFMXSS ","INTFMYSS ","INTFMZSS ","INTFRAXSS", & - "INTFRAYSS","INTFRAZSS","INTFRDXSS","INTFRDYSS","INTFRDZSS","INTFTAXSS","INTFTAYSS", & - "INTFTAZSS","INTFTDXSS","INTFTDYSS","INTFTDZSS","M1N1FKXE ","M1N1FKYE ","M1N1FKZE ", & - "M1N1FMXE ","M1N1FMYE ","M1N1FMZE ","M1N1MKXE ","M1N1MKYE ","M1N1MKZE ","M1N1MMXE ", & - "M1N1MMYE ","M1N1MMZE ","M1N1RAXE ","M1N1RAYE ","M1N1RAZE ","M1N1RDXE ","M1N1RDYE ", & - "M1N1RDZE ","M1N1TAXE ","M1N1TAYE ","M1N1TAZE ","M1N1TDXSS","M1N1TDYSS","M1N1TDZSS", & - "M1N2FKXE ","M1N2FKYE ","M1N2FKZE ","M1N2FMXE ","M1N2FMYE ","M1N2FMZE ","M1N2MKXE ", & - "M1N2MKYE ","M1N2MKZE ","M1N2MMXE ","M1N2MMYE ","M1N2MMZE ","M1N2RAXE ","M1N2RAYE ", & - "M1N2RAZE ","M1N2RDXE ","M1N2RDYE ","M1N2RDZE ","M1N2TAXE ","M1N2TAYE ","M1N2TAZE ", & - "M1N2TDXSS","M1N2TDYSS","M1N2TDZSS","M1N3FKXE ","M1N3FKYE ","M1N3FKZE ","M1N3FMXE ", & - "M1N3FMYE ","M1N3FMZE ","M1N3MKXE ","M1N3MKYE ","M1N3MKZE ","M1N3MMXE ","M1N3MMYE ", & - "M1N3MMZE ","M1N3RAXE ","M1N3RAYE ","M1N3RAZE ","M1N3RDXE ","M1N3RDYE ","M1N3RDZE ", & - "M1N3TAXE ","M1N3TAYE ","M1N3TAZE ","M1N3TDXSS","M1N3TDYSS","M1N3TDZSS","M1N4FKXE ", & - "M1N4FKYE ","M1N4FKZE ","M1N4FMXE ","M1N4FMYE ","M1N4FMZE ","M1N4MKXE ","M1N4MKYE ", & - "M1N4MKZE ","M1N4MMXE ","M1N4MMYE ","M1N4MMZE ","M1N4RAXE ","M1N4RAYE ","M1N4RAZE ", & - "M1N4RDXE ","M1N4RDYE ","M1N4RDZE ","M1N4TAXE ","M1N4TAYE ","M1N4TAZE ","M1N4TDXSS", & - "M1N4TDYSS","M1N4TDZSS","M1N5FKXE ","M1N5FKYE ","M1N5FKZE ","M1N5FMXE ","M1N5FMYE ", & - "M1N5FMZE ","M1N5MKXE ","M1N5MKYE ","M1N5MKZE ","M1N5MMXE ","M1N5MMYE ","M1N5MMZE ", & - "M1N5RAXE ","M1N5RAYE ","M1N5RAZE ","M1N5RDXE ","M1N5RDYE ","M1N5RDZE ","M1N5TAXE ", & - "M1N5TAYE ","M1N5TAZE ","M1N5TDXSS","M1N5TDYSS","M1N5TDZSS","M1N6FKXE ","M1N6FKYE ", & - "M1N6FKZE ","M1N6FMXE ","M1N6FMYE ","M1N6FMZE ","M1N6MKXE ","M1N6MKYE ","M1N6MKZE ", & - "M1N6MMXE ","M1N6MMYE ","M1N6MMZE ","M1N6RAXE ","M1N6RAYE ","M1N6RAZE ","M1N6RDXE ", & - "M1N6RDYE ","M1N6RDZE ","M1N6TAXE ","M1N6TAYE ","M1N6TAZE ","M1N6TDXSS","M1N6TDYSS", & - "M1N6TDZSS","M1N7FKXE ","M1N7FKYE ","M1N7FKZE ","M1N7FMXE ","M1N7FMYE ","M1N7FMZE ", & - "M1N7MKXE ","M1N7MKYE ","M1N7MKZE ","M1N7MMXE ","M1N7MMYE ","M1N7MMZE ","M1N7RAXE ", & - "M1N7RAYE ","M1N7RAZE ","M1N7RDXE ","M1N7RDYE ","M1N7RDZE ","M1N7TAXE ","M1N7TAYE ", & - "M1N7TAZE ","M1N7TDXSS","M1N7TDYSS","M1N7TDZSS","M1N8FKXE ","M1N8FKYE ","M1N8FKZE ", & - "M1N8FMXE ","M1N8FMYE ","M1N8FMZE ","M1N8MKXE ","M1N8MKYE ","M1N8MKZE ","M1N8MMXE ", & - "M1N8MMYE ","M1N8MMZE ","M1N8RAXE ","M1N8RAYE ","M1N8RAZE ","M1N8RDXE ","M1N8RDYE ", & - "M1N8RDZE ","M1N8TAXE ","M1N8TAYE ","M1N8TAZE ","M1N8TDXSS","M1N8TDYSS","M1N8TDZSS", & - "M1N9FKXE ","M1N9FKYE ","M1N9FKZE ","M1N9FMXE ","M1N9FMYE ","M1N9FMZE ","M1N9MKXE ", & - "M1N9MKYE ","M1N9MKZE ","M1N9MMXE ","M1N9MMYE ","M1N9MMZE ","M1N9RAXE ","M1N9RAYE ", & - "M1N9RAZE ","M1N9RDXE ","M1N9RDYE ","M1N9RDZE ","M1N9TAXE ","M1N9TAYE ","M1N9TAZE ", & - "M1N9TDXSS","M1N9TDYSS","M1N9TDZSS","M2N1FKXE ","M2N1FKYE ","M2N1FKZE ","M2N1FMXE ", & - "M2N1FMYE ","M2N1FMZE ","M2N1MKXE ","M2N1MKYE ","M2N1MKZE ","M2N1MMXE ","M2N1MMYE ", & - "M2N1MMZE ","M2N1RAXE ","M2N1RAYE ","M2N1RAZE ","M2N1RDXE ","M2N1RDYE ","M2N1RDZE ", & - "M2N1TAXE ","M2N1TAYE ","M2N1TAZE ","M2N1TDXSS","M2N1TDYSS","M2N1TDZSS","M2N2FKXE ", & - "M2N2FKYE ","M2N2FKZE ","M2N2FMXE ","M2N2FMYE ","M2N2FMZE ","M2N2MKXE ","M2N2MKYE ", & - "M2N2MKZE ","M2N2MMXE ","M2N2MMYE ","M2N2MMZE ","M2N2RAXE ","M2N2RAYE ","M2N2RAZE ", & - "M2N2RDXE ","M2N2RDYE ","M2N2RDZE ","M2N2TAXE ","M2N2TAYE ","M2N2TAZE ","M2N2TDXSS", & - "M2N2TDYSS","M2N2TDZSS","M2N3FKXE ","M2N3FKYE ","M2N3FKZE ","M2N3FMXE ","M2N3FMYE ", & - "M2N3FMZE ","M2N3MKXE ","M2N3MKYE ","M2N3MKZE ","M2N3MMXE ","M2N3MMYE ","M2N3MMZE ", & - "M2N3RAXE ","M2N3RAYE ","M2N3RAZE ","M2N3RDXE ","M2N3RDYE ","M2N3RDZE ","M2N3TAXE ", & - "M2N3TAYE ","M2N3TAZE ","M2N3TDXSS","M2N3TDYSS","M2N3TDZSS","M2N4FKXE ","M2N4FKYE ", & - "M2N4FKZE ","M2N4FMXE ","M2N4FMYE ","M2N4FMZE ","M2N4MKXE ","M2N4MKYE ","M2N4MKZE ", & - "M2N4MMXE ","M2N4MMYE ","M2N4MMZE ","M2N4RAXE ","M2N4RAYE ","M2N4RAZE ","M2N4RDXE ", & - "M2N4RDYE ","M2N4RDZE ","M2N4TAXE ","M2N4TAYE ","M2N4TAZE ","M2N4TDXSS","M2N4TDYSS", & - "M2N4TDZSS","M2N5FKXE ","M2N5FKYE ","M2N5FKZE ","M2N5FMXE ","M2N5FMYE ","M2N5FMZE ", & - "M2N5MKXE ","M2N5MKYE ","M2N5MKZE ","M2N5MMXE ","M2N5MMYE ","M2N5MMZE ","M2N5RAXE ", & - "M2N5RAYE ","M2N5RAZE ","M2N5RDXE ","M2N5RDYE ","M2N5RDZE ","M2N5TAXE ","M2N5TAYE ", & - "M2N5TAZE ","M2N5TDXSS","M2N5TDYSS","M2N5TDZSS","M2N6FKXE ","M2N6FKYE ","M2N6FKZE ", & - "M2N6FMXE ","M2N6FMYE ","M2N6FMZE ","M2N6MKXE ","M2N6MKYE ","M2N6MKZE ","M2N6MMXE ", & - "M2N6MMYE ","M2N6MMZE ","M2N6RAXE ","M2N6RAYE ","M2N6RAZE ","M2N6RDXE ","M2N6RDYE ", & - "M2N6RDZE ","M2N6TAXE ","M2N6TAYE ","M2N6TAZE ","M2N6TDXSS","M2N6TDYSS","M2N6TDZSS", & - "M2N7FKXE ","M2N7FKYE ","M2N7FKZE ","M2N7FMXE ","M2N7FMYE ","M2N7FMZE ","M2N7MKXE ", & - "M2N7MKYE ","M2N7MKZE ","M2N7MMXE ","M2N7MMYE ","M2N7MMZE ","M2N7RAXE ","M2N7RAYE ", & - "M2N7RAZE ","M2N7RDXE ","M2N7RDYE ","M2N7RDZE ","M2N7TAXE ","M2N7TAYE ","M2N7TAZE ", & - "M2N7TDXSS","M2N7TDYSS","M2N7TDZSS","M2N8FKXE ","M2N8FKYE ","M2N8FKZE ","M2N8FMXE ", & - "M2N8FMYE ","M2N8FMZE ","M2N8MKXE ","M2N8MKYE ","M2N8MKZE ","M2N8MMXE ","M2N8MMYE ", & - "M2N8MMZE ","M2N8RAXE ","M2N8RAYE ","M2N8RAZE ","M2N8RDXE ","M2N8RDYE ","M2N8RDZE ", & - "M2N8TAXE ","M2N8TAYE ","M2N8TAZE ","M2N8TDXSS","M2N8TDYSS","M2N8TDZSS","M2N9FKXE ", & - "M2N9FKYE ","M2N9FKZE ","M2N9FMXE ","M2N9FMYE ","M2N9FMZE ","M2N9MKXE ","M2N9MKYE ", & - "M2N9MKZE ","M2N9MMXE ","M2N9MMYE ","M2N9MMZE ","M2N9RAXE ","M2N9RAYE ","M2N9RAZE ", & - "M2N9RDXE ","M2N9RDYE ","M2N9RDZE ","M2N9TAXE ","M2N9TAYE ","M2N9TAZE ","M2N9TDXSS", & - "M2N9TDYSS","M2N9TDZSS","M3N1FKXE ","M3N1FKYE ","M3N1FKZE ","M3N1FMXE ","M3N1FMYE ", & - "M3N1FMZE ","M3N1MKXE ","M3N1MKYE ","M3N1MKZE ","M3N1MMXE ","M3N1MMYE ","M3N1MMZE ", & - "M3N1RAXE ","M3N1RAYE ","M3N1RAZE ","M3N1RDXE ","M3N1RDYE ","M3N1RDZE ","M3N1TAXE ", & - "M3N1TAYE ","M3N1TAZE ","M3N1TDXSS","M3N1TDYSS","M3N1TDZSS","M3N2FKXE ","M3N2FKYE ", & - "M3N2FKZE ","M3N2FMXE ","M3N2FMYE ","M3N2FMZE ","M3N2MKXE ","M3N2MKYE ","M3N2MKZE ", & - "M3N2MMXE ","M3N2MMYE ","M3N2MMZE ","M3N2RAXE ","M3N2RAYE ","M3N2RAZE ","M3N2RDXE ", & - "M3N2RDYE ","M3N2RDZE ","M3N2TAXE ","M3N2TAYE ","M3N2TAZE ","M3N2TDXSS","M3N2TDYSS", & - "M3N2TDZSS","M3N3FKXE ","M3N3FKYE ","M3N3FKZE ","M3N3FMXE ","M3N3FMYE ","M3N3FMZE ", & - "M3N3MKXE ","M3N3MKYE ","M3N3MKZE ","M3N3MMXE ","M3N3MMYE ","M3N3MMZE ","M3N3RAXE ", & - "M3N3RAYE ","M3N3RAZE ","M3N3RDXE ","M3N3RDYE ","M3N3RDZE ","M3N3TAXE ","M3N3TAYE ", & - "M3N3TAZE ","M3N3TDXSS","M3N3TDYSS","M3N3TDZSS","M3N4FKXE ","M3N4FKYE ","M3N4FKZE ", & - "M3N4FMXE ","M3N4FMYE ","M3N4FMZE ","M3N4MKXE ","M3N4MKYE ","M3N4MKZE ","M3N4MMXE ", & - "M3N4MMYE ","M3N4MMZE ","M3N4RAXE ","M3N4RAYE ","M3N4RAZE ","M3N4RDXE ","M3N4RDYE ", & - "M3N4RDZE ","M3N4TAXE ","M3N4TAYE ","M3N4TAZE ","M3N4TDXSS","M3N4TDYSS","M3N4TDZSS", & - "M3N5FKXE ","M3N5FKYE ","M3N5FKZE ","M3N5FMXE ","M3N5FMYE ","M3N5FMZE ","M3N5MKXE ", & - "M3N5MKYE ","M3N5MKZE ","M3N5MMXE ","M3N5MMYE ","M3N5MMZE ","M3N5RAXE ","M3N5RAYE ", & - "M3N5RAZE ","M3N5RDXE ","M3N5RDYE ","M3N5RDZE ","M3N5TAXE ","M3N5TAYE ","M3N5TAZE ", & - "M3N5TDXSS","M3N5TDYSS","M3N5TDZSS","M3N6FKXE ","M3N6FKYE ","M3N6FKZE ","M3N6FMXE ", & - "M3N6FMYE ","M3N6FMZE ","M3N6MKXE ","M3N6MKYE ","M3N6MKZE ","M3N6MMXE ","M3N6MMYE ", & - "M3N6MMZE ","M3N6RAXE ","M3N6RAYE ","M3N6RAZE ","M3N6RDXE ","M3N6RDYE ","M3N6RDZE ", & - "M3N6TAXE ","M3N6TAYE ","M3N6TAZE ","M3N6TDXSS","M3N6TDYSS","M3N6TDZSS","M3N7FKXE ", & - "M3N7FKYE ","M3N7FKZE ","M3N7FMXE ","M3N7FMYE ","M3N7FMZE ","M3N7MKXE ","M3N7MKYE ", & - "M3N7MKZE ","M3N7MMXE ","M3N7MMYE ","M3N7MMZE ","M3N7RAXE ","M3N7RAYE ","M3N7RAZE ", & - "M3N7RDXE ","M3N7RDYE ","M3N7RDZE ","M3N7TAXE ","M3N7TAYE ","M3N7TAZE ","M3N7TDXSS", & - "M3N7TDYSS","M3N7TDZSS","M3N8FKXE ","M3N8FKYE ","M3N8FKZE ","M3N8FMXE ","M3N8FMYE ", & - "M3N8FMZE ","M3N8MKXE ","M3N8MKYE ","M3N8MKZE ","M3N8MMXE ","M3N8MMYE ","M3N8MMZE ", & - "M3N8RAXE ","M3N8RAYE ","M3N8RAZE ","M3N8RDXE ","M3N8RDYE ","M3N8RDZE ","M3N8TAXE ", & - "M3N8TAYE ","M3N8TAZE ","M3N8TDXSS","M3N8TDYSS","M3N8TDZSS","M3N9FKXE ","M3N9FKYE ", & - "M3N9FKZE ","M3N9FMXE ","M3N9FMYE ","M3N9FMZE ","M3N9MKXE ","M3N9MKYE ","M3N9MKZE ", & - "M3N9MMXE ","M3N9MMYE ","M3N9MMZE ","M3N9RAXE ","M3N9RAYE ","M3N9RAZE ","M3N9RDXE ", & - "M3N9RDYE ","M3N9RDZE ","M3N9TAXE ","M3N9TAYE ","M3N9TAZE ","M3N9TDXSS","M3N9TDYSS", & - "M3N9TDZSS","M4N1FKXE ","M4N1FKYE ","M4N1FKZE ","M4N1FMXE ","M4N1FMYE ","M4N1FMZE ", & - "M4N1MKXE ","M4N1MKYE ","M4N1MKZE ","M4N1MMXE ","M4N1MMYE ","M4N1MMZE ","M4N1RAXE ", & - "M4N1RAYE ","M4N1RAZE ","M4N1RDXE ","M4N1RDYE ","M4N1RDZE ","M4N1TAXE ","M4N1TAYE ", & - "M4N1TAZE ","M4N1TDXSS","M4N1TDYSS","M4N1TDZSS","M4N2FKXE ","M4N2FKYE ","M4N2FKZE ", & - "M4N2FMXE ","M4N2FMYE ","M4N2FMZE ","M4N2MKXE ","M4N2MKYE ","M4N2MKZE ","M4N2MMXE ", & - "M4N2MMYE ","M4N2MMZE ","M4N2RAXE ","M4N2RAYE ","M4N2RAZE ","M4N2RDXE ","M4N2RDYE ", & - "M4N2RDZE ","M4N2TAXE ","M4N2TAYE ","M4N2TAZE ","M4N2TDXSS","M4N2TDYSS","M4N2TDZSS", & - "M4N3FKXE ","M4N3FKYE ","M4N3FKZE ","M4N3FMXE ","M4N3FMYE ","M4N3FMZE ","M4N3MKXE ", & - "M4N3MKYE ","M4N3MKZE ","M4N3MMXE ","M4N3MMYE ","M4N3MMZE ","M4N3RAXE ","M4N3RAYE ", & - "M4N3RAZE ","M4N3RDXE ","M4N3RDYE ","M4N3RDZE ","M4N3TAXE ","M4N3TAYE ","M4N3TAZE ", & - "M4N3TDXSS","M4N3TDYSS","M4N3TDZSS","M4N4FKXE ","M4N4FKYE ","M4N4FKZE ","M4N4FMXE ", & - "M4N4FMYE ","M4N4FMZE ","M4N4MKXE ","M4N4MKYE ","M4N4MKZE ","M4N4MMXE ","M4N4MMYE ", & - "M4N4MMZE ","M4N4RAXE ","M4N4RAYE ","M4N4RAZE ","M4N4RDXE ","M4N4RDYE ","M4N4RDZE ", & - "M4N4TAXE ","M4N4TAYE ","M4N4TAZE ","M4N4TDXSS","M4N4TDYSS","M4N4TDZSS","M4N5FKXE ", & - "M4N5FKYE ","M4N5FKZE ","M4N5FMXE ","M4N5FMYE ","M4N5FMZE ","M4N5MKXE ","M4N5MKYE ", & - "M4N5MKZE ","M4N5MMXE ","M4N5MMYE ","M4N5MMZE ","M4N5RAXE ","M4N5RAYE ","M4N5RAZE ", & - "M4N5RDXE ","M4N5RDYE ","M4N5RDZE ","M4N5TAXE ","M4N5TAYE ","M4N5TAZE ","M4N5TDXSS", & - "M4N5TDYSS","M4N5TDZSS","M4N6FKXE ","M4N6FKYE ","M4N6FKZE ","M4N6FMXE ","M4N6FMYE ", & - "M4N6FMZE ","M4N6MKXE ","M4N6MKYE ","M4N6MKZE ","M4N6MMXE ","M4N6MMYE ","M4N6MMZE ", & - "M4N6RAXE ","M4N6RAYE ","M4N6RAZE ","M4N6RDXE ","M4N6RDYE ","M4N6RDZE ","M4N6TAXE ", & - "M4N6TAYE ","M4N6TAZE ","M4N6TDXSS","M4N6TDYSS","M4N6TDZSS","M4N7FKXE ","M4N7FKYE ", & - "M4N7FKZE ","M4N7FMXE ","M4N7FMYE ","M4N7FMZE ","M4N7MKXE ","M4N7MKYE ","M4N7MKZE ", & - "M4N7MMXE ","M4N7MMYE ","M4N7MMZE ","M4N7RAXE ","M4N7RAYE ","M4N7RAZE ","M4N7RDXE ", & - "M4N7RDYE ","M4N7RDZE ","M4N7TAXE ","M4N7TAYE ","M4N7TAZE ","M4N7TDXSS","M4N7TDYSS", & - "M4N7TDZSS","M4N8FKXE ","M4N8FKYE ","M4N8FKZE ","M4N8FMXE ","M4N8FMYE ","M4N8FMZE ", & - "M4N8MKXE ","M4N8MKYE ","M4N8MKZE ","M4N8MMXE ","M4N8MMYE ","M4N8MMZE ","M4N8RAXE ", & - "M4N8RAYE ","M4N8RAZE ","M4N8RDXE ","M4N8RDYE ","M4N8RDZE ","M4N8TAXE ","M4N8TAYE ", & - "M4N8TAZE ","M4N8TDXSS","M4N8TDYSS","M4N8TDZSS","M4N9FKXE ","M4N9FKYE ","M4N9FKZE ", & - "M4N9FMXE ","M4N9FMYE ","M4N9FMZE ","M4N9MKXE ","M4N9MKYE ","M4N9MKZE ","M4N9MMXE ", & - "M4N9MMYE ","M4N9MMZE ","M4N9RAXE ","M4N9RAYE ","M4N9RAZE ","M4N9RDXE ","M4N9RDYE ", & - "M4N9RDZE ","M4N9TAXE ","M4N9TAYE ","M4N9TAZE ","M4N9TDXSS","M4N9TDYSS","M4N9TDZSS", & - "M5N1FKXE ","M5N1FKYE ","M5N1FKZE ","M5N1FMXE ","M5N1FMYE ","M5N1FMZE ","M5N1MKXE ", & - "M5N1MKYE ","M5N1MKZE ","M5N1MMXE ","M5N1MMYE ","M5N1MMZE ","M5N1RAXE ","M5N1RAYE ", & - "M5N1RAZE ","M5N1RDXE ","M5N1RDYE ","M5N1RDZE ","M5N1TAXE ","M5N1TAYE ","M5N1TAZE ", & - "M5N1TDXSS","M5N1TDYSS","M5N1TDZSS","M5N2FKXE ","M5N2FKYE ","M5N2FKZE ","M5N2FMXE ", & - "M5N2FMYE ","M5N2FMZE ","M5N2MKXE ","M5N2MKYE ","M5N2MKZE ","M5N2MMXE ","M5N2MMYE ", & - "M5N2MMZE ","M5N2RAXE ","M5N2RAYE ","M5N2RAZE ","M5N2RDXE ","M5N2RDYE ","M5N2RDZE ", & - "M5N2TAXE ","M5N2TAYE ","M5N2TAZE ","M5N2TDXSS","M5N2TDYSS","M5N2TDZSS","M5N3FKXE ", & - "M5N3FKYE ","M5N3FKZE ","M5N3FMXE ","M5N3FMYE ","M5N3FMZE ","M5N3MKXE ","M5N3MKYE ", & - "M5N3MKZE ","M5N3MMXE ","M5N3MMYE ","M5N3MMZE ","M5N3RAXE ","M5N3RAYE ","M5N3RAZE ", & - "M5N3RDXE ","M5N3RDYE ","M5N3RDZE ","M5N3TAXE ","M5N3TAYE ","M5N3TAZE ","M5N3TDXSS", & - "M5N3TDYSS","M5N3TDZSS","M5N4FKXE ","M5N4FKYE ","M5N4FKZE ","M5N4FMXE ","M5N4FMYE ", & - "M5N4FMZE ","M5N4MKXE ","M5N4MKYE ","M5N4MKZE ","M5N4MMXE ","M5N4MMYE ","M5N4MMZE ", & - "M5N4RAXE ","M5N4RAYE ","M5N4RAZE ","M5N4RDXE ","M5N4RDYE ","M5N4RDZE ","M5N4TAXE ", & - "M5N4TAYE ","M5N4TAZE ","M5N4TDXSS","M5N4TDYSS","M5N4TDZSS","M5N5FKXE ","M5N5FKYE ", & - "M5N5FKZE ","M5N5FMXE ","M5N5FMYE ","M5N5FMZE ","M5N5MKXE ","M5N5MKYE ","M5N5MKZE ", & - "M5N5MMXE ","M5N5MMYE ","M5N5MMZE ","M5N5RAXE ","M5N5RAYE ","M5N5RAZE ","M5N5RDXE ", & - "M5N5RDYE ","M5N5RDZE ","M5N5TAXE ","M5N5TAYE ","M5N5TAZE ","M5N5TDXSS","M5N5TDYSS", & - "M5N5TDZSS","M5N6FKXE ","M5N6FKYE ","M5N6FKZE ","M5N6FMXE ","M5N6FMYE ","M5N6FMZE ", & - "M5N6MKXE ","M5N6MKYE ","M5N6MKZE ","M5N6MMXE ","M5N6MMYE ","M5N6MMZE ","M5N6RAXE ", & - "M5N6RAYE ","M5N6RAZE ","M5N6RDXE ","M5N6RDYE ","M5N6RDZE ","M5N6TAXE ","M5N6TAYE ", & - "M5N6TAZE ","M5N6TDXSS","M5N6TDYSS","M5N6TDZSS","M5N7FKXE ","M5N7FKYE ","M5N7FKZE ", & - "M5N7FMXE ","M5N7FMYE ","M5N7FMZE ","M5N7MKXE ","M5N7MKYE ","M5N7MKZE ","M5N7MMXE ", & - "M5N7MMYE ","M5N7MMZE ","M5N7RAXE ","M5N7RAYE ","M5N7RAZE ","M5N7RDXE ","M5N7RDYE ", & - "M5N7RDZE ","M5N7TAXE ","M5N7TAYE ","M5N7TAZE ","M5N7TDXSS","M5N7TDYSS","M5N7TDZSS", & - "M5N8FKXE ","M5N8FKYE ","M5N8FKZE ","M5N8FMXE ","M5N8FMYE ","M5N8FMZE ","M5N8MKXE ", & - "M5N8MKYE ","M5N8MKZE ","M5N8MMXE ","M5N8MMYE ","M5N8MMZE ","M5N8RAXE ","M5N8RAYE ", & - "M5N8RAZE ","M5N8RDXE ","M5N8RDYE ","M5N8RDZE ","M5N8TAXE ","M5N8TAYE ","M5N8TAZE ", & - "M5N8TDXSS","M5N8TDYSS","M5N8TDZSS","M5N9FKXE ","M5N9FKYE ","M5N9FKZE ","M5N9FMXE ", & - "M5N9FMYE ","M5N9FMZE ","M5N9MKXE ","M5N9MKYE ","M5N9MKZE ","M5N9MMXE ","M5N9MMYE ", & - "M5N9MMZE ","M5N9RAXE ","M5N9RAYE ","M5N9RAZE ","M5N9RDXE ","M5N9RDYE ","M5N9RDZE ", & - "M5N9TAXE ","M5N9TAYE ","M5N9TAZE ","M5N9TDXSS","M5N9TDYSS","M5N9TDZSS","M6N1FKXE ", & - "M6N1FKYE ","M6N1FKZE ","M6N1FMXE ","M6N1FMYE ","M6N1FMZE ","M6N1MKXE ","M6N1MKYE ", & - "M6N1MKZE ","M6N1MMXE ","M6N1MMYE ","M6N1MMZE ","M6N1RAXE ","M6N1RAYE ","M6N1RAZE ", & - "M6N1RDXE ","M6N1RDYE ","M6N1RDZE ","M6N1TAXE ","M6N1TAYE ","M6N1TAZE ","M6N1TDXSS", & - "M6N1TDYSS","M6N1TDZSS","M6N2FKXE ","M6N2FKYE ","M6N2FKZE ","M6N2FMXE ","M6N2FMYE ", & - "M6N2FMZE ","M6N2MKXE ","M6N2MKYE ","M6N2MKZE ","M6N2MMXE ","M6N2MMYE ","M6N2MMZE ", & - "M6N2RAXE ","M6N2RAYE ","M6N2RAZE ","M6N2RDXE ","M6N2RDYE ","M6N2RDZE ","M6N2TAXE ", & - "M6N2TAYE ","M6N2TAZE ","M6N2TDXSS","M6N2TDYSS","M6N2TDZSS","M6N3FKXE ","M6N3FKYE ", & - "M6N3FKZE ","M6N3FMXE ","M6N3FMYE ","M6N3FMZE ","M6N3MKXE ","M6N3MKYE ","M6N3MKZE ", & - "M6N3MMXE ","M6N3MMYE ","M6N3MMZE ","M6N3RAXE ","M6N3RAYE ","M6N3RAZE ","M6N3RDXE ", & - "M6N3RDYE ","M6N3RDZE ","M6N3TAXE ","M6N3TAYE ","M6N3TAZE ","M6N3TDXSS","M6N3TDYSS", & - "M6N3TDZSS","M6N4FKXE ","M6N4FKYE ","M6N4FKZE ","M6N4FMXE ","M6N4FMYE ","M6N4FMZE ", & - "M6N4MKXE ","M6N4MKYE ","M6N4MKZE ","M6N4MMXE ","M6N4MMYE ","M6N4MMZE ","M6N4RAXE ", & - "M6N4RAYE ","M6N4RAZE ","M6N4RDXE ","M6N4RDYE ","M6N4RDZE ","M6N4TAXE ","M6N4TAYE ", & - "M6N4TAZE ","M6N4TDXSS","M6N4TDYSS","M6N4TDZSS","M6N5FKXE ","M6N5FKYE ","M6N5FKZE ", & - "M6N5FMXE ","M6N5FMYE ","M6N5FMZE ","M6N5MKXE ","M6N5MKYE ","M6N5MKZE ","M6N5MMXE ", & - "M6N5MMYE ","M6N5MMZE ","M6N5RAXE ","M6N5RAYE ","M6N5RAZE ","M6N5RDXE ","M6N5RDYE ", & - "M6N5RDZE ","M6N5TAXE ","M6N5TAYE ","M6N5TAZE ","M6N5TDXSS","M6N5TDYSS","M6N5TDZSS", & - "M6N6FKXE ","M6N6FKYE ","M6N6FKZE ","M6N6FMXE ","M6N6FMYE ","M6N6FMZE ","M6N6MKXE ", & - "M6N6MKYE ","M6N6MKZE ","M6N6MMXE ","M6N6MMYE ","M6N6MMZE ","M6N6RAXE ","M6N6RAYE ", & - "M6N6RAZE ","M6N6RDXE ","M6N6RDYE ","M6N6RDZE ","M6N6TAXE ","M6N6TAYE ","M6N6TAZE ", & - "M6N6TDXSS","M6N6TDYSS","M6N6TDZSS","M6N7FKXE ","M6N7FKYE ","M6N7FKZE ","M6N7FMXE ", & - "M6N7FMYE ","M6N7FMZE ","M6N7MKXE ","M6N7MKYE ","M6N7MKZE ","M6N7MMXE ","M6N7MMYE ", & - "M6N7MMZE ","M6N7RAXE ","M6N7RAYE ","M6N7RAZE ","M6N7RDXE ","M6N7RDYE ","M6N7RDZE ", & - "M6N7TAXE ","M6N7TAYE ","M6N7TAZE ","M6N7TDXSS","M6N7TDYSS","M6N7TDZSS","M6N8FKXE ", & - "M6N8FKYE ","M6N8FKZE ","M6N8FMXE ","M6N8FMYE ","M6N8FMZE ","M6N8MKXE ","M6N8MKYE ", & - "M6N8MKZE ","M6N8MMXE ","M6N8MMYE ","M6N8MMZE ","M6N8RAXE ","M6N8RAYE ","M6N8RAZE ", & - "M6N8RDXE ","M6N8RDYE ","M6N8RDZE ","M6N8TAXE ","M6N8TAYE ","M6N8TAZE ","M6N8TDXSS", & - "M6N8TDYSS","M6N8TDZSS","M6N9FKXE ","M6N9FKYE ","M6N9FKZE ","M6N9FMXE ","M6N9FMYE ", & - "M6N9FMZE ","M6N9MKXE ","M6N9MKYE ","M6N9MKZE ","M6N9MMXE ","M6N9MMYE ","M6N9MMZE ", & - "M6N9RAXE ","M6N9RAYE ","M6N9RAZE ","M6N9RDXE ","M6N9RDYE ","M6N9RDZE ","M6N9TAXE ", & - "M6N9TAYE ","M6N9TAZE ","M6N9TDXSS","M6N9TDYSS","M6N9TDZSS","M7N1FKXE ","M7N1FKYE ", & - "M7N1FKZE ","M7N1FMXE ","M7N1FMYE ","M7N1FMZE ","M7N1MKXE ","M7N1MKYE ","M7N1MKZE ", & - "M7N1MMXE ","M7N1MMYE ","M7N1MMZE ","M7N1RAXE ","M7N1RAYE ","M7N1RAZE ","M7N1RDXE ", & - "M7N1RDYE ","M7N1RDZE ","M7N1TAXE ","M7N1TAYE ","M7N1TAZE ","M7N1TDXSS","M7N1TDYSS", & - "M7N1TDZSS","M7N2FKXE ","M7N2FKYE ","M7N2FKZE ","M7N2FMXE ","M7N2FMYE ","M7N2FMZE ", & - "M7N2MKXE ","M7N2MKYE ","M7N2MKZE ","M7N2MMXE ","M7N2MMYE ","M7N2MMZE ","M7N2RAXE ", & - "M7N2RAYE ","M7N2RAZE ","M7N2RDXE ","M7N2RDYE ","M7N2RDZE ","M7N2TAXE ","M7N2TAYE ", & - "M7N2TAZE ","M7N2TDXSS","M7N2TDYSS","M7N2TDZSS","M7N3FKXE ","M7N3FKYE ","M7N3FKZE ", & - "M7N3FMXE ","M7N3FMYE ","M7N3FMZE ","M7N3MKXE ","M7N3MKYE ","M7N3MKZE ","M7N3MMXE ", & - "M7N3MMYE ","M7N3MMZE ","M7N3RAXE ","M7N3RAYE ","M7N3RAZE ","M7N3RDXE ","M7N3RDYE ", & - "M7N3RDZE ","M7N3TAXE ","M7N3TAYE ","M7N3TAZE ","M7N3TDXSS","M7N3TDYSS","M7N3TDZSS", & - "M7N4FKXE ","M7N4FKYE ","M7N4FKZE ","M7N4FMXE ","M7N4FMYE ","M7N4FMZE ","M7N4MKXE ", & - "M7N4MKYE ","M7N4MKZE ","M7N4MMXE ","M7N4MMYE ","M7N4MMZE ","M7N4RAXE ","M7N4RAYE ", & - "M7N4RAZE ","M7N4RDXE ","M7N4RDYE ","M7N4RDZE ","M7N4TAXE ","M7N4TAYE ","M7N4TAZE ", & - "M7N4TDXSS","M7N4TDYSS","M7N4TDZSS","M7N5FKXE ","M7N5FKYE ","M7N5FKZE ","M7N5FMXE ", & - "M7N5FMYE ","M7N5FMZE ","M7N5MKXE ","M7N5MKYE ","M7N5MKZE ","M7N5MMXE ","M7N5MMYE ", & - "M7N5MMZE ","M7N5RAXE ","M7N5RAYE ","M7N5RAZE ","M7N5RDXE ","M7N5RDYE ","M7N5RDZE ", & - "M7N5TAXE ","M7N5TAYE ","M7N5TAZE ","M7N5TDXSS","M7N5TDYSS","M7N5TDZSS","M7N6FKXE ", & - "M7N6FKYE ","M7N6FKZE ","M7N6FMXE ","M7N6FMYE ","M7N6FMZE ","M7N6MKXE ","M7N6MKYE ", & - "M7N6MKZE ","M7N6MMXE ","M7N6MMYE ","M7N6MMZE ","M7N6RAXE ","M7N6RAYE ","M7N6RAZE ", & - "M7N6RDXE ","M7N6RDYE ","M7N6RDZE ","M7N6TAXE ","M7N6TAYE ","M7N6TAZE ","M7N6TDXSS", & - "M7N6TDYSS","M7N6TDZSS","M7N7FKXE ","M7N7FKYE ","M7N7FKZE ","M7N7FMXE ","M7N7FMYE ", & - "M7N7FMZE ","M7N7MKXE ","M7N7MKYE ","M7N7MKZE ","M7N7MMXE ","M7N7MMYE ","M7N7MMZE ", & - "M7N7RAXE ","M7N7RAYE ","M7N7RAZE ","M7N7RDXE ","M7N7RDYE ","M7N7RDZE ","M7N7TAXE ", & - "M7N7TAYE ","M7N7TAZE ","M7N7TDXSS","M7N7TDYSS","M7N7TDZSS","M7N8FKXE ","M7N8FKYE ", & - "M7N8FKZE ","M7N8FMXE ","M7N8FMYE ","M7N8FMZE ","M7N8MKXE ","M7N8MKYE ","M7N8MKZE ", & - "M7N8MMXE ","M7N8MMYE ","M7N8MMZE ","M7N8RAXE ","M7N8RAYE ","M7N8RAZE ","M7N8RDXE ", & - "M7N8RDYE ","M7N8RDZE ","M7N8TAXE ","M7N8TAYE ","M7N8TAZE ","M7N8TDXSS","M7N8TDYSS", & - "M7N8TDZSS","M7N9FKXE ","M7N9FKYE ","M7N9FKZE ","M7N9FMXE ","M7N9FMYE ","M7N9FMZE ", & - "M7N9MKXE ","M7N9MKYE ","M7N9MKZE ","M7N9MMXE ","M7N9MMYE ","M7N9MMZE ","M7N9RAXE ", & - "M7N9RAYE ","M7N9RAZE ","M7N9RDXE ","M7N9RDYE ","M7N9RDZE ","M7N9TAXE ","M7N9TAYE ", & - "M7N9TAZE ","M7N9TDXSS","M7N9TDYSS","M7N9TDZSS","M8N1FKXE ","M8N1FKYE ","M8N1FKZE ", & - "M8N1FMXE ","M8N1FMYE ","M8N1FMZE ","M8N1MKXE ","M8N1MKYE ","M8N1MKZE ","M8N1MMXE ", & - "M8N1MMYE ","M8N1MMZE ","M8N1RAXE ","M8N1RAYE ","M8N1RAZE ","M8N1RDXE ","M8N1RDYE ", & - "M8N1RDZE ","M8N1TAXE ","M8N1TAYE ","M8N1TAZE ","M8N1TDXSS","M8N1TDYSS","M8N1TDZSS", & - "M8N2FKXE ","M8N2FKYE ","M8N2FKZE ","M8N2FMXE ","M8N2FMYE ","M8N2FMZE ","M8N2MKXE ", & - "M8N2MKYE ","M8N2MKZE ","M8N2MMXE ","M8N2MMYE ","M8N2MMZE ","M8N2RAXE ","M8N2RAYE ", & - "M8N2RAZE ","M8N2RDXE ","M8N2RDYE ","M8N2RDZE ","M8N2TAXE ","M8N2TAYE ","M8N2TAZE ", & - "M8N2TDXSS","M8N2TDYSS","M8N2TDZSS","M8N3FKXE ","M8N3FKYE ","M8N3FKZE ","M8N3FMXE ", & - "M8N3FMYE ","M8N3FMZE ","M8N3MKXE ","M8N3MKYE ","M8N3MKZE ","M8N3MMXE ","M8N3MMYE ", & - "M8N3MMZE ","M8N3RAXE ","M8N3RAYE ","M8N3RAZE ","M8N3RDXE ","M8N3RDYE ","M8N3RDZE ", & - "M8N3TAXE ","M8N3TAYE ","M8N3TAZE ","M8N3TDXSS","M8N3TDYSS","M8N3TDZSS","M8N4FKXE ", & - "M8N4FKYE ","M8N4FKZE ","M8N4FMXE ","M8N4FMYE ","M8N4FMZE ","M8N4MKXE ","M8N4MKYE ", & - "M8N4MKZE ","M8N4MMXE ","M8N4MMYE ","M8N4MMZE ","M8N4RAXE ","M8N4RAYE ","M8N4RAZE ", & - "M8N4RDXE ","M8N4RDYE ","M8N4RDZE ","M8N4TAXE ","M8N4TAYE ","M8N4TAZE ","M8N4TDXSS", & - "M8N4TDYSS","M8N4TDZSS","M8N5FKXE ","M8N5FKYE ","M8N5FKZE ","M8N5FMXE ","M8N5FMYE ", & - "M8N5FMZE ","M8N5MKXE ","M8N5MKYE ","M8N5MKZE ","M8N5MMXE ","M8N5MMYE ","M8N5MMZE ", & - "M8N5RAXE ","M8N5RAYE ","M8N5RAZE ","M8N5RDXE ","M8N5RDYE ","M8N5RDZE ","M8N5TAXE ", & - "M8N5TAYE ","M8N5TAZE ","M8N5TDXSS","M8N5TDYSS","M8N5TDZSS","M8N6FKXE ","M8N6FKYE ", & - "M8N6FKZE ","M8N6FMXE ","M8N6FMYE ","M8N6FMZE ","M8N6MKXE ","M8N6MKYE ","M8N6MKZE ", & - "M8N6MMXE ","M8N6MMYE ","M8N6MMZE ","M8N6RAXE ","M8N6RAYE ","M8N6RAZE ","M8N6RDXE ", & - "M8N6RDYE ","M8N6RDZE ","M8N6TAXE ","M8N6TAYE ","M8N6TAZE ","M8N6TDXSS","M8N6TDYSS", & - "M8N6TDZSS","M8N7FKXE ","M8N7FKYE ","M8N7FKZE ","M8N7FMXE ","M8N7FMYE ","M8N7FMZE ", & - "M8N7MKXE ","M8N7MKYE ","M8N7MKZE ","M8N7MMXE ","M8N7MMYE ","M8N7MMZE ","M8N7RAXE ", & - "M8N7RAYE ","M8N7RAZE ","M8N7RDXE ","M8N7RDYE ","M8N7RDZE ","M8N7TAXE ","M8N7TAYE ", & - "M8N7TAZE ","M8N7TDXSS","M8N7TDYSS","M8N7TDZSS","M8N8FKXE ","M8N8FKYE ","M8N8FKZE ", & - "M8N8FMXE ","M8N8FMYE ","M8N8FMZE ","M8N8MKXE ","M8N8MKYE ","M8N8MKZE ","M8N8MMXE ", & - "M8N8MMYE ","M8N8MMZE ","M8N8RAXE ","M8N8RAYE ","M8N8RAZE ","M8N8RDXE ","M8N8RDYE ", & - "M8N8RDZE ","M8N8TAXE ","M8N8TAYE ","M8N8TAZE ","M8N8TDXSS","M8N8TDYSS","M8N8TDZSS", & - "M8N9FKXE ","M8N9FKYE ","M8N9FKZE ","M8N9FMXE ","M8N9FMYE ","M8N9FMZE ","M8N9MKXE ", & - "M8N9MKYE ","M8N9MKZE ","M8N9MMXE ","M8N9MMYE ","M8N9MMZE ","M8N9RAXE ","M8N9RAYE ", & - "M8N9RAZE ","M8N9RDXE ","M8N9RDYE ","M8N9RDZE ","M8N9TAXE ","M8N9TAYE ","M8N9TAZE ", & - "M8N9TDXSS","M8N9TDYSS","M8N9TDZSS","M9N1FKXE ","M9N1FKYE ","M9N1FKZE ","M9N1FMXE ", & - "M9N1FMYE ","M9N1FMZE ","M9N1MKXE ","M9N1MKYE ","M9N1MKZE ","M9N1MMXE ","M9N1MMYE ", & - "M9N1MMZE ","M9N1RAXE ","M9N1RAYE ","M9N1RAZE ","M9N1RDXE ","M9N1RDYE ","M9N1RDZE ", & - "M9N1TAXE ","M9N1TAYE ","M9N1TAZE ","M9N1TDXSS","M9N1TDYSS","M9N1TDZSS","M9N2FKXE ", & - "M9N2FKYE ","M9N2FKZE ","M9N2FMXE ","M9N2FMYE ","M9N2FMZE ","M9N2MKXE ","M9N2MKYE ", & - "M9N2MKZE ","M9N2MMXE ","M9N2MMYE ","M9N2MMZE ","M9N2RAXE ","M9N2RAYE ","M9N2RAZE ", & - "M9N2RDXE ","M9N2RDYE ","M9N2RDZE ","M9N2TAXE ","M9N2TAYE ","M9N2TAZE ","M9N2TDXSS", & - "M9N2TDYSS","M9N2TDZSS","M9N3FKXE ","M9N3FKYE ","M9N3FKZE ","M9N3FMXE ","M9N3FMYE ", & - "M9N3FMZE ","M9N3MKXE ","M9N3MKYE ","M9N3MKZE ","M9N3MMXE ","M9N3MMYE ","M9N3MMZE ", & - "M9N3RAXE ","M9N3RAYE ","M9N3RAZE ","M9N3RDXE ","M9N3RDYE ","M9N3RDZE ","M9N3TAXE ", & - "M9N3TAYE ","M9N3TAZE ","M9N3TDXSS","M9N3TDYSS","M9N3TDZSS","M9N4FKXE ","M9N4FKYE ", & - "M9N4FKZE ","M9N4FMXE ","M9N4FMYE ","M9N4FMZE ","M9N4MKXE ","M9N4MKYE ","M9N4MKZE ", & - "M9N4MMXE ","M9N4MMYE ","M9N4MMZE ","M9N4RAXE ","M9N4RAYE ","M9N4RAZE ","M9N4RDXE ", & - "M9N4RDYE ","M9N4RDZE ","M9N4TAXE ","M9N4TAYE ","M9N4TAZE ","M9N4TDXSS","M9N4TDYSS", & - "M9N4TDZSS","M9N5FKXE ","M9N5FKYE ","M9N5FKZE ","M9N5FMXE ","M9N5FMYE ","M9N5FMZE ", & - "M9N5MKXE ","M9N5MKYE ","M9N5MKZE ","M9N5MMXE ","M9N5MMYE ","M9N5MMZE ","M9N5RAXE ", & - "M9N5RAYE ","M9N5RAZE ","M9N5RDXE ","M9N5RDYE ","M9N5RDZE ","M9N5TAXE ","M9N5TAYE ", & - "M9N5TAZE ","M9N5TDXSS","M9N5TDYSS","M9N5TDZSS","M9N6FKXE ","M9N6FKYE ","M9N6FKZE ", & - "M9N6FMXE ","M9N6FMYE ","M9N6FMZE ","M9N6MKXE ","M9N6MKYE ","M9N6MKZE ","M9N6MMXE ", & - "M9N6MMYE ","M9N6MMZE ","M9N6RAXE ","M9N6RAYE ","M9N6RAZE ","M9N6RDXE ","M9N6RDYE ", & - "M9N6RDZE ","M9N6TAXE ","M9N6TAYE ","M9N6TAZE ","M9N6TDXSS","M9N6TDYSS","M9N6TDZSS", & - "M9N7FKXE ","M9N7FKYE ","M9N7FKZE ","M9N7FMXE ","M9N7FMYE ","M9N7FMZE ","M9N7MKXE ", & - "M9N7MKYE ","M9N7MKZE ","M9N7MMXE ","M9N7MMYE ","M9N7MMZE ","M9N7RAXE ","M9N7RAYE ", & - "M9N7RAZE ","M9N7RDXE ","M9N7RDYE ","M9N7RDZE ","M9N7TAXE ","M9N7TAYE ","M9N7TAZE ", & - "M9N7TDXSS","M9N7TDYSS","M9N7TDZSS","M9N8FKXE ","M9N8FKYE ","M9N8FKZE ","M9N8FMXE ", & - "M9N8FMYE ","M9N8FMZE ","M9N8MKXE ","M9N8MKYE ","M9N8MKZE ","M9N8MMXE ","M9N8MMYE ", & - "M9N8MMZE ","M9N8RAXE ","M9N8RAYE ","M9N8RAZE ","M9N8RDXE ","M9N8RDYE ","M9N8RDZE ", & - "M9N8TAXE ","M9N8TAYE ","M9N8TAZE ","M9N8TDXSS","M9N8TDYSS","M9N8TDZSS","M9N9FKXE ", & - "M9N9FKYE ","M9N9FKZE ","M9N9FMXE ","M9N9FMYE ","M9N9FMZE ","M9N9MKXE ","M9N9MKYE ", & - "M9N9MKZE ","M9N9MMXE ","M9N9MMYE ","M9N9MMZE ","M9N9RAXE ","M9N9RAYE ","M9N9RAZE ", & - "M9N9RDXE ","M9N9RDYE ","M9N9RDZE ","M9N9TAXE ","M9N9TAYE ","M9N9TAZE ","M9N9TDXSS", & - "M9N9TDYSS","M9N9TDZSS","REACTFXSS","REACTFYSS","REACTFZSS","REACTMXSS","REACTMYSS", & - "REACTMZSS","SSQM01 ","SSQM02 ","SSQM03 ","SSQM04 ","SSQM05 ","SSQM06 ", & - "SSQM07 ","SSQM08 ","SSQM09 ","SSQM10 ","SSQM11 ","SSQM12 ","SSQM13 ", & - "SSQM14 ","SSQM15 ","SSQM16 ","SSQM17 ","SSQM18 ","SSQM19 ","SSQM20 ", & - "SSQM21 ","SSQM22 ","SSQM23 ","SSQM24 ","SSQM25 ","SSQM26 ","SSQM27 ", & - "SSQM28 ","SSQM29 ","SSQM30 ","SSQM31 ","SSQM32 ","SSQM33 ","SSQM34 ", & - "SSQM35 ","SSQM36 ","SSQM37 ","SSQM38 ","SSQM39 ","SSQM40 ","SSQM41 ", & - "SSQM42 ","SSQM43 ","SSQM44 ","SSQM45 ","SSQM46 ","SSQM47 ","SSQM48 ", & - "SSQM49 ","SSQM50 ","SSQM51 ","SSQM52 ","SSQM53 ","SSQM54 ","SSQM55 ", & - "SSQM56 ","SSQM57 ","SSQM58 ","SSQM59 ","SSQM60 ","SSQM61 ","SSQM62 ", & - "SSQM63 ","SSQM64 ","SSQM65 ","SSQM66 ","SSQM67 ","SSQM68 ","SSQM69 ", & - "SSQM70 ","SSQM71 ","SSQM72 ","SSQM73 ","SSQM74 ","SSQM75 ","SSQM76 ", & - "SSQM77 ","SSQM78 ","SSQM79 ","SSQM80 ","SSQM81 ","SSQM82 ","SSQM83 ", & - "SSQM84 ","SSQM85 ","SSQM86 ","SSQM87 ","SSQM88 ","SSQM89 ","SSQM90 ", & - "SSQM91 ","SSQM92 ","SSQM93 ","SSQM94 ","SSQM95 ","SSQM96 ","SSQM97 ", & - "SSQM98 ","SSQM99 ","SSQMD01 ","SSQMD02 ","SSQMD03 ","SSQMD04 ","SSQMD05 ", & - "SSQMD06 ","SSQMD07 ","SSQMD08 ","SSQMD09 ","SSQMD10 ","SSQMD11 ","SSQMD12 ", & - "SSQMD13 ","SSQMD14 ","SSQMD15 ","SSQMD16 ","SSQMD17 ","SSQMD18 ","SSQMD19 ", & - "SSQMD20 ","SSQMD21 ","SSQMD22 ","SSQMD23 ","SSQMD24 ","SSQMD25 ","SSQMD26 ", & - "SSQMD27 ","SSQMD28 ","SSQMD29 ","SSQMD30 ","SSQMD31 ","SSQMD32 ","SSQMD33 ", & - "SSQMD34 ","SSQMD35 ","SSQMD36 ","SSQMD37 ","SSQMD38 ","SSQMD39 ","SSQMD40 ", & - "SSQMD41 ","SSQMD42 ","SSQMD43 ","SSQMD44 ","SSQMD45 ","SSQMD46 ","SSQMD47 ", & - "SSQMD48 ","SSQMD49 ","SSQMD50 ","SSQMD51 ","SSQMD52 ","SSQMD53 ","SSQMD54 ", & - "SSQMD55 ","SSQMD56 ","SSQMD57 ","SSQMD58 ","SSQMD59 ","SSQMD60 ","SSQMD61 ", & - "SSQMD62 ","SSQMD63 ","SSQMD64 ","SSQMD65 ","SSQMD66 ","SSQMD67 ","SSQMD68 ", & - "SSQMD69 ","SSQMD70 ","SSQMD71 ","SSQMD72 ","SSQMD73 ","SSQMD74 ","SSQMD75 ", & - "SSQMD76 ","SSQMD77 ","SSQMD78 ","SSQMD79 ","SSQMD80 ","SSQMD81 ","SSQMD82 ", & - "SSQMD83 ","SSQMD84 ","SSQMD85 ","SSQMD86 ","SSQMD87 ","SSQMD88 ","SSQMD89 ", & - "SSQMD90 ","SSQMD91 ","SSQMD92 ","SSQMD93 ","SSQMD94 ","SSQMD95 ","SSQMD96 ", & - "SSQMD97 ","SSQMD98 ","SSQMD99 ","SSQMDD01 ","SSQMDD02 ","SSQMDD03 ","SSQMDD04 ", & - "SSQMDD05 ","SSQMDD06 ","SSQMDD07 ","SSQMDD08 ","SSQMDD09 ","SSQMDD10 ","SSQMDD11 ", & - "SSQMDD12 ","SSQMDD13 ","SSQMDD14 ","SSQMDD15 ","SSQMDD16 ","SSQMDD17 ","SSQMDD18 ", & - "SSQMDD19 ","SSQMDD20 ","SSQMDD21 ","SSQMDD22 ","SSQMDD23 ","SSQMDD24 ","SSQMDD25 ", & - "SSQMDD26 ","SSQMDD27 ","SSQMDD28 ","SSQMDD29 ","SSQMDD30 ","SSQMDD31 ","SSQMDD32 ", & - "SSQMDD33 ","SSQMDD34 ","SSQMDD35 ","SSQMDD36 ","SSQMDD37 ","SSQMDD38 ","SSQMDD39 ", & - "SSQMDD40 ","SSQMDD41 ","SSQMDD42 ","SSQMDD43 ","SSQMDD44 ","SSQMDD45 ","SSQMDD46 ", & - "SSQMDD47 ","SSQMDD48 ","SSQMDD49 ","SSQMDD50 ","SSQMDD51 ","SSQMDD52 ","SSQMDD53 ", & - "SSQMDD54 ","SSQMDD55 ","SSQMDD56 ","SSQMDD57 ","SSQMDD58 ","SSQMDD59 ","SSQMDD60 ", & - "SSQMDD61 ","SSQMDD62 ","SSQMDD63 ","SSQMDD64 ","SSQMDD65 ","SSQMDD66 ","SSQMDD67 ", & - "SSQMDD68 ","SSQMDD69 ","SSQMDD70 ","SSQMDD71 ","SSQMDD72 ","SSQMDD73 ","SSQMDD74 ", & - "SSQMDD75 ","SSQMDD76 ","SSQMDD77 ","SSQMDD78 ","SSQMDD79 ","SSQMDD80 ","SSQMDD81 ", & - "SSQMDD82 ","SSQMDD83 ","SSQMDD84 ","SSQMDD85 ","SSQMDD86 ","SSQMDD87 ","SSQMDD88 ", & - "SSQMDD89 ","SSQMDD90 ","SSQMDD91 ","SSQMDD92 ","SSQMDD93 ","SSQMDD94 ","SSQMDD95 ", & - "SSQMDD96 ","SSQMDD97 ","SSQMDD98 ","SSQMDD99 "/) - INTEGER(IntKi), PARAMETER :: ParamIndxAry(2265) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) - IntfFXss , IntfFYss , IntfFZss , IntfMXss , IntfMYss , IntfMZss , IntfRAXss , & - IntfRAYss , IntfRAZss , IntfRDXss , IntfRDYss , IntfRDZss , IntfTAXss , IntfTAYss , & - IntfTAZss , IntfTDXss , IntfTDYss , IntfTDZss , M1N1FKxe , M1N1FKye , M1N1FKze , & - M1N1FMxe , M1N1FMye , M1N1FMze , M1N1MKxe , M1N1MKye , M1N1MKze , M1N1MMxe , & - M1N1MMye , M1N1MMze , M1N1RAxe , M1N1RAye , M1N1RAze , M1N1RDxe , M1N1RDye , & - M1N1RDze , M1N1TAxe , M1N1TAye , M1N1TAze , M1N1TDxss , M1N1TDyss , M1N1TDzss , & - M1N2FKxe , M1N2FKye , M1N2FKze , M1N2FMxe , M1N2FMye , M1N2FMze , M1N2MKxe , & - M1N2MKye , M1N2MKze , M1N2MMxe , M1N2MMye , M1N2MMze , M1N2RAxe , M1N2RAye , & - M1N2RAze , M1N2RDxe , M1N2RDye , M1N2RDze , M1N2TAxe , M1N2TAye , M1N2TAze , & - M1N2TDxss , M1N2TDyss , M1N2TDzss , M1N3FKxe , M1N3FKye , M1N3FKze , M1N3FMxe , & - M1N3FMye , M1N3FMze , M1N3MKxe , M1N3MKye , M1N3MKze , M1N3MMxe , M1N3MMye , & - M1N3MMze , M1N3RAxe , M1N3RAye , M1N3RAze , M1N3RDxe , M1N3RDye , M1N3RDze , & - M1N3TAxe , M1N3TAye , M1N3TAze , M1N3TDxss , M1N3TDyss , M1N3TDzss , M1N4FKxe , & - M1N4FKye , M1N4FKze , M1N4FMxe , M1N4FMye , M1N4FMze , M1N4MKxe , M1N4MKye , & - M1N4MKze , M1N4MMxe , M1N4MMye , M1N4MMze , M1N4RAxe , M1N4RAye , M1N4RAze , & - M1N4RDxe , M1N4RDye , M1N4RDze , M1N4TAxe , M1N4TAye , M1N4TAze , M1N4TDxss , & - M1N4TDyss , M1N4TDzss , M1N5FKxe , M1N5FKye , M1N5FKze , M1N5FMxe , M1N5FMye , & - M1N5FMze , M1N5MKxe , M1N5MKye , M1N5MKze , M1N5MMxe , M1N5MMye , M1N5MMze , & - M1N5RAxe , M1N5RAye , M1N5RAze , M1N5RDxe , M1N5RDye , M1N5RDze , M1N5TAxe , & - M1N5TAye , M1N5TAze , M1N5TDxss , M1N5TDyss , M1N5TDzss , M1N6FKxe , M1N6FKye , & - M1N6FKze , M1N6FMxe , M1N6FMye , M1N6FMze , M1N6MKxe , M1N6MKye , M1N6MKze , & - M1N6MMxe , M1N6MMye , M1N6MMze , M1N6RAxe , M1N6RAye , M1N6RAze , M1N6RDxe , & - M1N6RDye , M1N6RDze , M1N6TAxe , M1N6TAye , M1N6TAze , M1N6TDxss , M1N6TDyss , & - M1N6TDzss , M1N7FKxe , M1N7FKye , M1N7FKze , M1N7FMxe , M1N7FMye , M1N7FMze , & - M1N7MKxe , M1N7MKye , M1N7MKze , M1N7MMxe , M1N7MMye , M1N7MMze , M1N7RAxe , & - M1N7RAye , M1N7RAze , M1N7RDxe , M1N7RDye , M1N7RDze , M1N7TAxe , M1N7TAye , & - M1N7TAze , M1N7TDxss , M1N7TDyss , M1N7TDzss , M1N8FKxe , M1N8FKye , M1N8FKze , & - M1N8FMxe , M1N8FMye , M1N8FMze , M1N8MKxe , M1N8MKye , M1N8MKze , M1N8MMxe , & - M1N8MMye , M1N8MMze , M1N8RAxe , M1N8RAye , M1N8RAze , M1N8RDxe , M1N8RDye , & - M1N8RDze , M1N8TAxe , M1N8TAye , M1N8TAze , M1N8TDxss , M1N8TDyss , M1N8TDzss , & - M1N9FKxe , M1N9FKye , M1N9FKze , M1N9FMxe , M1N9FMye , M1N9FMze , M1N9MKxe , & - M1N9MKye , M1N9MKze , M1N9MMxe , M1N9MMye , M1N9MMze , M1N9RAxe , M1N9RAye , & - M1N9RAze , M1N9RDxe , M1N9RDye , M1N9RDze , M1N9TAxe , M1N9TAye , M1N9TAze , & - M1N9TDxss , M1N9TDyss , M1N9TDzss , M2N1FKxe , M2N1FKye , M2N1FKze , M2N1FMxe , & - M2N1FMye , M2N1FMze , M2N1MKxe , M2N1MKye , M2N1MKze , M2N1MMxe , M2N1MMye , & - M2N1MMze , M2N1RAxe , M2N1RAye , M2N1RAze , M2N1RDxe , M2N1RDye , M2N1RDze , & - M2N1TAxe , M2N1TAye , M2N1TAze , M2N1TDxss , M2N1TDyss , M2N1TDzss , M2N2FKxe , & - M2N2FKye , M2N2FKze , M2N2FMxe , M2N2FMye , M2N2FMze , M2N2MKxe , M2N2MKye , & - M2N2MKze , M2N2MMxe , M2N2MMye , M2N2MMze , M2N2RAxe , M2N2RAye , M2N2RAze , & - M2N2RDxe , M2N2RDye , M2N2RDze , M2N2TAxe , M2N2TAye , M2N2TAze , M2N2TDxss , & - M2N2TDyss , M2N2TDzss , M2N3FKxe , M2N3FKye , M2N3FKze , M2N3FMxe , M2N3FMye , & - M2N3FMze , M2N3MKxe , M2N3MKye , M2N3MKze , M2N3MMxe , M2N3MMye , M2N3MMze , & - M2N3RAxe , M2N3RAye , M2N3RAze , M2N3RDxe , M2N3RDye , M2N3RDze , M2N3TAxe , & - M2N3TAye , M2N3TAze , M2N3TDxss , M2N3TDyss , M2N3TDzss , M2N4FKxe , M2N4FKye , & - M2N4FKze , M2N4FMxe , M2N4FMye , M2N4FMze , M2N4MKxe , M2N4MKye , M2N4MKze , & - M2N4MMxe , M2N4MMye , M2N4MMze , M2N4RAxe , M2N4RAye , M2N4RAze , M2N4RDxe , & - M2N4RDye , M2N4RDze , M2N4TAxe , M2N4TAye , M2N4TAze , M2N4TDxss , M2N4TDyss , & - M2N4TDzss , M2N5FKxe , M2N5FKye , M2N5FKze , M2N5FMxe , M2N5FMye , M2N5FMze , & - M2N5MKxe , M2N5MKye , M2N5MKze , M2N5MMxe , M2N5MMye , M2N5MMze , M2N5RAxe , & - M2N5RAye , M2N5RAze , M2N5RDxe , M2N5RDye , M2N5RDze , M2N5TAxe , M2N5TAye , & - M2N5TAze , M2N5TDxss , M2N5TDyss , M2N5TDzss , M2N6FKxe , M2N6FKye , M2N6FKze , & - M2N6FMxe , M2N6FMye , M2N6FMze , M2N6MKxe , M2N6MKye , M2N6MKze , M2N6MMxe , & - M2N6MMye , M2N6MMze , M2N6RAxe , M2N6RAye , M2N6RAze , M2N6RDxe , M2N6RDye , & - M2N6RDze , M2N6TAxe , M2N6TAye , M2N6TAze , M2N6TDxss , M2N6TDyss , M2N6TDzss , & - M2N7FKxe , M2N7FKye , M2N7FKze , M2N7FMxe , M2N7FMye , M2N7FMze , M2N7MKxe , & - M2N7MKye , M2N7MKze , M2N7MMxe , M2N7MMye , M2N7MMze , M2N7RAxe , M2N7RAye , & - M2N7RAze , M2N7RDxe , M2N7RDye , M2N7RDze , M2N7TAxe , M2N7TAye , M2N7TAze , & - M2N7TDxss , M2N7TDyss , M2N7TDzss , M2N8FKxe , M2N8FKye , M2N8FKze , M2N8FMxe , & - M2N8FMye , M2N8FMze , M2N8MKxe , M2N8MKye , M2N8MKze , M2N8MMxe , M2N8MMye , & - M2N8MMze , M2N8RAxe , M2N8RAye , M2N8RAze , M2N8RDxe , M2N8RDye , M2N8RDze , & - M2N8TAxe , M2N8TAye , M2N8TAze , M2N8TDxss , M2N8TDyss , M2N8TDzss , M2N9FKxe , & - M2N9FKye , M2N9FKze , M2N9FMxe , M2N9FMye , M2N9FMze , M2N9MKxe , M2N9MKye , & - M2N9MKze , M2N9MMxe , M2N9MMye , M2N9MMze , M2N9RAxe , M2N9RAye , M2N9RAze , & - M2N9RDxe , M2N9RDye , M2N9RDze , M2N9TAxe , M2N9TAye , M2N9TAze , M2N9TDxss , & - M2N9TDyss , M2N9TDzss , M3N1FKxe , M3N1FKye , M3N1FKze , M3N1FMxe , M3N1FMye , & - M3N1FMze , M3N1MKxe , M3N1MKye , M3N1MKze , M3N1MMxe , M3N1MMye , M3N1MMze , & - M3N1RAxe , M3N1RAye , M3N1RAze , M3N1RDxe , M3N1RDye , M3N1RDze , M3N1TAxe , & - M3N1TAye , M3N1TAze , M3N1TDxss , M3N1TDyss , M3N1TDzss , M3N2FKxe , M3N2FKye , & - M3N2FKze , M3N2FMxe , M3N2FMye , M3N2FMze , M3N2MKxe , M3N2MKye , M3N2MKze , & - M3N2MMxe , M3N2MMye , M3N2MMze , M3N2RAxe , M3N2RAye , M3N2RAze , M3N2RDxe , & - M3N2RDye , M3N2RDze , M3N2TAxe , M3N2TAye , M3N2TAze , M3N2TDxss , M3N2TDyss , & - M3N2TDzss , M3N3FKxe , M3N3FKye , M3N3FKze , M3N3FMxe , M3N3FMye , M3N3FMze , & - M3N3MKxe , M3N3MKye , M3N3MKze , M3N3MMxe , M3N3MMye , M3N3MMze , M3N3RAxe , & - M3N3RAye , M3N3RAze , M3N3RDxe , M3N3RDye , M3N3RDze , M3N3TAxe , M3N3TAye , & - M3N3TAze , M3N3TDxss , M3N3TDyss , M3N3TDzss , M3N4FKxe , M3N4FKye , M3N4FKze , & - M3N4FMxe , M3N4FMye , M3N4FMze , M3N4MKxe , M3N4MKye , M3N4MKze , M3N4MMxe , & - M3N4MMye , M3N4MMze , M3N4RAxe , M3N4RAye , M3N4RAze , M3N4RDxe , M3N4RDye , & - M3N4RDze , M3N4TAxe , M3N4TAye , M3N4TAze , M3N4TDxss , M3N4TDyss , M3N4TDzss , & - M3N5FKxe , M3N5FKye , M3N5FKze , M3N5FMxe , M3N5FMye , M3N5FMze , M3N5MKxe , & - M3N5MKye , M3N5MKze , M3N5MMxe , M3N5MMye , M3N5MMze , M3N5RAxe , M3N5RAye , & - M3N5RAze , M3N5RDxe , M3N5RDye , M3N5RDze , M3N5TAxe , M3N5TAye , M3N5TAze , & - M3N5TDxss , M3N5TDyss , M3N5TDzss , M3N6FKxe , M3N6FKye , M3N6FKze , M3N6FMxe , & - M3N6FMye , M3N6FMze , M3N6MKxe , M3N6MKye , M3N6MKze , M3N6MMxe , M3N6MMye , & - M3N6MMze , M3N6RAxe , M3N6RAye , M3N6RAze , M3N6RDxe , M3N6RDye , M3N6RDze , & - M3N6TAxe , M3N6TAye , M3N6TAze , M3N6TDxss , M3N6TDyss , M3N6TDzss , M3N7FKxe , & - M3N7FKye , M3N7FKze , M3N7FMxe , M3N7FMye , M3N7FMze , M3N7MKxe , M3N7MKye , & - M3N7MKze , M3N7MMxe , M3N7MMye , M3N7MMze , M3N7RAxe , M3N7RAye , M3N7RAze , & - M3N7RDxe , M3N7RDye , M3N7RDze , M3N7TAxe , M3N7TAye , M3N7TAze , M3N7TDxss , & - M3N7TDyss , M3N7TDzss , M3N8FKxe , M3N8FKye , M3N8FKze , M3N8FMxe , M3N8FMye , & - M3N8FMze , M3N8MKxe , M3N8MKye , M3N8MKze , M3N8MMxe , M3N8MMye , M3N8MMze , & - M3N8RAxe , M3N8RAye , M3N8RAze , M3N8RDxe , M3N8RDye , M3N8RDze , M3N8TAxe , & - M3N8TAye , M3N8TAze , M3N8TDxss , M3N8TDyss , M3N8TDzss , M3N9FKxe , M3N9FKye , & - M3N9FKze , M3N9FMxe , M3N9FMye , M3N9FMze , M3N9MKxe , M3N9MKye , M3N9MKze , & - M3N9MMxe , M3N9MMye , M3N9MMze , M3N9RAxe , M3N9RAye , M3N9RAze , M3N9RDxe , & - M3N9RDye , M3N9RDze , M3N9TAxe , M3N9TAye , M3N9TAze , M3N9TDxss , M3N9TDyss , & - M3N9TDzss , M4N1FKxe , M4N1FKye , M4N1FKze , M4N1FMxe , M4N1FMye , M4N1FMze , & - M4N1MKxe , M4N1MKye , M4N1MKze , M4N1MMxe , M4N1MMye , M4N1MMze , M4N1RAxe , & - M4N1RAye , M4N1RAze , M4N1RDxe , M4N1RDye , M4N1RDze , M4N1TAxe , M4N1TAye , & - M4N1TAze , M4N1TDxss , M4N1TDyss , M4N1TDzss , M4N2FKxe , M4N2FKye , M4N2FKze , & - M4N2FMxe , M4N2FMye , M4N2FMze , M4N2MKxe , M4N2MKye , M4N2MKze , M4N2MMxe , & - M4N2MMye , M4N2MMze , M4N2RAxe , M4N2RAye , M4N2RAze , M4N2RDxe , M4N2RDye , & - M4N2RDze , M4N2TAxe , M4N2TAye , M4N2TAze , M4N2TDxss , M4N2TDyss , M4N2TDzss , & - M4N3FKxe , M4N3FKye , M4N3FKze , M4N3FMxe , M4N3FMye , M4N3FMze , M4N3MKxe , & - M4N3MKye , M4N3MKze , M4N3MMxe , M4N3MMye , M4N3MMze , M4N3RAxe , M4N3RAye , & - M4N3RAze , M4N3RDxe , M4N3RDye , M4N3RDze , M4N3TAxe , M4N3TAye , M4N3TAze , & - M4N3TDxss , M4N3TDyss , M4N3TDzss , M4N4FKxe , M4N4FKye , M4N4FKze , M4N4FMxe , & - M4N4FMye , M4N4FMze , M4N4MKxe , M4N4MKye , M4N4MKze , M4N4MMxe , M4N4MMye , & - M4N4MMze , M4N4RAxe , M4N4RAye , M4N4RAze , M4N4RDxe , M4N4RDye , M4N4RDze , & - M4N4TAxe , M4N4TAye , M4N4TAze , M4N4TDxss , M4N4TDyss , M4N4TDzss , M4N5FKxe , & - M4N5FKye , M4N5FKze , M4N5FMxe , M4N5FMye , M4N5FMze , M4N5MKxe , M4N5MKye , & - M4N5MKze , M4N5MMxe , M4N5MMye , M4N5MMze , M4N5RAxe , M4N5RAye , M4N5RAze , & - M4N5RDxe , M4N5RDye , M4N5RDze , M4N5TAxe , M4N5TAye , M4N5TAze , M4N5TDxss , & - M4N5TDyss , M4N5TDzss , M4N6FKxe , M4N6FKye , M4N6FKze , M4N6FMxe , M4N6FMye , & - M4N6FMze , M4N6MKxe , M4N6MKye , M4N6MKze , M4N6MMxe , M4N6MMye , M4N6MMze , & - M4N6RAxe , M4N6RAye , M4N6RAze , M4N6RDxe , M4N6RDye , M4N6RDze , M4N6TAxe , & - M4N6TAye , M4N6TAze , M4N6TDxss , M4N6TDyss , M4N6TDzss , M4N7FKxe , M4N7FKye , & - M4N7FKze , M4N7FMxe , M4N7FMye , M4N7FMze , M4N7MKxe , M4N7MKye , M4N7MKze , & - M4N7MMxe , M4N7MMye , M4N7MMze , M4N7RAxe , M4N7RAye , M4N7RAze , M4N7RDxe , & - M4N7RDye , M4N7RDze , M4N7TAxe , M4N7TAye , M4N7TAze , M4N7TDxss , M4N7TDyss , & - M4N7TDzss , M4N8FKxe , M4N8FKye , M4N8FKze , M4N8FMxe , M4N8FMye , M4N8FMze , & - M4N8MKxe , M4N8MKye , M4N8MKze , M4N8MMxe , M4N8MMye , M4N8MMze , M4N8RAxe , & - M4N8RAye , M4N8RAze , M4N8RDxe , M4N8RDye , M4N8RDze , M4N8TAxe , M4N8TAye , & - M4N8TAze , M4N8TDxss , M4N8TDyss , M4N8TDzss , M4N9FKxe , M4N9FKye , M4N9FKze , & - M4N9FMxe , M4N9FMye , M4N9FMze , M4N9MKxe , M4N9MKye , M4N9MKze , M4N9MMxe , & - M4N9MMye , M4N9MMze , M4N9RAxe , M4N9RAye , M4N9RAze , M4N9RDxe , M4N9RDye , & - M4N9RDze , M4N9TAxe , M4N9TAye , M4N9TAze , M4N9TDxss , M4N9TDyss , M4N9TDzss , & - M5N1FKxe , M5N1FKye , M5N1FKze , M5N1FMxe , M5N1FMye , M5N1FMze , M5N1MKxe , & - M5N1MKye , M5N1MKze , M5N1MMxe , M5N1MMye , M5N1MMze , M5N1RAxe , M5N1RAye , & - M5N1RAze , M5N1RDxe , M5N1RDye , M5N1RDze , M5N1TAxe , M5N1TAye , M5N1TAze , & - M5N1TDxss , M5N1TDyss , M5N1TDzss , M5N2FKxe , M5N2FKye , M5N2FKze , M5N2FMxe , & - M5N2FMye , M5N2FMze , M5N2MKxe , M5N2MKye , M5N2MKze , M5N2MMxe , M5N2MMye , & - M5N2MMze , M5N2RAxe , M5N2RAye , M5N2RAze , M5N2RDxe , M5N2RDye , M5N2RDze , & - M5N2TAxe , M5N2TAye , M5N2TAze , M5N2TDxss , M5N2TDyss , M5N2TDzss , M5N3FKxe , & - M5N3FKye , M5N3FKze , M5N3FMxe , M5N3FMye , M5N3FMze , M5N3MKxe , M5N3MKye , & - M5N3MKze , M5N3MMxe , M5N3MMye , M5N3MMze , M5N3RAxe , M5N3RAye , M5N3RAze , & - M5N3RDxe , M5N3RDye , M5N3RDze , M5N3TAxe , M5N3TAye , M5N3TAze , M5N3TDxss , & - M5N3TDyss , M5N3TDzss , M5N4FKxe , M5N4FKye , M5N4FKze , M5N4FMxe , M5N4FMye , & - M5N4FMze , M5N4MKxe , M5N4MKye , M5N4MKze , M5N4MMxe , M5N4MMye , M5N4MMze , & - M5N4RAxe , M5N4RAye , M5N4RAze , M5N4RDxe , M5N4RDye , M5N4RDze , M5N4TAxe , & - M5N4TAye , M5N4TAze , M5N4TDxss , M5N4TDyss , M5N4TDzss , M5N5FKxe , M5N5FKye , & - M5N5FKze , M5N5FMxe , M5N5FMye , M5N5FMze , M5N5MKxe , M5N5MKye , M5N5MKze , & - M5N5MMxe , M5N5MMye , M5N5MMze , M5N5RAxe , M5N5RAye , M5N5RAze , M5N5RDxe , & - M5N5RDye , M5N5RDze , M5N5TAxe , M5N5TAye , M5N5TAze , M5N5TDxss , M5N5TDyss , & - M5N5TDzss , M5N6FKxe , M5N6FKye , M5N6FKze , M5N6FMxe , M5N6FMye , M5N6FMze , & - M5N6MKxe , M5N6MKye , M5N6MKze , M5N6MMxe , M5N6MMye , M5N6MMze , M5N6RAxe , & - M5N6RAye , M5N6RAze , M5N6RDxe , M5N6RDye , M5N6RDze , M5N6TAxe , M5N6TAye , & - M5N6TAze , M5N6TDxss , M5N6TDyss , M5N6TDzss , M5N7FKxe , M5N7FKye , M5N7FKze , & - M5N7FMxe , M5N7FMye , M5N7FMze , M5N7MKxe , M5N7MKye , M5N7MKze , M5N7MMxe , & - M5N7MMye , M5N7MMze , M5N7RAxe , M5N7RAye , M5N7RAze , M5N7RDxe , M5N7RDye , & - M5N7RDze , M5N7TAxe , M5N7TAye , M5N7TAze , M5N7TDxss , M5N7TDyss , M5N7TDzss , & - M5N8FKxe , M5N8FKye , M5N8FKze , M5N8FMxe , M5N8FMye , M5N8FMze , M5N8MKxe , & - M5N8MKye , M5N8MKze , M5N8MMxe , M5N8MMye , M5N8MMze , M5N8RAxe , M5N8RAye , & - M5N8RAze , M5N8RDxe , M5N8RDye , M5N8RDze , M5N8TAxe , M5N8TAye , M5N8TAze , & - M5N8TDxss , M5N8TDyss , M5N8TDzss , M5N9FKxe , M5N9FKye , M5N9FKze , M5N9FMxe , & - M5N9FMye , M5N9FMze , M5N9MKxe , M5N9MKye , M5N9MKze , M5N9MMxe , M5N9MMye , & - M5N9MMze , M5N9RAxe , M5N9RAye , M5N9RAze , M5N9RDxe , M5N9RDye , M5N9RDze , & - M5N9TAxe , M5N9TAye , M5N9TAze , M5N9TDxss , M5N9TDyss , M5N9TDzss , M6N1FKxe , & - M6N1FKye , M6N1FKze , M6N1FMxe , M6N1FMye , M6N1FMze , M6N1MKxe , M6N1MKye , & - M6N1MKze , M6N1MMxe , M6N1MMye , M6N1MMze , M6N1RAxe , M6N1RAye , M6N1RAze , & - M6N1RDxe , M6N1RDye , M6N1RDze , M6N1TAxe , M6N1TAye , M6N1TAze , M6N1TDxss , & - M6N1TDyss , M6N1TDzss , M6N2FKxe , M6N2FKye , M6N2FKze , M6N2FMxe , M6N2FMye , & - M6N2FMze , M6N2MKxe , M6N2MKye , M6N2MKze , M6N2MMxe , M6N2MMye , M6N2MMze , & - M6N2RAxe , M6N2RAye , M6N2RAze , M6N2RDxe , M6N2RDye , M6N2RDze , M6N2TAxe , & - M6N2TAye , M6N2TAze , M6N2TDxss , M6N2TDyss , M6N2TDzss , M6N3FKxe , M6N3FKye , & - M6N3FKze , M6N3FMxe , M6N3FMye , M6N3FMze , M6N3MKxe , M6N3MKye , M6N3MKze , & - M6N3MMxe , M6N3MMye , M6N3MMze , M6N3RAxe , M6N3RAye , M6N3RAze , M6N3RDxe , & - M6N3RDye , M6N3RDze , M6N3TAxe , M6N3TAye , M6N3TAze , M6N3TDxss , M6N3TDyss , & - M6N3TDzss , M6N4FKxe , M6N4FKye , M6N4FKze , M6N4FMxe , M6N4FMye , M6N4FMze , & - M6N4MKxe , M6N4MKye , M6N4MKze , M6N4MMxe , M6N4MMye , M6N4MMze , M6N4RAxe , & - M6N4RAye , M6N4RAze , M6N4RDxe , M6N4RDye , M6N4RDze , M6N4TAxe , M6N4TAye , & - M6N4TAze , M6N4TDxss , M6N4TDyss , M6N4TDzss , M6N5FKxe , M6N5FKye , M6N5FKze , & - M6N5FMxe , M6N5FMye , M6N5FMze , M6N5MKxe , M6N5MKye , M6N5MKze , M6N5MMxe , & - M6N5MMye , M6N5MMze , M6N5RAxe , M6N5RAye , M6N5RAze , M6N5RDxe , M6N5RDye , & - M6N5RDze , M6N5TAxe , M6N5TAye , M6N5TAze , M6N5TDxss , M6N5TDyss , M6N5TDzss , & - M6N6FKxe , M6N6FKye , M6N6FKze , M6N6FMxe , M6N6FMye , M6N6FMze , M6N6MKxe , & - M6N6MKye , M6N6MKze , M6N6MMxe , M6N6MMye , M6N6MMze , M6N6RAxe , M6N6RAye , & - M6N6RAze , M6N6RDxe , M6N6RDye , M6N6RDze , M6N6TAxe , M6N6TAye , M6N6TAze , & - M6N6TDxss , M6N6TDyss , M6N6TDzss , M6N7FKxe , M6N7FKye , M6N7FKze , M6N7FMxe , & - M6N7FMye , M6N7FMze , M6N7MKxe , M6N7MKye , M6N7MKze , M6N7MMxe , M6N7MMye , & - M6N7MMze , M6N7RAxe , M6N7RAye , M6N7RAze , M6N7RDxe , M6N7RDye , M6N7RDze , & - M6N7TAxe , M6N7TAye , M6N7TAze , M6N7TDxss , M6N7TDyss , M6N7TDzss , M6N8FKxe , & - M6N8FKye , M6N8FKze , M6N8FMxe , M6N8FMye , M6N8FMze , M6N8MKxe , M6N8MKye , & - M6N8MKze , M6N8MMxe , M6N8MMye , M6N8MMze , M6N8RAxe , M6N8RAye , M6N8RAze , & - M6N8RDxe , M6N8RDye , M6N8RDze , M6N8TAxe , M6N8TAye , M6N8TAze , M6N8TDxss , & - M6N8TDyss , M6N8TDzss , M6N9FKxe , M6N9FKye , M6N9FKze , M6N9FMxe , M6N9FMye , & - M6N9FMze , M6N9MKxe , M6N9MKye , M6N9MKze , M6N9MMxe , M6N9MMye , M6N9MMze , & - M6N9RAxe , M6N9RAye , M6N9RAze , M6N9RDxe , M6N9RDye , M6N9RDze , M6N9TAxe , & - M6N9TAye , M6N9TAze , M6N9TDxss , M6N9TDyss , M6N9TDzss , M7N1FKxe , M7N1FKye , & - M7N1FKze , M7N1FMxe , M7N1FMye , M7N1FMze , M7N1MKxe , M7N1MKye , M7N1MKze , & - M7N1MMxe , M7N1MMye , M7N1MMze , M7N1RAxe , M7N1RAye , M7N1RAze , M7N1RDxe , & - M7N1RDye , M7N1RDze , M7N1TAxe , M7N1TAye , M7N1TAze , M7N1TDxss , M7N1TDyss , & - M7N1TDzss , M7N2FKxe , M7N2FKye , M7N2FKze , M7N2FMxe , M7N2FMye , M7N2FMze , & - M7N2MKxe , M7N2MKye , M7N2MKze , M7N2MMxe , M7N2MMye , M7N2MMze , M7N2RAxe , & - M7N2RAye , M7N2RAze , M7N2RDxe , M7N2RDye , M7N2RDze , M7N2TAxe , M7N2TAye , & - M7N2TAze , M7N2TDxss , M7N2TDyss , M7N2TDzss , M7N3FKxe , M7N3FKye , M7N3FKze , & - M7N3FMxe , M7N3FMye , M7N3FMze , M7N3MKxe , M7N3MKye , M7N3MKze , M7N3MMxe , & - M7N3MMye , M7N3MMze , M7N3RAxe , M7N3RAye , M7N3RAze , M7N3RDxe , M7N3RDye , & - M7N3RDze , M7N3TAxe , M7N3TAye , M7N3TAze , M7N3TDxss , M7N3TDyss , M7N3TDzss , & - M7N4FKxe , M7N4FKye , M7N4FKze , M7N4FMxe , M7N4FMye , M7N4FMze , M7N4MKxe , & - M7N4MKye , M7N4MKze , M7N4MMxe , M7N4MMye , M7N4MMze , M7N4RAxe , M7N4RAye , & - M7N4RAze , M7N4RDxe , M7N4RDye , M7N4RDze , M7N4TAxe , M7N4TAye , M7N4TAze , & - M7N4TDxss , M7N4TDyss , M7N4TDzss , M7N5FKxe , M7N5FKye , M7N5FKze , M7N5FMxe , & - M7N5FMye , M7N5FMze , M7N5MKxe , M7N5MKye , M7N5MKze , M7N5MMxe , M7N5MMye , & - M7N5MMze , M7N5RAxe , M7N5RAye , M7N5RAze , M7N5RDxe , M7N5RDye , M7N5RDze , & - M7N5TAxe , M7N5TAye , M7N5TAze , M7N5TDxss , M7N5TDyss , M7N5TDzss , M7N6FKxe , & - M7N6FKye , M7N6FKze , M7N6FMxe , M7N6FMye , M7N6FMze , M7N6MKxe , M7N6MKye , & - M7N6MKze , M7N6MMxe , M7N6MMye , M7N6MMze , M7N6RAxe , M7N6RAye , M7N6RAze , & - M7N6RDxe , M7N6RDye , M7N6RDze , M7N6TAxe , M7N6TAye , M7N6TAze , M7N6TDxss , & - M7N6TDyss , M7N6TDzss , M7N7FKxe , M7N7FKye , M7N7FKze , M7N7FMxe , M7N7FMye , & - M7N7FMze , M7N7MKxe , M7N7MKye , M7N7MKze , M7N7MMxe , M7N7MMye , M7N7MMze , & - M7N7RAxe , M7N7RAye , M7N7RAze , M7N7RDxe , M7N7RDye , M7N7RDze , M7N7TAxe , & - M7N7TAye , M7N7TAze , M7N7TDxss , M7N7TDyss , M7N7TDzss , M7N8FKxe , M7N8FKye , & - M7N8FKze , M7N8FMxe , M7N8FMye , M7N8FMze , M7N8MKxe , M7N8MKye , M7N8MKze , & - M7N8MMxe , M7N8MMye , M7N8MMze , M7N8RAxe , M7N8RAye , M7N8RAze , M7N8RDxe , & - M7N8RDye , M7N8RDze , M7N8TAxe , M7N8TAye , M7N8TAze , M7N8TDxss , M7N8TDyss , & - M7N8TDzss , M7N9FKxe , M7N9FKye , M7N9FKze , M7N9FMxe , M7N9FMye , M7N9FMze , & - M7N9MKxe , M7N9MKye , M7N9MKze , M7N9MMxe , M7N9MMye , M7N9MMze , M7N9RAxe , & - M7N9RAye , M7N9RAze , M7N9RDxe , M7N9RDye , M7N9RDze , M7N9TAxe , M7N9TAye , & - M7N9TAze , M7N9TDxss , M7N9TDyss , M7N9TDzss , M8N1FKxe , M8N1FKye , M8N1FKze , & - M8N1FMxe , M8N1FMye , M8N1FMze , M8N1MKxe , M8N1MKye , M8N1MKze , M8N1MMxe , & - M8N1MMye , M8N1MMze , M8N1RAxe , M8N1RAye , M8N1RAze , M8N1RDxe , M8N1RDye , & - M8N1RDze , M8N1TAxe , M8N1TAye , M8N1TAze , M8N1TDxss , M8N1TDyss , M8N1TDzss , & - M8N2FKxe , M8N2FKye , M8N2FKze , M8N2FMxe , M8N2FMye , M8N2FMze , M8N2MKxe , & - M8N2MKye , M8N2MKze , M8N2MMxe , M8N2MMye , M8N2MMze , M8N2RAxe , M8N2RAye , & - M8N2RAze , M8N2RDxe , M8N2RDye , M8N2RDze , M8N2TAxe , M8N2TAye , M8N2TAze , & - M8N2TDxss , M8N2TDyss , M8N2TDzss , M8N3FKxe , M8N3FKye , M8N3FKze , M8N3FMxe , & - M8N3FMye , M8N3FMze , M8N3MKxe , M8N3MKye , M8N3MKze , M8N3MMxe , M8N3MMye , & - M8N3MMze , M8N3RAxe , M8N3RAye , M8N3RAze , M8N3RDxe , M8N3RDye , M8N3RDze , & - M8N3TAxe , M8N3TAye , M8N3TAze , M8N3TDxss , M8N3TDyss , M8N3TDzss , M8N4FKxe , & - M8N4FKye , M8N4FKze , M8N4FMxe , M8N4FMye , M8N4FMze , M8N4MKxe , M8N4MKye , & - M8N4MKze , M8N4MMxe , M8N4MMye , M8N4MMze , M8N4RAxe , M8N4RAye , M8N4RAze , & - M8N4RDxe , M8N4RDye , M8N4RDze , M8N4TAxe , M8N4TAye , M8N4TAze , M8N4TDxss , & - M8N4TDyss , M8N4TDzss , M8N5FKxe , M8N5FKye , M8N5FKze , M8N5FMxe , M8N5FMye , & - M8N5FMze , M8N5MKxe , M8N5MKye , M8N5MKze , M8N5MMxe , M8N5MMye , M8N5MMze , & - M8N5RAxe , M8N5RAye , M8N5RAze , M8N5RDxe , M8N5RDye , M8N5RDze , M8N5TAxe , & - M8N5TAye , M8N5TAze , M8N5TDxss , M8N5TDyss , M8N5TDzss , M8N6FKxe , M8N6FKye , & - M8N6FKze , M8N6FMxe , M8N6FMye , M8N6FMze , M8N6MKxe , M8N6MKye , M8N6MKze , & - M8N6MMxe , M8N6MMye , M8N6MMze , M8N6RAxe , M8N6RAye , M8N6RAze , M8N6RDxe , & - M8N6RDye , M8N6RDze , M8N6TAxe , M8N6TAye , M8N6TAze , M8N6TDxss , M8N6TDyss , & - M8N6TDzss , M8N7FKxe , M8N7FKye , M8N7FKze , M8N7FMxe , M8N7FMye , M8N7FMze , & - M8N7MKxe , M8N7MKye , M8N7MKze , M8N7MMxe , M8N7MMye , M8N7MMze , M8N7RAxe , & - M8N7RAye , M8N7RAze , M8N7RDxe , M8N7RDye , M8N7RDze , M8N7TAxe , M8N7TAye , & - M8N7TAze , M8N7TDxss , M8N7TDyss , M8N7TDzss , M8N8FKxe , M8N8FKye , M8N8FKze , & - M8N8FMxe , M8N8FMye , M8N8FMze , M8N8MKxe , M8N8MKye , M8N8MKze , M8N8MMxe , & - M8N8MMye , M8N8MMze , M8N8RAxe , M8N8RAye , M8N8RAze , M8N8RDxe , M8N8RDye , & - M8N8RDze , M8N8TAxe , M8N8TAye , M8N8TAze , M8N8TDxss , M8N8TDyss , M8N8TDzss , & - M8N9FKxe , M8N9FKye , M8N9FKze , M8N9FMxe , M8N9FMye , M8N9FMze , M8N9MKxe , & - M8N9MKye , M8N9MKze , M8N9MMxe , M8N9MMye , M8N9MMze , M8N9RAxe , M8N9RAye , & - M8N9RAze , M8N9RDxe , M8N9RDye , M8N9RDze , M8N9TAxe , M8N9TAye , M8N9TAze , & - M8N9TDxss , M8N9TDyss , M8N9TDzss , M9N1FKxe , M9N1FKye , M9N1FKze , M9N1FMxe , & - M9N1FMye , M9N1FMze , M9N1MKxe , M9N1MKye , M9N1MKze , M9N1MMxe , M9N1MMye , & - M9N1MMze , M9N1RAxe , M9N1RAye , M9N1RAze , M9N1RDxe , M9N1RDye , M9N1RDze , & - M9N1TAxe , M9N1TAye , M9N1TAze , M9N1TDxss , M9N1TDyss , M9N1TDzss , M9N2FKxe , & - M9N2FKye , M9N2FKze , M9N2FMxe , M9N2FMye , M9N2FMze , M9N2MKxe , M9N2MKye , & - M9N2MKze , M9N2MMxe , M9N2MMye , M9N2MMze , M9N2RAxe , M9N2RAye , M9N2RAze , & - M9N2RDxe , M9N2RDye , M9N2RDze , M9N2TAxe , M9N2TAye , M9N2TAze , M9N2TDxss , & - M9N2TDyss , M9N2TDzss , M9N3FKxe , M9N3FKye , M9N3FKze , M9N3FMxe , M9N3FMye , & - M9N3FMze , M9N3MKxe , M9N3MKye , M9N3MKze , M9N3MMxe , M9N3MMye , M9N3MMze , & - M9N3RAxe , M9N3RAye , M9N3RAze , M9N3RDxe , M9N3RDye , M9N3RDze , M9N3TAxe , & - M9N3TAye , M9N3TAze , M9N3TDxss , M9N3TDyss , M9N3TDzss , M9N4FKxe , M9N4FKye , & - M9N4FKze , M9N4FMxe , M9N4FMye , M9N4FMze , M9N4MKxe , M9N4MKye , M9N4MKze , & - M9N4MMxe , M9N4MMye , M9N4MMze , M9N4RAxe , M9N4RAye , M9N4RAze , M9N4RDxe , & - M9N4RDye , M9N4RDze , M9N4TAxe , M9N4TAye , M9N4TAze , M9N4TDxss , M9N4TDyss , & - M9N4TDzss , M9N5FKxe , M9N5FKye , M9N5FKze , M9N5FMxe , M9N5FMye , M9N5FMze , & - M9N5MKxe , M9N5MKye , M9N5MKze , M9N5MMxe , M9N5MMye , M9N5MMze , M9N5RAxe , & - M9N5RAye , M9N5RAze , M9N5RDxe , M9N5RDye , M9N5RDze , M9N5TAxe , M9N5TAye , & - M9N5TAze , M9N5TDxss , M9N5TDyss , M9N5TDzss , M9N6FKxe , M9N6FKye , M9N6FKze , & - M9N6FMxe , M9N6FMye , M9N6FMze , M9N6MKxe , M9N6MKye , M9N6MKze , M9N6MMxe , & - M9N6MMye , M9N6MMze , M9N6RAxe , M9N6RAye , M9N6RAze , M9N6RDxe , M9N6RDye , & - M9N6RDze , M9N6TAxe , M9N6TAye , M9N6TAze , M9N6TDxss , M9N6TDyss , M9N6TDzss , & - M9N7FKxe , M9N7FKye , M9N7FKze , M9N7FMxe , M9N7FMye , M9N7FMze , M9N7MKxe , & - M9N7MKye , M9N7MKze , M9N7MMxe , M9N7MMye , M9N7MMze , M9N7RAxe , M9N7RAye , & - M9N7RAze , M9N7RDxe , M9N7RDye , M9N7RDze , M9N7TAxe , M9N7TAye , M9N7TAze , & - M9N7TDxss , M9N7TDyss , M9N7TDzss , M9N8FKxe , M9N8FKye , M9N8FKze , M9N8FMxe , & - M9N8FMye , M9N8FMze , M9N8MKxe , M9N8MKye , M9N8MKze , M9N8MMxe , M9N8MMye , & - M9N8MMze , M9N8RAxe , M9N8RAye , M9N8RAze , M9N8RDxe , M9N8RDye , M9N8RDze , & - M9N8TAxe , M9N8TAye , M9N8TAze , M9N8TDxss , M9N8TDyss , M9N8TDzss , M9N9FKxe , & - M9N9FKye , M9N9FKze , M9N9FMxe , M9N9FMye , M9N9FMze , M9N9MKxe , M9N9MKye , & - M9N9MKze , M9N9MMxe , M9N9MMye , M9N9MMze , M9N9RAxe , M9N9RAye , M9N9RAze , & - M9N9RDxe , M9N9RDye , M9N9RDze , M9N9TAxe , M9N9TAye , M9N9TAze , M9N9TDxss , & - M9N9TDyss , M9N9TDzss , ReactFXss , ReactFYss , ReactFZss , ReactMXss , ReactMYss , & - ReactMZss , SSqm01 , SSqm02 , SSqm03 , SSqm04 , SSqm05 , SSqm06 , & - SSqm07 , SSqm08 , SSqm09 , SSqm10 , SSqm11 , SSqm12 , SSqm13 , & - SSqm14 , SSqm15 , SSqm16 , SSqm17 , SSqm18 , SSqm19 , SSqm20 , & - SSqm21 , SSqm22 , SSqm23 , SSqm24 , SSqm25 , SSqm26 , SSqm27 , & - SSqm28 , SSqm29 , SSqm30 , SSqm31 , SSqm32 , SSqm33 , SSqm34 , & - SSqm35 , SSqm36 , SSqm37 , SSqm38 , SSqm39 , SSqm40 , SSqm41 , & - SSqm42 , SSqm43 , SSqm44 , SSqm45 , SSqm46 , SSqm47 , SSqm48 , & - SSqm49 , SSqm50 , SSqm51 , SSqm52 , SSqm53 , SSqm54 , SSqm55 , & - SSqm56 , SSqm57 , SSqm58 , SSqm59 , SSqm60 , SSqm61 , SSqm62 , & - SSqm63 , SSqm64 , SSqm65 , SSqm66 , SSqm67 , SSqm68 , SSqm69 , & - SSqm70 , SSqm71 , SSqm72 , SSqm73 , SSqm74 , SSqm75 , SSqm76 , & - SSqm77 , SSqm78 , SSqm79 , SSqm80 , SSqm81 , SSqm82 , SSqm83 , & - SSqm84 , SSqm85 , SSqm86 , SSqm87 , SSqm88 , SSqm89 , SSqm90 , & - SSqm91 , SSqm92 , SSqm93 , SSqm94 , SSqm95 , SSqm96 , SSqm97 , & - SSqm98 , SSqm99 , SSqmd01 , SSqmd02 , SSqmd03 , SSqmd04 , SSqmd05 , & - SSqmd06 , SSqmd07 , SSqmd08 , SSqmd09 , SSqmd10 , SSqmd11 , SSqmd12 , & - SSqmd13 , SSqmd14 , SSqmd15 , SSqmd16 , SSqmd17 , SSqmd18 , SSqmd19 , & - SSqmd20 , SSqmd21 , SSqmd22 , SSqmd23 , SSqmd24 , SSqmd25 , SSqmd26 , & - SSqmd27 , SSqmd28 , SSqmd29 , SSqmd30 , SSqmd31 , SSqmd32 , SSqmd33 , & - SSqmd34 , SSqmd35 , SSqmd36 , SSqmd37 , SSqmd38 , SSqmd39 , SSqmd40 , & - SSqmd41 , SSqmd42 , SSqmd43 , SSqmd44 , SSqmd45 , SSqmd46 , SSqmd47 , & - SSqmd48 , SSqmd49 , SSqmd50 , SSqmd51 , SSqmd52 , SSqmd53 , SSqmd54 , & - SSqmd55 , SSqmd56 , SSqmd57 , SSqmd58 , SSqmd59 , SSqmd60 , SSqmd61 , & - SSqmd62 , SSqmd63 , SSqmd64 , SSqmd65 , SSqmd66 , SSqmd67 , SSqmd68 , & - SSqmd69 , SSqmd70 , SSqmd71 , SSqmd72 , SSqmd73 , SSqmd74 , SSqmd75 , & - SSqmd76 , SSqmd77 , SSqmd78 , SSqmd79 , SSqmd80 , SSqmd81 , SSqmd82 , & - SSqmd83 , SSqmd84 , SSqmd85 , SSqmd86 , SSqmd87 , SSqmd88 , SSqmd89 , & - SSqmd90 , SSqmd91 , SSqmd92 , SSqmd93 , SSqmd94 , SSqmd95 , SSqmd96 , & - SSqmd97 , SSqmd98 , SSqmd99 , SSqmdd01 , SSqmdd02 , SSqmdd03 , SSqmdd04 , & - SSqmdd05 , SSqmdd06 , SSqmdd07 , SSqmdd08 , SSqmdd09 , SSqmdd10 , SSqmdd11 , & - SSqmdd12 , SSqmdd13 , SSqmdd14 , SSqmdd15 , SSqmdd16 , SSqmdd17 , SSqmdd18 , & - SSqmdd19 , SSqmdd20 , SSqmdd21 , SSqmdd22 , SSqmdd23 , SSqmdd24 , SSqmdd25 , & - SSqmdd26 , SSqmdd27 , SSqmdd28 , SSqmdd29 , SSqmdd30 , SSqmdd31 , SSqmdd32 , & - SSqmdd33 , SSqmdd34 , SSqmdd35 , SSqmdd36 , SSqmdd37 , SSqmdd38 , SSqmdd39 , & - SSqmdd40 , SSqmdd41 , SSqmdd42 , SSqmdd43 , SSqmdd44 , SSqmdd45 , SSqmdd46 , & - SSqmdd47 , SSqmdd48 , SSqmdd49 , SSqmdd50 , SSqmdd51 , SSqmdd52 , SSqmdd53 , & - SSqmdd54 , SSqmdd55 , SSqmdd56 , SSqmdd57 , SSqmdd58 , SSqmdd59 , SSqmdd60 , & - SSqmdd61 , SSqmdd62 , SSqmdd63 , SSqmdd64 , SSqmdd65 , SSqmdd66 , SSqmdd67 , & - SSqmdd68 , SSqmdd69 , SSqmdd70 , SSqmdd71 , SSqmdd72 , SSqmdd73 , SSqmdd74 , & - SSqmdd75 , SSqmdd76 , SSqmdd77 , SSqmdd78 , SSqmdd79 , SSqmdd80 , SSqmdd81 , & - SSqmdd82 , SSqmdd83 , SSqmdd84 , SSqmdd85 , SSqmdd86 , SSqmdd87 , SSqmdd88 , & - SSqmdd89 , SSqmdd90 , SSqmdd91 , SSqmdd92 , SSqmdd93 , SSqmdd94 , SSqmdd95 , & - SSqmdd96 , SSqmdd97 , SSqmdd98 , SSqmdd99 /) - CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(2265) = (/ & ! This lists the units corresponding to the allowed parameters - "(N) ","(N) ","(N) ","(Nm) ","(Nm) ","(Nm) ","(rad/s^2) ", & - "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & - "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & - "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & - "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & - "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & - "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & - "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & - "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & - "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & - "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & - "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & - "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & - "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & - "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & - "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & - "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & - "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & - "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & - "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & - "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & - "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & - "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & - "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & - "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & - "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & - "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & - "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & - "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & - "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & - "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & - "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & - "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & - "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & - "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & - "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & - "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & - "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & - "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & - "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & - "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & - "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & - "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & - "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & - "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & - "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & - "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & - "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & - "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & - "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & - "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & - "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & - "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & - "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & - "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & - "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & - "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & - "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & - "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & - "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & - "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & - "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & - "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & - "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & - "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & - "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & - "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & - "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & - "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & - "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & - "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & - "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & - "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & - "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & - "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & - "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & - "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & - "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & - "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & - "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & - "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & - "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & - "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & - "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & - "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & - "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & - "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & - "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & - "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & - "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & - "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & - "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & - "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & - "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & - "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & - "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & - "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & - "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & - "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & - "(m) ","(m) ","(N) ","(N) ","(N) ","(Nm) ","(Nm) ", & - "(Nm) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & - "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & - "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & - "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & - "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & - "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & - "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & - "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & - "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & - "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & - "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & - "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & - "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & - "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & - "(--) ","(--) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & - "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & - "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & - "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & - "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & - "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & - "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & - "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & - "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & - "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & - "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & - "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & - "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & - "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & - "(1/s) ","(1/s) ","(1/s) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & - "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & - "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & - "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & - "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & - "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & - "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & - "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & - "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & - "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & - "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & - "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & - "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & - "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & - "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) "/) - - -!End of code generated by Matlab script - - - + PRIVATE ! ..... Public Subroutines ................................................................................................... PUBLIC :: SDOut_CloseSum PUBLIC :: SDOut_OpenSum @@ -3763,791 +40,476 @@ MODULE SubDyn_Output PUBLIC :: SDOut_WriteOutputUnits PUBLIC :: SDOut_WriteOutputs PUBLIC :: SDOut_Init + PUBLIC :: SD_Init_Jacobian + PUBLIC :: SD_Perturb_u + PUBLIC :: SD_Perturb_x + PUBLIC :: SD_Compute_dY + PUBLIC :: SD_Compute_dX CONTAINS -SUBROUTINE SDOut_Init( Init, y, p, misc, InitOut, WtrDpth, ErrStat, ErrMsg ) -! This subroutine initializes the output module, checking if the output parameter list (OutList) +!> This subroutine initializes the output module, checking if the output parameter list (OutList) ! contains valid names, and opening the output file if there are any requested outputs -!---------------------------------------------------------------------------------------------------- - - -! Passed variables - - 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), INTENT( INOUT ) :: p ! SubDyn module paramters - 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 - INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - -! Local variables - - INTEGER(IntKi) :: I,J,K,K2,L,NconEls !Counters - INTEGER(IntKi) :: Junk !Temporary Holders - INTEGER(IntKi) :: iMember ! Member index (not member ID) - INTEGER(IntKi), Dimension(2) :: M !counter for two nodes at a time -!------------------------------------------------------------------------------------------------- -! Initialize local variables -!------------------------------------------------------------------------------------------------- -ErrStat = 0 -ErrMsg="" - -p%OutAllDims=12*p%Nmembers*2 !size of AllOut Member Joint forces - -!------------------------------------------------------------------------------------------------- -! Check that the variables in OutList are valid -!------------------------------------------------------------------------------------------------- - -! SDOut_Data%NumOuts = HDO_InitData%NumOuts - CALL SDOut_ChkOutLst( Init%SSOutList, p, ErrStat, ErrMsg ) - IF ( ErrStat /= 0 ) RETURN - -!------------------------------------------------------------------------------------------------- -! INITIALIZE FAST-TYPE OUTPUT (y) -!------------------------------------------------------------------------------------------------- - !ALLOCATE( y%Y1(TPdofL), STAT = ErrStat ) - !IF ( ErrStat/= 0 ) THEN - ! ErrStat = ErrID_Fatal - ! ErrMsg = 'Error allocating output Y1 array in SDOut_Init' - ! RETURN - !END IF +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_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 + INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred + CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! Local variables + INTEGER(IntKi) :: ErrStat2 ! Error status of the operation + CHARACTER(ErrMsgLen) :: ErrMsg2 ! Error message if ErrStat /= ErrID_None + INTEGER(IntKi) :: I,J,K2 !Counters + INTEGER(IntKi) :: iMember ! Member index (not member ID) + INTEGER(IntKi) :: iElem ! Index of element in Element List + INTEGER(IntKi) :: iNode ! Index of node in Node list + INTEGER(IntKi) :: iiElem ! Loop counter on element index + INTEGER(IntKi) :: nElemPerNode, nNodesPerElem ! Number of elements connecting to a node, Number of nodes per elem + type(MeshAuxDataType), pointer :: pLst !< Alias to shorten notation and highlight code similarities + real(ReKi), allocatable :: T_TIreact(:,:) ! Transpose of TIreact, temporary + ErrStat = 0 + ErrMsg="" -!------------------------------------------------------------------------------------------------- -! Open the output file, if necessary, and write the header -!------------------------------------------------------------------------------------------------- + p%OutAllDims=12*p%NMembers*2 !size of AllOut Member Joint forces - IF ( ALLOCATED( p%OutParam ) .AND. p%NumOuts > 0 ) THEN ! Output has been requested + ! Check that the variables in OutList are valid + CALL SDOut_ChkOutLst( Init%SSOutList, p, ErrStat2, ErrMsg2 ); if(Failed()) return - + ! --- Allocation (size 0 if not outputs) + !IF ( ALLOCATED( p%OutParam ) .AND. p%NumOuts > 0 ) THEN ! Output has been requested ! Allocate SDWrOuput which is used to store a time step's worth of output channels, prior to writing to a file. - ALLOCATE( misc%SDWrOutput( p%NumOuts +p%OutAllInt*p%OutAllDims), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for SDWrOutput array.' - ErrStat = ErrID_Fatal - RETURN - END IF + CALL AllocAry(misc%SDWrOutput , p%NumOuts + p%OutAllInt*p%OutAllDims, 'SDWrOutupt' , ErrStat2, ErrMsg2) ; if(Failed()) return + ! Allocate WriteOuput + CALL AllocAry(y%WriteOutput , p%NumOuts + p%OutAllInt*p%OutAllDims, 'WriteOutput', ErrStat2, ErrMsg2); if(Failed()) return + ! Header, and Units, copy of data already available in the OutParam data structure ! TODO TODO TODO remove copy + CALL AllocAry(InitOut%WriteOutputHdr, p%NumOuts + p%OutAllint*p%OutAllDims, 'WriteOutputHdr', ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(InitOut%WriteOutputUnt, p%NumOuts + p%OutAllint*p%OutAllDims, 'WriteOutputUnt', ErrStat2, ErrMsg2); if(Failed()) return misc%SDWrOutput = 0.0_ReKi misc%LastOutTime = 0.0_DbKi misc%Decimat = 0 - - !Allocate WriteOuput - ALLOCATE( y%WriteOutput( p%NumOuts +p%OutAllInt*p%OutAllDims), STAT = ErrStat ) - IF ( ErrStat /= 0 ) THEN - ErrMsg = ' Error allocating space for WriteOutput array.' - ErrStat = ErrID_Fatal - RETURN - END IF y%WriteOutput = 0 - - !Do some final mapping and carry out housekeeping to calculate some of the output variable - - - !Store mapping between nodes and elements - CALL NodeCon(Init,p,ErrStat, ErrMsg) - IF ( ErrStat /=0) RETURN - - DO I=1,p%NMOutputs - ALLOCATE( p%MOutLst(I)%NodeIDs(p%MoutLst(I)%NoutCnt), STAT = ErrStat ) - IF ( ErrStat/= 0 ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'Error allocating p%MOutLst(I)%NodeIDs arrays in SDOut_Init' - RETURN - END IF - iMember = FINDLOCI(Init%Members(:,1), p%MoutLst(I)%MemberID) ! Reindexing from MemberID to 1:nMembers - p%MOutLst(I)%NodeIDs=Init%MemberNodes(iMember ,p%MOutLst(I)%NodeCnt) !We are storing the actual node numbers corresponding to what the user ordinal number is requesting - - ALLOCATE( p%MOutLst(I)%ElmIDs(p%MoutLst(I)%NoutCnt,p%NAvgEls), STAT = ErrStat ) !ElmIDs has for each selected node within the member, several element numbers to refer to for averaging (max 2 elements) - IF ( ErrStat/= 0 ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'Error allocating p%MOutLst(I)%ElmIDs arrays in SDOut_Init' - RETURN - END IF - p%MOutLst(I)%ElmIDs=0 !Initialize to 0 - - ALLOCATE( p%MOutLst(I)%ElmNds(p%MoutLst(I)%NoutCnt,p%NAvgEls), STAT = ErrStat ) !ElmNds has for each selected node within the member, for each element number to refer to for averaging, the flag 1 or 2 depending on whether it is the 1st or last node of that element - IF ( ErrStat/= 0 ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'Error allocating p%MOutLst(I)%ElmNds arrays in SDOut_Init' - RETURN - END IF - - ALLOCATE( p%MOutLst(I)%Me(12,12,p%MoutLst(I)%NoutCnt,p%NAvgEls), STAT = ErrStat ) !Me has for each selected node within the member, and for each element attached to that node for averaging (max 2) a 12x12 matrix - IF ( ErrStat/= 0 ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'Error allocating p%MOutLst(I)%Me arrays in SDOut_Init' - RETURN - END IF - ALLOCATE( p%MOutLst(I)%Ke(12,12,p%MoutLst(I)%NoutCnt,p%NAvgEls), STAT = ErrStat ) !Ke has for each selected node within the member, and for each element attached to that node for averaging (max 2) a 12x12 matrix - IF ( ErrStat/= 0 ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'Error allocating p%MOutLst(I)%Ke arrays in SDOut_Init' - RETURN - END IF - ALLOCATE( p%MOutLst(I)%Fg(12,p%MoutLst(I)%NoutCnt,p%NAvgEls), STAT = ErrStat ) !Fg has for each selected node within the member, and for each element attached to that node for averaging (max 2) a 12x1 vector - IF ( ErrStat/= 0 ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'Error allocating p%MOutLst(I)%Fg arrays in SDOut_Init' - RETURN - END IF - - - - DO J=1,p%MoutLst(I)%NoutCnt !Iterate on requested nodes for that member - !I need to get at most 2 elements that belong to the same MoutLst(I)%MemberID - !make use of MemberNodes and NodesConnE - NconEls=Init%NodesConnE(p%MoutLst(I)%NodeIDs(J),1)!Number of elements connecting to the j-th node - - K2=0 !Initialize counter - DO K=1, NconEls - L=Init%NodesConnE(p%MoutLst(I)%NodeIDs(J),k+1) !k-th Element Number - M=p%Elems(L,2:3) !1st and 2nd node of the k-th element - - !Select only the other node, not the one where elements connect to - Junk=M(1) - IF (M(1) .EQ. p%MoutLst(I)%NodeIDs(J)) Junk=M(2) - - IF (ANY(Init%MemberNodes(iMember,:) .EQ. Junk)) THEN !This means we are in the selected member - IF (K2 .EQ. 2) EXIT - K2=K2+1 - p%MoutLst(I)%ElmIDs(J,K2)=L !This array has for each node requested NODEID(J), for each memberMOutLst(I)%MemberID, the 2 elements to average from, it may have 1 if one of the numbers is 0 - - p%MoutLst(I)%ElmNds(J,K2)=1 !store whether first or second node of element - IF (M(2) .EQ. p%MoutLst(I)%NodeIDs(J) ) p%MoutLst(I)%ElmNds(J,K2)=2 !store whether first or second node of element - - !Calculate Ke, Me to be used for output - CALL ElemK( p%elemprops(L)%Area, p%elemprops(L)%Length, p%elemprops(L)%Ixx, p%elemprops(L)%Iyy, & - p%elemprops(L)%Jzz, p%elemprops(L)%Shear, p%elemprops(L)%kappa, p%elemprops(L)%YoungE, & - p%elemprops(L)%ShearG, p%elemprops(L)%DirCos, p%MoutLst(I)%Ke(:,:,J,K2) ) - CALL ElemM( p%elemprops(L)%Area, p%elemprops(L)%Length, p%elemprops(L)%Ixx, p%elemprops(L)%Iyy,& - p%elemprops(L)%Jzz, p%elemprops(L)%rho, p%elemprops(L)%DirCos, p%MoutLst(I)%Me(:,:,J,K2) ) - - CALL ElemG( p%elemprops(L)%Area, p%elemprops(L)%Length, p%elemprops(L)%rho, p%elemprops(L)%DirCos, p%MoutLst(I)%Fg(:,J,K2), Init%g ) - END IF - ENDDO - ENDDO - - ENDDO - - - - END IF ! there are any requested outputs - - - IF (p%OutAll) THEN !I need to store all member end forces and moments - - ALLOCATE ( p%MOutLst2(p%NMembers), STAT = ErrStat ) !this list contains different arrays for each of its elements - IF ( ErrStat /= ErrID_None ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'Error allocating p%MOutLst2 array in SDOut_Init' - RETURN - END IF - + DO I = 1,p%NumOuts+p%OutAllint*p%OutAllDims + InitOut%WriteOutputHdr(I) = TRIM( p%OutParam(I)%Name ) + InitOut%WriteOutputUnt(I) = TRIM( p%OutParam(I)%Units ) + END DO - DO I=1,p%NMembers - p%MOutLst2(I)%MemberID=Init%Members(I,1) - - ALLOCATE( p%MOutLst2(I)%NodeIDs(Init%Ndiv+1), STAT = ErrStat ) !1st and last node of member - IF ( ErrStat/= 0 ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'Error allocating p%MOutLst2(I)%NodeIDs arrays in SDOut_Init' - RETURN - END IF - p%MOutLst2(I)%NodeIDs=Init%MemberNodes(I,1:Init%Ndiv+1) !We are storing the actual node numbers in the member - - !Now I need to find out which elements are attached to those nodes and still belong to the member I - !ElmID2s could contain the same element twice if Ndiv=1 - p%MOutLst2(I)%ElmID2s=0 !Initialize to 0 - - - DO J=1,Init%Ndiv+1,Init%Ndiv !Iterate on requested nodes for that member (first and last) - !I need to get at most 2 elements that belong to the same I Member - !make use of MemberNodes and NodesConnE - - NconEls=Init%NodesConnE(p%MoutLst2(I)%NodeIDs(J),1) !Number of elements connecting to the 1st or last node of the member - - K2= J/(Init%Ndiv+1)+1 !store this quantity used later, basically 1 or 2 depending on J - - DO K=1, NconEls - L=Init%NodesConnE(p%MoutLst2(I)%NodeIDs(J),k+1) !k-th Element Number in the set of elements attached to the selected node - M=p%Elems(L,2:3) !1st and 2nd node of the k-th element - !Select only the other node, not the one where elements connect to - Junk=M(1) - IF (M(1) .EQ. p%MoutLst2(I)%NodeIDs(J)) Junk=M(2) - - IF (ANY(Init%MemberNodes(I,:) .EQ. Junk)) THEN !This means we are in the selected member - - p%MoutLst2(I)%ElmID2s(K2)=L !This array has for each node requested NODEID(J), for each member I, the element to get results for - - p%MoutLst2(I)%ElmNd2s(K2)=1 !store whether first or second node of element - IF (M(2) .EQ. p%MoutLst2(I)%NodeIDs(J) ) p%MoutLst2(I)%ElmNd2s(K2)=2 !store whether first or second node of element - - !Calculate Ke, Me to be used for output - CALL ElemK( p%elemprops(L)%Area, p%elemprops(L)%Length, p%elemprops(L)%Ixx, p%elemprops(L)%Iyy, & - p%elemprops(L)%Jzz, p%elemprops(L)%Shear, p%elemprops(L)%kappa, p%elemprops(L)%YoungE, & - p%elemprops(L)%ShearG, p%elemprops(L)%DirCos, p%MoutLst2(I)%Ke2(:,:,K2) ) - CALL ElemM( p%elemprops(L)%Area, p%elemprops(L)%Length, p%elemprops(L)%Ixx, p%elemprops(L)%Iyy,& - p%elemprops(L)%Jzz, p%elemprops(L)%rho, p%elemprops(L)%DirCos, p%MoutLst2(I)%Me2(:,:,K2) ) - CALL ElemG( p%elemprops(L)%Area, p%elemprops(L)%Length, p%elemprops(L)%rho, p%elemprops(L)%DirCos, p%MoutLst2(I)%Fg2(:,K2), Init%g ) - + !_________________________________ OUTPUT FOR REQUESTED MEMBERS _______________________________ + DO I=1,p%NMOutputs + pLst => p%MOutLst(I) ! Alias to shorten notations + CALL AllocAry(pLst%NodeIDs, pLst%NoutCnt , 'MOutLst(I)%NodeIDs', ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(pLst%ElmIDs, pLst%NoutCnt, 2, 'MOutLst(I)%ElmIDs' , ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(pLst%ElmNds, pLst%NoutCnt, 2, 'MOutLst(I)%ElmNds' , ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(pLst%Me, 12, 12, pLst%NoutCnt, 2, 'MOutLst(I)%Me' , ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(pLst%Ke, 12, 12, pLst%NoutCnt, 2, 'MOutLst(I)%Ke' , ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(pLst%Fg, 12, pLst%NoutCnt, 2, 'MOutLst(I)%Fg' , ErrStat2, ErrMsg2); if(Failed()) return + + ! NOTE: len(MemberNodes) >2 if nDiv>1 + iMember = FINDLOCI(Init%Members(:,1), pLst%MemberID) ! Reindexing from MemberID to 1:nMembers + pLst%NodeIDs(1:pLst%NoutCnt)=Init%MemberNodes(iMember, pLst%NodeCnt) ! We are storing the actual node numbers corresponding to what the user ordinal number is requesting + pLst%ElmIDs=0 !Initialize to 0 + pLst%ElmNds=0 !Initialize to 0 + + DO J=1,pLst%NoutCnt ! loop on requested nodes for that member + iNode = pLst%NodeIDs(J) ! Index of requested node in node list + nElemPerNode = Init%NodesConnE(iNode, 1) ! Number of elements connecting to the j-th node + ! Finding 1 or max 2 elements that belong to the member and connect to the node + K2=0 ! Counter so that max 2 elements are included: NOTE: I belive more than 2 should be an error + DO iiElem = 1, nElemPerNode + iElem = Init%NodesConnE(iNode, iiElem+1) ! iiElem-th Element Number + IF (ThisElementIsAlongMember(iElem, iNode, iMember)) THEN + IF (K2 == 2) EXIT ! we found both elements already, error... + K2=K2+1 + call ConfigOutputNode_MKF_ID(pLst, iElem, iiNode=J, iStore=K2, NodeID2=iNode) + END IF + ENDDO ! iiElem, nElemPerNode + ENDDO !J, Noutcnt + ENDDO !I, NMOutputs + + !_________________________________ OUTPUT FOR ALL MEMBERS __________________________________ + IF (p%OutAll) THEN !I need to store all member end forces and moments + + ! MOutLst2: nodal output info by members, for all members, First and Last Node + ALLOCATE ( p%MOutLst2(p%NMembers), STAT = ErrStat2 ); ErrMsg2 = 'Error allocating p%MOutLst2 array in SDOut_Init'; if(Failed()) return + + DO iMember=1,p%NMembers + pLst => p%MOutLst2(iMember) ! Alias + pLst%MemberID = Init%Members(iMember,1) + nNodesPerElem = count(Init%MemberNodes(iMember,:) >0 ) + CALL AllocAry(pLst%NodeIDs, nNodesPerElem, 'MOutLst2(I)%NodeIDs', ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(pLst%ElmIDs, 2, 1, 'MOutLst2(I)%ElmIDs' , ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(pLst%ElmNds, 2, 1, 'MOutLst2(I)%ElmNds' , ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(pLst%Me, 12, 12, 2, 1, 'MOutLst2(I)%Me' , ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(pLst%Ke, 12, 12, 2, 1, 'MOutLst2(I)%Ke' , ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(pLst%Fg, 12, 2, 1, 'MOutLst2(I)%Fg' , ErrStat2, ErrMsg2); if(Failed()) return + pLst%NodeIDs(1:nNodesPerElem) = Init%MemberNodes(iMember,1:nNodesPerElem) ! We are storing the actual node numbers in the member + !ElmIDs could contain the same element twice if Ndiv=1 + pLst%ElmIDs=0 !Initialize to 0 + DO J=1,nNodesPerElem,nNodesPerElem-1 ! loop on first and last node of member + iNode = pLst%NodeIDs(J) ! Index of requested node in node list + nElemPerNode = Init%NodesConnE(iNode, 1) ! Number of elements connecting to the 1st or last node of the member + K2= J/(nNodesPerElem)+1 ! 1 (first node) or 2 (last node) depending on J + DO iiElem=1, nElemPerNode + iElem = Init%NodesConnE(iNode,iiElem+1) ! iiElem-th Element Number in the set of elements attached to the selected node + IF (ThisElementIsAlongMember(iElem, iNode, iMember)) THEN + call ConfigOutputNode_MKF_ID(pLst, iElem, iiNode=K2, iStore=1, NodeID2=iNode) EXIT !We found the element for that node, exit loop on elements - ENDIF - - - ENDDO - + ENDIF + ENDDO + ENDDO ! Loop on divisions + ENDDO ! Loop on members + ENDIF ! OutAll + !_____________________________________REACTIONS_____________________________________________ + ! --- Check if reaction requested by user + p%OutReact = .FALSE. + DO I=1,p%NumOuts + if ( ANY( p%OutParam(I)%Indx == ReactSS) ) THEN ! bjj: removed check of first 5 characters being "React" because (1) cases matter and (2) we can also ask for "-React*" or "mREACT" + p%OutReact =.TRUE. + EXIT + ENDIF + ENDDO + IF (p%OutReact) THEN !I need to store all constrained forces and moments; WE do not allow more than one member to be connected at a constrained joint for the time being + ! MOutLst3: nodal output info by members, for the members involved in reaction + ALLOCATE(p%MOutLst3(p%nNodes_C), STAT = ErrStat2); ErrMsg2 = 'Error allocating p%MOutLst3 array in SDOut_Init'; if(Failed()) return + + DO I=1,p%nNodes_C !For all constrained node + pLst => p%MOutLst3(I) + iNode = p%Nodes_C(I,1) ! Note: Nodes_C has been reindexed + nElemPerNode = Init%NodesConnE(iNode,1) ! Number of elements connecting to the joint + CALL AllocAry(pLst%ElmIDs, 1, nElemPerNode, ' p%MOutLst3(I)%ElmIds', ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(pLst%ElmNds, 1, nElemPerNode, ' p%MOutLst3(I)%ElmNds', ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(pLst%Me, 12, 12 , 1, nElemPerNode, ' p%MOutLst3(I)%Me' , ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(pLst%Ke, 12, 12 , 1, nElemPerNode, ' p%MOutLst3(I)%Ke' , ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(pLst%Fg, 12 , 1, nElemPerNode, ' p%MOutLst3(I)%Fg' , ErrStat2, ErrMsg2); if(Failed()) return + DO iiElem = 1, nElemPerNode + iElem = Init%NodesConnE(iNode, iiElem+1) ! iiElem-th Element Number in the set of elements attached to the selected node + call ConfigOutputNode_MKF_ID(pLst, iElem, iiNode=1, iStore=iiElem, NodeID2=iNode) + ENDDO ENDDO - - ENDDO - - - ENDIF - - !_____________________________________REACTIONS_____________________________________________ -p%OutReact = .FALSE. -DO I=1,p%NumOuts - if ( ANY( p%OutParam(I)%Indx == ReactSS) ) THEN ! bjj: removed check of first 5 characters being "React" because (1) cases matter and (2) we can also ask for "-React*" or "mREACT" - p%OutReact =.TRUE. - EXIT + ! Compute p%TIreact, rigid transf. matrix from reaction DOFs to base structure point (0,0,-WD) + CALL AllocAry(p%TIreact, 6, p%nDOFC__, 'TIReact ', ErrStat2, ErrMsg2); if(Failed()) return + CALL AllocAry(T_TIreact, p%nDOFC__, 6, 'TIReact_T', ErrStat2, ErrMsg2); if(Failed()) return + call RigidTrnsf(Init, p, (/0.0_Reki, 0.0_ReKi, -WtrDpth /), p%IDC__, p%nDOFC__, T_TIreact, ErrStat2, ErrMsg2); if(Failed()) return + p%TIreact=transpose(T_TIreact) + deallocate(T_TIreact) ENDIF -ENDDO - - IF (p%OutReact) THEN !I need to store all constrained forces and moments; WE do not allow more than one member to be connected at a constrained joint for the time being - - ALLOCATE ( p%MOutLst3(p%NReact), STAT = ErrStat ) !this list contains different arrays for each of its elements - IF ( ErrStat /= ErrID_None ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'Error allocating p%MOutLst3 array in SDOut_Init' - RETURN - END IF - - - DO I=1,p%NReact !For all constrained node - - p%MOutLst3(I)%Noutcnt=p%Reacts(I,1) !Assign nodeID for list I, I am using Noutcnt as a temporary holder for it, since nodeID is n array - - !Next stuff to be eliminated - !ALLOCATE( p%MOutLst3(I)%NodeIDs(Init%Ndiv+1), STAT = ErrStat ) ! - ! IF ( ErrStat/= 0 ) THEN - ! ErrStat = ErrID_Fatal - ! ErrMsg = 'Error allocating p%MOutLst3(I)%NodeIDs arrays in SDOut_Init' - ! RETURN - ! END IF - ! - !p%MOutLst3(I)%NodeIDs=Init%MemberNodes(I,1:Init%Ndiv+1) !We are storing the actual node numbers in the member - !Now I need to find out which elements are attached to those nodes and still belong to the member I - !ElmID2s could contain the same element twice if Ndiv=1 - !p%MOutLst3(I)%ElmID2s=0 !Initialize to 0 - - !I need to get ALL the elements that belong to the same joint - !make use of MemberNodes and NodesConnE - - NconEls=Init%NodesConnE(p%MoutLst3(I)%Noutcnt,1) !Number of elements connecting to the joint - - ALLOCATE( p%MOutLst3(I)%ElmIDs(1,NconEls), STAT = ErrStat ) !element IDs connecting to the joint; (1,NconEls) and not (NconEls) as the same meshauxtype is used with other Moutlst - IF ( ErrStat/= 0 ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'Error allocating p%MOutLst3(I)%ElmIDs arrays in SDOut_Init' - RETURN - END IF - - ALLOCATE( p%MOutLst3(I)%ElmNds(1,NconEls), STAT = ErrStat ) !This array contains for each element connected to the joint, a flag that tells me whether the joint is node 1 or 2 for the elements - IF ( ErrStat/= 0 ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'Error allocating p%MOutLst3(I)%ElmIDs arrays in SDOut_Init' - RETURN - END IF - - ALLOCATE( p%MOutLst3(I)%Me(12,12,1,NconEls), STAT = ErrStat ) !Me has for each selected joint, and for each element attached to that node, a 12x12 matrix (extra dimension redundant) - IF ( ErrStat/= 0 ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'Error allocating p%MOutLst3(I)%Me arrays in SDOut_Init' - RETURN - END IF - ALLOCATE( p%MOutLst3(I)%Ke(12,12,1,NconEls), STAT = ErrStat ) !Ke has for each selected joint, and for each element attached to that node a 12x12 matrix - IF ( ErrStat/= 0 ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'Error allocating p%MOutLst3(I)%Ke arrays in SDOut_Init' - RETURN - END IF - ALLOCATE( p%MOutLst3(I)%Fg(12,1,NconEls), STAT = ErrStat ) !Fg has for each selected joint, and for each element attached to that node a 12x1 vector - IF ( ErrStat/= 0 ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'Error allocating p%MOutLst3(I)%Ke arrays in SDOut_Init' - RETURN - END IF - - DO K=1, NconEls - L=Init%NodesConnE(p%MoutLst3(I)%Noutcnt,k+1) !k-th Element Number in the set of elements attached to the selected node - - p%MoutLst3(I)%ElmIDs(1,K)=L !This array has for each joint requested the elements' ID to get results for - - M=p%Elems(L,2:3) !1st and 2nd node of the k-th element - - !Select whether the joint is the 1st or second node of the element - p%MoutLst3(I)%ElmNds(1,K)=1 !store whether first or second node of element - IF (M(2) .EQ. p%MoutLst3(I)%Noutcnt ) p%MoutLst3(I)%ElmNds(1,K)=2 !store whether first or second node of element - - !Calculate Ke, Me to be used for output - CALL ElemK( p%elemprops(L)%Area, p%elemprops(L)%Length, p%elemprops(L)%Ixx, p%elemprops(L)%Iyy, & - p%elemprops(L)%Jzz, p%elemprops(L)%Shear, p%elemprops(L)%kappa, p%elemprops(L)%YoungE, & - p%elemprops(L)%ShearG, p%elemprops(L)%DirCos, p%MoutLst3(I)%Ke(:,:,1,K) ) - CALL ElemM( p%elemprops(L)%Area, p%elemprops(L)%Length, p%elemprops(L)%Ixx, p%elemprops(L)%Iyy,& - p%elemprops(L)%Jzz, p%elemprops(L)%rho, p%elemprops(L)%DirCos, p%MoutLst3(I)%Me(:,:,1,K) ) - CALL ElemG( p%elemprops(L)%Area, p%elemprops(L)%Length, p%elemprops(L)%rho, p%elemprops(L)%DirCos, p%MoutLst3(I)%Fg(:,1,K), Init%g ) - - - ENDDO - - ENDDO - - !Store the matrix that will let me calculate single point reaction at the base of structure - CALL ReactMatx(Init, p, WtrDpth, ErrStat, ErrMsg) - ENDIF - - - - ! These variables are to help follow the framework template, but the data in them is simply a copy of data - ! already available in the OutParam data structure - - ALLOCATE ( InitOut%WriteOutputHdr(p%NumOuts+p%OutAllint*p%OutAllDims), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for WriteOutputHdr array.' - ErrStat = ErrID_Fatal RETURN - END IF - ALLOCATE ( InitOut%WriteOutputUnt(p%NumOuts+p%OutAllint*p%OutAllDims), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for WriteOutputHdr array.' - ErrStat = ErrID_Fatal - RETURN - END IF +CONTAINS + LOGICAL FUNCTION Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SDOut_Init') + Failed = ErrStat >= AbortErrLev + END FUNCTION Failed + + !> Returns true if an element is connected to node iNode, and along member iMember + LOGICAL FUNCTION ThisElementIsAlongMember(iElem, iNode, iMember) + integer(IntKi), intent(in) :: iElem !< Element index + integer(IntKi), intent(in) :: iNode !< Node index + integer(IntKi), intent(in) :: iMember !< Member index + integer(IntKi), dimension(2) :: ElemNodes ! Node IDs for element under consideration (may not be consecutive numbers) + integer(IntKi) :: iOtherNode ! Other node than iNode for element iElem + ElemNodes = p%Elems(iElem,2:3) ! 1st and 2nd node of the element + ! Check that the other node belongs to the member + IF (ElemNodes(1) == iNode) then + iOtherNode=ElemNodes(2) + else if (ElemNodes(2) == iNode) then + iOtherNode=ElemNodes(1) + else + ThisElementIsAlongMember=.false. ! Not along member since nodes don't match + return + endif + ! Being along the member means the second node of the element is in the node list of the member + ThisElementIsAlongMember= ANY(Init%MemberNodes(iMember,:) == iOtherNode) + END FUNCTION + + !> Set different "data" for a given output node, and possibly store more than one "data" per node: + !! The "data" is: + !! - Mass, stiffness matrices and constant element force (gravity and cable) + !! - A flag whether the node is the 1st or second node of an element + !! The "data" is stored at the index (iiNode,iStore): + !! - iiNode: node index within the list of nodes that are to be used for output for this member + !! - iStore: index over the number of "data" stored per node. E.g. Member1 and 2 connecting to a node + SUBROUTINE ConfigOutputNode_MKF_ID(pLst, iElem, iiNode, iStore, NodeID2) + type(MeshAuxDataType), intent(inout) :: pLst !< Info for one member output + integer(IntKi) , intent(in) :: iElem !< Element index to which the node belong + integer(IntKi) , intent(in) :: iiNode !< Index over the nodes of a given member (>2 if nDIV>1) + integer(IntKi) , intent(in) :: iStore !< Storage index, used several informations are stored per node + integer(IntKi) , intent(in) :: NodeID2 !< If ElemNode(2) == NodeID2, then it's the second node + integer(IntKi), dimension(2) :: ElemNodes ! Node IDs for element under consideration (may not be consecutive numbers) + REAL(FEKi) :: FCe(12) ! Pretension force from cable element + pLst%ElmIDs(iiNode,iStore) = iElem ! This array has for each joint requested the elements' ID to get results for + ElemNodes = p%Elems(iElem,2:3) ! 1st and 2nd node of the k-th element + if (ElemNodes(2) == NodeID2) then + pLst%ElmNds(iiNode,iStore) = 2 ! store whether first or second node of element + else + pLst%ElmNds(iiNode,iStore) = 1 ! store whether first or second node of element + endif + ! --- Element Me, Ke, Fg, Fce + CALL ElemM(p%ElemProps(iElem), pLst%Me(:,:,iiNode,iStore)) + CALL ElemK(p%ElemProps(iElem), pLst%Ke(:,:,iiNode,iStore)) + CALL ElemF(p%ElemProps(iElem), Init%g, pLst%Fg(:,iiNode,iStore), FCe) + ! NOTE: Removing this force contribution for now (maybe put Tension only?) + ! The output of subdyn will just be the "Kx" part for now + !pLst%Fg(:,iiNode,iStore) = pLst%Fg(:,iiNode,iStore) + FCe(1:12) ! Adding cable element force + pLst%Fg(:,iiNode,iStore) = 0.0_ReKi + END SUBROUTINE ConfigOutputNode_MKF_ID - - DO I = 1,p%NumOuts+p%OutAllint*p%OutAllDims - InitOut%WriteOutputHdr(I) = TRIM( p%OutParam(I)%Name ) - InitOut%WriteOutputUnt(I) = TRIM( p%OutParam(I)%Units ) - END DO - - -RETURN END SUBROUTINE SDOut_Init - !------------------------------------------------------------------------------------------------------ -SUBROUTINE ReactMatx(Init, p, WtrDpth, ErrStat, ErrMsg) -!This subroutine allocates and calculated TIreact, Matrix to go from local reactions at constrained nodes to single point reactions - TYPE(SD_InitType), INTENT( IN) :: Init ! Input data for initialization routine - TYPE(SD_ParameterType), INTENT( INOUT) :: p ! Parameter data - REAL(ReKi), INTENT(IN) :: WtrDpth - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - ! local variables - INTEGER :: I !counter - INTEGER :: rmndr !type-column index - INTEGER :: n !node ID - INTEGER(IntKi) :: DOFC ! DOFC = Init%NReact*6 - REAL(ReKi) :: x, y, z !coordinates - - !Initialize - ErrStat=ErrID_None - ErrMsg="" - - DOFC = p%NReact*6 ! bjj, this is p%DOFC !Total DOFs at the base of structure - - ALLOCATE ( p%TIreact(6,DOFC), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for TIreact array.' - ErrStat = ErrID_Fatal - RETURN - END IF - - p%TIreact=0 !Initialize - - DO I=1,3 !Take care of first three rows - p%TIreact(I,I:DOFC:6)=1 - ENDDO - - !Other rows done per column actually - DO I = 1, DOFC - - n = p%Reacts(ceiling(I/6.0),1) !Constrained Node ID (this works in the reordered/renumbered p%Reacts) - - x = Init%Nodes(n, 2) - y = Init%Nodes(n, 3) - z = Init%Nodes(n, 4) + WtrDpth - - rmndr = MOD(I, 6) !It gives me the column index among the 6 different kinds - SELECT CASE (rmndr) - CASE (1) - p%TIreact(4:6, I) = (/0.0_ReKi, z, -y/) - - CASE (2) - p%TIreact(4:6, I) = (/-z, 0.0_ReKi, x/) - - CASE (3) - p%TIreact(4:6, I) = (/y, -x, 0.0_ReKi/) - - CASE (4) - p%TIreact(4:6, I) = (/1.0_ReKi, 0.0_ReKi, 0.0_ReKi/) - - CASE (5) - p%TIreact(4:6, I) = (/0.0_ReKi, 1.0_ReKi, 0.0_ReKi/) - - CASE (0) - p%TIreact(4:6, I) = (/0.0_ReKi, 0.0_ReKi, 1.0_ReKi/) - - CASE DEFAULT - ErrStat = ErrID_Fatal - ErrMsg = 'Error calculating transformation matrix TIreact ' - RETURN - END SELECT - - ENDDO - - -END SUBROUTINE ReactMatx - -!==================================================================================================== -SUBROUTINE SDOut_MapOutputs( CurrentTime, u,p,x, y, m, AllOuts, ErrStat, ErrMsg ) -! This subroutine writes the data stored in the y variable to the correct indexed postions in WriteOutput -! This is called by SD_CalcOutput() at each time step. -! This routine does fill Allouts -! note that this routine assumes m%u_TP and m%udotdot_TP have been set before calling -! this routine (which is done in SD_CalcOutput() and SD CalcContStateDeriv) -!---------------------------------------------------------------------------------------------------- - REAL(DbKi), INTENT( IN ) :: CurrentTime ! Current simulation time in seconds - TYPE(SD_InputType), INTENT( IN ) :: u ! SubDyn module's input data - TYPE(SD_ContinuousStateType), INTENT( IN ) :: x ! SubDyn module's states data - TYPE(SD_OutputType), INTENT( INOUT ) :: y ! SubDyn module's output data - TYPE(SD_ParameterType), INTENT( IN ) :: p ! SubDyn module's parameter data - TYPE(SD_MiscVarType), INTENT( INOUT ) :: m ! Misc/optimization variables - REAL(ReKi), INTENT( OUT ) :: AllOuts(0:MaxOutPts+p%OutAllInt*p%OutAllDims) ! Array of output data for all possible outputs - INTEGER(IntKi), INTENT( OUT ) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - +!> Writes the data stored in the y variable to the correct indexed postions in WriteOutput +!! This is called by SD_CalcOutput() at each time step. +!! This routine does fill Allouts +!! note that this routine assumes m%u_TP and m%udotdot_TP have been set before calling +!! this routine (which is done in SD_CalcOutput() and SD CalcContStateDeriv) +SUBROUTINE SDOut_MapOutputs(u,p,x, y, m, AllOuts, ErrStat, ErrMsg ) + type(SD_InputType), intent( in ) :: u ! SubDyn module's input data + type(SD_ContinuousStateType), intent( in ) :: x ! SubDyn module's states data + type(SD_OutputType), intent( inout ) :: y ! SubDyn module's output data + type(SD_ParameterType), target,intent( in ) :: p ! SubDyn module's parameter data + type(SD_MiscVarType), intent( inout ) :: m ! Misc/optimization variables + real(ReKi), intent( out ) :: AllOuts(0:MaxOutPts+p%OutAllInt*p%OutAllDims) ! Array of output data for all possible outputs + integer(IntKi), intent( out ) :: ErrStat ! Error status of the operation + character(*), intent( out ) :: ErrMsg ! Error message if ErrStat /= ErrID_None !locals - INTEGER(IntKi) ::I,J,K,K2,L,L2 ! Counters - INTEGER(IntKi), DIMENSION(2) ::K3 ! It stores Node IDs for element under consideration (may not be consecutive numbers) - INTEGER(IntKi) :: maxOutModes ! maximum modes to output, the minimum of 99 or p%Nmodes - REAL(ReKi), DIMENSION (6) :: FM_elm, FK_elm, junk !output static and dynamic forces and moments - REAL(ReKi), DIMENSION (6) :: FM_elm2, FK_elm2 !output static and dynamic forces and moments - Real(ReKi), DIMENSION (3,3) :: DIRCOS !direction cosice matrix (global to local) (3x3) - Real(ReKi), ALLOCATABLE :: ReactNs(:) !6*Nreact reactions - REAL(ReKi) :: Tmp_Udotdot(12), Tmp_y2(12) !temporary storage for calls to CALC_LOCAL - - Real(reKi), DIMENSION( p%URbarL+p%DOFL+6*p%Nreact) :: yout ! modifications to Y2 and Udotdot to include constrained node DOFs - Real(ReKi), DIMENSION(p%URbarL+p%DOFL+6*p%Nreact) ::uddout ! modifications to Y2 and Udotdot to include constrained node DOFs - Integer(IntKi) ::sgn !+1/-1 for node force calculations + integer(IntKi) :: iMemberOutput, iiNode, iSDNode, iMeshNode, I, J, L, L2 ! Counters + integer(IntKi) :: maxOutModes ! maximum modes to output, the minimum of 99 or p%nDOFM + real(ReKi), dimension (6) :: FM_elm, FK_elm, Fext !output static and dynamic forces and moments + real(ReKi), dimension (6) :: FM_elm2, FK_elm2 !output static and dynamic forces and moments + real(FEKi), dimension (3,3) :: DIRCOS !direction cosice matrix (global to local) (3x3) + real(ReKi), allocatable :: ReactNs(:) !6*Nreact reactions + integer(IntKi) :: sgn !+1/-1 for node force calculations + type(MeshAuxDataType), pointer :: pLst !< Info for a given member-output (Alias to shorten notation) + integer(IntKi), pointer :: DOFList(:) !< List of DOF indices for a given Nodes (Alias to shorten notation) ErrStat = ErrID_None ErrMsg = "" AllOuts = 0.0_ReKi ! initialize for those outputs that aren't valid (and thus aren't set in this routine) - - !Create a variable that lists Y2 and adds removed constrained nodes' dofs; we will be using it to carry out other calculations with a special indexing array - yout =0 !Initialize and populate with Y2 data - yout(1: p%UrbarL ) = m%UR_bar - yout(p%URbarL+1:p%URbarL+p%DOFL) = m%UL - - !Same for a variable that deals with Udotdot - uddout =0 !Initialize and populate with Udotdot data - uddout(1 : p%URbarL ) = m%UR_bar_dotdot - uddout(p%URbarL+1 : p%URbarL+p%DOFL ) = m%UL_dotdot - ! Only generate member-based outputs for the number of user-requested member outputs - !Now store and identify needed output as requested by user - !p%MOutLst has the mapping for the member, node, elements per node, to be used - !MXNYZZZ will need to connects to p%MOutLst(X)%ElmIDs(Y,1:2) if it is a force or accel; else to u%UFL(p%MOutLst(X)%NodeIDs(Y)) - !Inertial Load for the elements that are needed - if (p%NumOuts > 0) then !bjj: some of these fields aren't allocated when NumOuts==0 - DO I=1,p%NMOutputs - !I know el # and whether it is 1st node or second node - DO J=1,p%MoutLst(I)%NOutCnt !Iterate on requested nodes for that member - !I need to average across potentially up to 2 elements - !Calculate forces on 1st stored element, and if 2nd exists do averaging with the second - K=p%MOutLst(I)%ElmIDs(J,1) !element number - K2=p%MOutLst(I)%ElmNds(J,1) !first or second node of the element to be considered - !Assign the sign depending on whether it is the 1st or second node - sgn=-1 - IF (K2 .EQ. 2) sgn= +1 - - K3=p%Elems(K,2:3) !first and second node ID associated with element K - - L=p%IDY((K3(1)-1)*6+1)! starting index for node K3(1) within yout - L2=p%IDY((K3(2)-1)*6+1)! starting index for node K3(2) within yout - - DIRCOS=tranSpose(p%elemprops(K)%DirCos)! global to local dir-cosine matrix - - !I need to find the Udotdot() for the two nodes of the element of interest - !I need to move the displacements to the local ref system - - ! bjj: added these temporary storage variables so that the CALC_LOCAL call doesn't created - ! new temporary *every time* it's called - Tmp_Udotdot(1: 6) = uddout( L : L+5 ) - Tmp_Udotdot(7:12) = uddout( L2 : L2+5 ) - - Tmp_y2(1: 6) = yout( L : L+5 ) - Tmp_y2(7:12) = yout( L2 : L2+5 ) - - CALL CALC_LOCAL( DIRCOS,p%MOutLst(I)%Me(:,:,J,1),p%MOutLst(I)%Ke(:,:,J,1),Tmp_Udotdot, & - Tmp_y2,p%MoutLst(I)%Fg(:,J,1), K2,FM_elm,FK_elm) - - FM_elm2=sgn*FM_elm - FK_elm2=sgn*FK_elm - - IF (p%MOutLst(I)%ElmIDs(J,p%NavgEls) .NE. 0) THEN !element number - K=p%MOutLst(I)%ElmIDs(J,p%NavgEls) !element number - K2=p%MOutLst(I)%ElmNds(J,p%NavgEls) !first or second node of the element to be considered - !Assign the sign depending on whether it is the 1st or second node - sgn=-1 - IF (K2 .EQ. 2) sgn= +1 - - K3=p%Elems(K,2:3) !first and second node ID associated with element K - - L=p%IDY((K3(1)-1)*6+1)! starting index for node K3(1) within yout - L2=p%IDY((K3(2)-1)*6+1)! starting index for node K3(2) within yout - CALL CALC_LOCAL(DIRCOS,p%MOutLst(I)%Me(:,:,J,p%NavgEls),p%MOutLst(I)%Ke(:,:,J,p%NavgEls),(/uddout( L : L+5 ),uddout( L2 : L2+5 )/), & - (/yout( L : L+5 ), yout( L2 : L2+5 )/), p%MoutLst(I)%Fg(:,J,p%NavgEls), K2,FM_elm,FK_elm ) - - FM_elm2=0.5*( FM_elm2 + sgn*FM_elm ) !Now Average - FK_elm2=0.5*( FK_elm2 + sgn*FK_elm) !Now Average - ENDIF - - !NOW HERE I WOULD NEED TO PUT IT INTO AllOuts - !Forces and moments - AllOuts(MNfmKe (:,J,I)) = FK_elm2 !static forces and moments (6) Local Ref - AllOuts(MNfmMe (:,J,I)) = FM_elm2 !dynamic forces and moments (6) Local Ref - !Displacement- Translational -no need for averaging since it is a node translation - In global reference SS - L=p%IDY( (p%MOutLst(I)%NodeIDs(J)-1)*6 +1 )! starting index for nodeID(J) within yout - AllOuts(MNTDss (:,J,I)) = yout(L:L+2) - !Displacement- Rotational - I need to get the direction cosine matrix to tranform rotations - In Local reference Element Ref Sys - - AllOuts(MNRDe (:,J,I)) = matmul(DIRCOS,yout(L+3:L+5) ) !local ref - !Accelerations- I need to get the direction cosine matrix to tranform displacement and rotations - AllOuts(MNTRAe (1:3,J,I)) = matmul(DIRCOS,uddout(L:L+2) ) !translational accel local ref - AllOuts(MNTRAe (4:6,J,I)) = matmul(DIRCOS,uddout(L+3:L+5) ) !rotational accel local ref - - - - ENDDO - - ENDDO + ! -------------------------------------------------------------------------------- + ! --- Requested member-outputs (Node kinematics and loads) + ! -------------------------------------------------------------------------------- + ! p%MOutLst has the mapping for the member, node, elements per node, to be used + ! MXNYZZZ will need to connects to p%MOutLst(X)%ElmIDs(Y,1:2) if it is a force or accel; else to u%UFL(p%MOutLst(X)%NodeIDs(Y)) + if (p%NumOuts > 0) then !bjj: some of these fields aren't allocated when NumOuts==0 + ! Loop over member-outputs requested + DO iMemberOutput=1,p%NMOutputs + pLst=>p%MOutLst(iMemberOutput) ! List for a given member-output + DO iiNode=1,pLst%NOutCnt !Iterate on requested nodes for that member + ! --- Forces (potentially averaged on 2 elements) + call ElementForce(pLst, iiNode, 1, FM_elm, FK_elm, sgn, DIRCOS, .false.) + FM_elm2=sgn*FM_elm + FK_elm2=sgn*FK_elm + IF (pLst%ElmIDs(iiNode,2) .NE. 0) THEN ! Second element exist + ! NOTE: forces are computed in the coordinate system of the first element for averaging + call ElementForce(pLst, iiNode, 2, FM_elm, FK_elm, sgn, DIRCOS, .true.) ! True= we use DIRCOS from element above + FM_elm2=0.5*( FM_elm2 + sgn*FM_elm ) ! Now Average + FK_elm2=0.5*( FK_elm2 + sgn*FK_elm) ! Now Average + ENDIF + ! Static (elastic) component of reaction forces and moments at MαNβ along local member coordinate system + ! "MαNβFKxe, MαNβFKye, MαNβFKze, MαNβMKxe, MαNβMKye, MαNβMKze" + AllOuts(MNfmKe (:,iiNode,iMemberOutput)) = FK_elm2 !static forces and moments (6) Local Ref + ! Dynamic (inertial) component of reaction forces and moments at MαNβ along local member coordinate system + ! "MαNβFMxe, MαNβFMye, MαNβFMze, MαNβMMxe, MαNβMMye, MαNβMMze" + AllOuts(MNfmMe (:,iiNode,iMemberOutput)) = FM_elm2 !dynamic forces and moments (6) Local Ref + + ! --- Displacements and acceleration + DOFList => p%NodesDOF(pLst%NodeIDs(iiNode))%List + ! Displacement- Translational -no need for averaging since it is a node translation - In global reference SS + ! "MαNβTDxss, MαNβTDyss, MαNβTDzss" + AllOuts(MNTDss (:,iiNode,iMemberOutput)) = m%U_full(DOFList(1:3)) + ! Displacement- Rotational - need direction cosine matrix to tranform rotations - In Local reference Element Ref Sys + ! "MαNβRDxss, MαNβRDye, MαNβRDze" + AllOuts(MNRDe (:,iiNode,iMemberOutput)) = matmul(DIRCOS,m%U_full(DOFList(4:6))) !local ref + ! Accelerations- I need to get the direction cosine matrix to tranform displacement and rotations + ! "MαNβTAxe, MαNβTAye, MαNβTAze" + ! "MαNβRAxe, MαNβRAye, MαNβRAze" + AllOuts(MNTRAe (1:3,iiNode,iMemberOutput)) = matmul(DIRCOS,m%U_full_dotdot(DOFList(1:3))) ! translational accel local ref + AllOuts(MNTRAe (4:6,iiNode,iMemberOutput)) = matmul(DIRCOS,m%U_full_dotdot(DOFList(4:6))) ! rotational accel local ref + ENDDO ! iiNode, Loop on requested nodes for that member + ENDDO ! iMemberOutput, Loop on member outputs END IF - - IF (p%OutAll) THEN !NEED TO CALCULATE TOTAL FORCES - - DO I=1,p%NMembers !Cycle on all members - DO J=1,2 !Iterate on requested nodes for that member (first and last) - K=p%MOutLst2(I)%ElmID2s(J) !element number - K2=p%MOutLst2(I)%ElmNd2s(J) !first or second node of the element to be considered - - !Assign the sign depending on whether it is the 1st or second node - sgn=-1 - IF (K2 .EQ. 2) sgn= +1 - - K3=p%Elems(K,2:3) !first and second node ID associated with element K - - L=p%IDY((K3(1)-1)*6+1)! starting index for node K3(1) within yout - L2=p%IDY((K3(2)-1)*6+1)! starting index for node K3(2) within yout - - DIRCOS=tranSpose(p%elemprops(K)%DirCos)! global to local - - CALL CALC_LOCAL( DIRCOS,p%MOutLst2(I)%Me2(:,:,J),p%MOutLst2(I)%Ke2(:,:,J),(/uddout( L : L+5 ),uddout( L2 : L2+5 )/), & - (/yout( L : L+5 ), yout( L2 : L2+5 )/), p%MoutLst2(I)%Fg2(:,J), K2,FM_elm,FK_elm) - - ! FM_elm2=sgn*FM_elm - ! FK_elm2=sgn*FK_elm - - !NOW HERE I WOULD NEED TO PUT IT INTO AllOuts - L=MaxOutPts+(I-1)*24+(J-1)*12+1!start index - L2=L+11 - AllOuts( L:L2 ) =sgn* (/FK_elm,FM_elm/) - - ENDDO - ENDDO - - ENDIF - - - !Assign interface forces and moments - AllOuts(IntfSS(1:TPdofL))= - (/y%Y1Mesh%Force (:,1), y%Y1Mesh%Moment(:,1)/) !-y%Y1 !Note this is the force that the TP applies to the Jacket, opposite to what the GLue Code needs thus "-" sign - - !Assign interface translations and rotations at the TP ref point - AllOuts(IntfTRss(1:TPdofL))=m%u_TP - - !Assign interface translations and rotations accelerations - AllOuts(IntfTRAss(1:TPdofL))= m%udotdot_TP + ! -------------------------------------------------------------------------------- + ! --- All nodal loads from stiffness and mass matrix + ! -------------------------------------------------------------------------------- + ! "MaaaJbFKxe, MaaaJbMKxe MaaaJbFMxe, MaaaJbMMxe for member aaa and node b." + IF (p%OutAll) THEN + DO iMemberOutput=1,p%NMembers !Cycle on all members + pLst=>p%MOutLst2(iMemberOutput) + DO iiNode=1,2 !Iterate on requested nodes for that member (first and last) + call ElementForce(pLst, iiNode, 1, FM_elm, FK_elm, sgn, DIRCOS, .false.) + ! Store in All Outs + L = MaxOutPts+(iMemberOutput-1)*24+(iiNode-1)*12+1 + L2 = L+11 + AllOuts( L:L2 ) =sgn* (/FK_elm,FM_elm/) + ENDDO !iiNode, nodes 1 and 2 + ENDDO ! iMemberOutput, Loop on members + ENDIF - ! Assign all SSqm, SSqmdot, SSqmdotdot - ! We only have space for the first 99 values - maxOutModes = min(p%Nmodes,99) + ! -------------------------------------------------------------------------------- + ! --- Interface kinematics and loads (TP/platform reference point) + ! -------------------------------------------------------------------------------- + ! Total interface reaction forces and moments in SS coordinate system + ! "IntfFXss, IntfFYss, IntfFZss, IntfMXss, IntfMYss, IntfMZss," + AllOuts(IntfSS(1:nDOFL_TP))= - (/y%Y1Mesh%Force (:,1), y%Y1Mesh%Moment(:,1)/) !-y%Y1 !Note this is the force that the TP applies to the Jacket, opposite to what the GLue Code needs thus "-" sign + ! Interface translations and rotations in SS coordinate system + ! "IntfTDXss, IntfTDYss, IntfTDZss, IntfRDXss, IntfRDYss IntfRDZss" + AllOuts(IntfTRss(1:nDOFL_TP))=m%u_TP + ! Interface Translational and rotational accelerations in SS coordinate system + ! "IntfTAXss, IntfTAYss, IntfTAZss, IntfRAXss, IntfRAYss IntfRAZss" + AllOuts(IntfTRAss(1:nDOFL_TP))= m%udotdot_TP + + ! -------------------------------------------------------------------------------- + ! --- Modal parameters "SSqmXX, SSqmdotXX, SSqmddXX" amplitude, speed and acceleration + ! -------------------------------------------------------------------------------- + maxOutModes = min(p%nDOFM,99) ! We only have space for the first 99 values IF ( maxOutModes > 0 ) THEN !BJJ: TODO: is there a check to see if we requested these channels but didn't request the modes? (i.e., retain 2 modes but asked for 75th mode?) - Allouts(SSqm01 :SSqm01 +maxOutModes-1) = x%qm (1:maxOutModes) - Allouts(SSqmd01 :SSqmd01 +maxOutModes-1) = x%qmdot (1:maxOutModes) - Allouts(SSqmdd01:SSqmdd01+maxOutModes-1) = m%qmdotdot(1:maxOutModes) + AllOuts(SSqm01 :SSqm01 +maxOutModes-1) = x%qm (1:maxOutModes) + AllOuts(SSqmd01 :SSqmd01 +maxOutModes-1) = x%qmdot (1:maxOutModes) + AllOuts(SSqmdd01:SSqmdd01+maxOutModes-1) = m%qmdotdot(1:maxOutModes) END IF - !Need to Calculate Reaction Forces Now, but only if requested - IF (p%OutReact) THEN - - ALLOCATE ( ReactNs(6*p%NReact), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN + ! --------------------------------------------------------------------------------} + ! --- Base reaction loads + ! --------------------------------------------------------------------------------{ + ! Total base reaction forces and moments at the (0.,0.,-WtrDpth) location in SS coordinate system + ! "ReactFXss, ReactFYss, ReactFZss, ReactMXss, ReactMYss, ReactMZss" + IF (p%OutReact) THEN + ALLOCATE ( ReactNs(6*p%nNodes_C), STAT = ErrStat ) + IF ( ErrStat /= ErrID_None ) THEN ErrMsg = ' Error allocating space for ReactNs array.' ErrStat = ErrID_Fatal RETURN - END IF - - ReactNs = 0.0 !Initialize - - DO I=1,p%NReact !Do for each constrained node, they are ordered as given in the input file and so as in the order of y2mesh - - FK_elm2=0. !Initialize - FM_elm2=0. !Initialize - - !Find the joint forces - DO J=1,SIZE(p%MOutLst3(I)%ElmIDs(1,:)) !for all the elements connected (normally 1) - - K=p%MOutLst3(I)%ElmIDs(1,J) !element number - K2=p%MOutLst3(I)%ElmNds(1,J) !first or second node of the element to be considered - - !Assign the sign depending on whether it is the 1st or second node - K3=p%Elems(K,2:3) !first and second node ID associated with element K - - L =p%IDY((K3(1)-1)*6+1)! starting index for node K3(1) within yout - L2=p%IDY((K3(2)-1)*6+1)! starting index for node K3(2) within yout - - DIRCOS=tranSpose(p%elemprops(K)%DirCos)! global to local - - CALL CALC_LOCAL( DIRCOS,p%MOutLst3(I)%Me(:,:,1,J),p%MOutLst3(I)%Ke(:,:,1,J),(/uddout( L : L+5 ),uddout( L2 : L2+5 )/), & - (/yout( L : L+5 ), yout( L2 : L2+5 )/), p%MoutLst3(I)%Fg(:,1,J), K2,FM_elm,FK_elm) - - !transform back to global, need to do 3 at a time since cosine matrix is 3x3 - DO L=1,2 - FM_elm2((L-1)*3+1:L*3) = FM_elm2((L-1)*3+1:L*3) + matmul(p%elemprops(K)%DirCos,FM_elm((L-1)*3+1:L*3)) !sum forces at joint in GLOBAL REF - FK_elm2((L-1)*3+1:L*3) = FK_elm2((L-1)*3+1:L*3) + matmul(p%elemprops(K)%DirCos,FK_elm((L-1)*3+1:L*3)) !signs may be wrong, we will fix that later; - ! I believe this is all fixed in terms of signs now ,RRD 5/20/13 - ENDDO - - ENDDO - !junk= FK_elm2 ! + FM_elm2 !removed the inertial component 12/13 !Not sure why I need an intermediate step here, but the sum would not work otherwise - - !NEED TO ADD HYDRODYNAMIC FORCES AT THE RESTRAINT NODES - ! The joind iD of the reaction, i.e. thre reaction node ID is within p%MOutLst3(I)%Noutcnt - !The index in Y2mesh is? - !Since constrained nodes are ordered as given in the input file and so as in the order of y2mesh, i Can do: - junk = (/u%LMesh%Force(:,p%NNodes_I+p%NNodes_L+I),u%LMesh%Moment(:,p%NNodes_I+p%NNodes_L+I)/) - - ReactNs((I-1)*6+1:6*I)=FK_elm2 - junk !Accumulate reactions from all nodes in GLOBAL COORDINATES - ENDDO - - !NOW HERE I WOULD NEED TO PUT IT INTO AllOuts - - AllOuts( ReactSS(1:TPdofL) ) = matmul(p%TIreact,ReactNs) - ENDIF - + END IF + ReactNs = 0.0_ReKi !Initialize + DO I=1,p%nNodes_C !Do for each constrained node, they are ordered as given in the input file and so as in the order of y2mesh + FK_elm2=0._ReKi !Initialize for cumulative force + FM_elm2=0._ReKi !Initialize + pLst => p%MOutLst3(I) + !Find the joint forces + DO J=1,SIZE(pLst%ElmIDs(1,:)) !for all the elements connected (normally 1) + iiNode = 1 + call ElementForce(pLst, iiNode, J, FM_elm, FK_elm, sgn, DIRCOS, .false.) + !transform back to global, need to do 3 at a time since cosine matrix is 3x3 + DO L=1,2 + FM_elm2((L-1)*3+1:L*3) = FM_elm2((L-1)*3+1:L*3) + matmul(transpose(DIRCOS),FM_elm((L-1)*3+1:L*3)) !sum forces at joint in GLOBAL REF + FK_elm2((L-1)*3+1:L*3) = FK_elm2((L-1)*3+1:L*3) + matmul(transpose(DIRCOS),FK_elm((L-1)*3+1:L*3)) !signs may be wrong, we will fix that later; + ! I believe this is all fixed in terms of signs now ,RRD 5/20/13 + ENDDO + ENDDO + ! FK_elm2 ! + FM_elm2 !removed the inertial component 12/13 !Not sure why I need an intermediate step here, but the sum would not work otherwise + ! NEED TO ADD HYDRODYNAMIC FORCES AT THE RESTRAINT NODES + iSDNode = p%Nodes_C(I,1) + iMeshNode = iSDNode ! input and Y2 mesh nodes are the same as subdyn + Fext = (/ u%LMesh%Force(:,iMeshNode), u%LMesh%Moment(:,iMeshNode) /) + ReactNs((I-1)*6+1:6*I) = FK_elm2 - Fext !Accumulate reactions from all nodes in GLOBAL COORDINATES + ENDDO + ! Store into AllOuts + AllOuts( ReactSS(1:nDOFL_TP) ) = matmul(p%TIreact,ReactNs) + ENDIF if (allocated(ReactNs)) deallocate(ReactNs) - -END SUBROUTINE SDOut_MapOutputs +contains + + subroutine ElementForce(pLst, iiNode, JJ, FM_elm, FK_elm, sgn, DIRCOS, bUseInputDirCos) + type(MeshAuxDataType), intent(in) :: pLst !< Info for one member output + integer(IntKi) , intent(in) :: iiNode !< Index over the nodes of a given member (>2 if nDIV>1) + integer(IntKi) , intent(in) :: JJ !< TODO: interpretation: index over other member connected to the current member (for averaging) + real(FEKi), dimension (3,3), intent(inout) :: DIRCOS !direction cosice matrix (global to local) (3x3) + real(ReKi), dimension (6), intent(out) :: FM_elm, FK_elm !output static and dynamic forces and moments + integer(IntKi), intent(out) :: sgn !+1/-1 for node force calculations + logical, intent(in) :: bUseInputDirCos !< If True, use DIRCOS from input, otherwise, use element DirCos + ! Local + integer(IntKi) :: iElem !< Element index/number + integer(IntKi) :: FirstOrSecond !< 1 or 2 if first node or second node + integer(IntKi), dimension(2) :: ElemNodes ! Node IDs for element under consideration (may not be consecutive numbers) + real(ReKi) , dimension(12) :: X_e, Xdd_e ! Displacement and acceleration for an element + integer(IntKi), dimension(2), parameter :: NodeNumber_To_Sign = (/-1, +1/) + + iElem = pLst%ElmIDs(iiNode,JJ) ! element number + FirstOrSecond = pLst%ElmNds(iiNode,JJ) ! first or second node of the element to be considered + sgn = NodeNumber_To_Sign(FirstOrSecond) ! Assign sign depending if it's the 1st or second node + ElemNodes = p%Elems(iElem,2:3) ! first and second node ID associated with element iElem + X_e(1:6) = m%U_full_elast (p%NodesDOF(ElemNodes(1))%List(1:6)) + X_e(7:12) = m%U_full_elast (p%NodesDOF(ElemNodes(2))%List(1:6)) + Xdd_e(1:6) = m%U_full_dotdot(p%NodesDOF(ElemNodes(1))%List(1:6)) + Xdd_e(7:12) = m%U_full_dotdot(p%NodesDOF(ElemNodes(2))%List(1:6)) + if (.not. bUseInputDirCos) then + DIRCOS=transpose(p%ElemProps(iElem)%DirCos)! global to local + endif + CALL CALC_NODE_FORCES( DIRCOS, pLst%Me(:,:,iiNode,JJ),pLst%Ke(:,:,iiNode,JJ), Xdd_e, X_e, pLst%Fg(:,iiNode,JJ), FirstOrSecond, FM_elm, FK_elm) + end subroutine ElementForce -!==================================================================================================== - SUBROUTINE CALC_LOCAL(DIRCOS,Me,Ke,Udotdot,Y2,Fg, K2,FM_elm,FK_elm) - !This function calculates for the given element the static and dynamic forces, given K and M of the element, and + !==================================================================================================== + !> Calculates static and dynamic forces for a given element, using K and M of the element, and !output quantities Udotdot and Y2 containing the !and K2 indicating wheter the 1st (1) or 2nd (2) node is to be picked -!---------------------------------------------------------------------------------------------------- - Real(ReKi), DIMENSION (3,3), INTENT(IN) :: DIRCOS !direction cosice matrix (global to local) (3x3) - Real(ReKi), DIMENSION (12,12), INTENT(IN) :: Me,Ke !element M and K matrices (12x12) in GLOBAL REFERENCE (DIRCOS^T K DIRCOS) - Real(ReKi), DIMENSION (12), INTENT(IN) :: Udotdot, Y2, Fg !acceleration and velocities, gravity forces - Integer(IntKi), INTENT(IN) :: K2 !1 or 2 depending on node of interest - REAL(ReKi), DIMENSION (6), INTENT(OUT) :: FM_elm, FK_elm !output static and dynamic forces and moments - - !Locals - INTEGER(IntKi) ::L !counter - REAL(DbKi), DIMENSION(12) ::Junk,Junk1,Junk3,Junk4 ! temporary storage for output stuff - - Junk=matmul(Me,Udotdot) !GLOBAL REFERENCE - Junk1=matmul(Ke,Y2) !GLOBAL REFERENCE - Junk1=Junk1- Fg !GLOBAL REFERENCE - DO L=1,4 - Junk3((L-1)*3+1:L*3)= matmul(DIRCOS, Junk( (L-1)*3+1:L*3 ) ) - Junk4((L-1)*3+1:L*3) = matmul(DIRCOS, Junk1( (L-1)*3+1:L*3 ) ) - ENDDO - - - FM_elm=Junk3(6*(k2-1)+1:k2*6) - FK_elm=Junk4(6*(k2-1)+1:k2*6) - - - END SUBROUTINE CALC_LOCAL + !---------------------------------------------------------------------------------------------------- + SUBROUTINE CALC_NODE_FORCES(DIRCOS,Me,Ke,Udotdot,Y2 ,Fg, FirstOrSecond, FM_nod, FK_nod) + Real(FEKi), DIMENSION (3,3), INTENT(IN) :: DIRCOS !direction cosice matrix (global to local) (3x3) + Real(FEKi), DIMENSION (12,12), INTENT(IN) :: Me,Ke !element M and K matrices (12x12) in GLOBAL REFERENCE (DIRCOS^T K DIRCOS) + Real(ReKi), DIMENSION (12), INTENT(IN) :: Udotdot, Y2 !acceleration and velocities, gravity forces + Real(FEKi), DIMENSION (12), INTENT(IN) :: Fg !acceleration and velocities, gravity forces + Integer(IntKi), INTENT(IN) :: FirstOrSecond !1 or 2 depending on node of interest + REAL(ReKi), DIMENSION (6), INTENT(OUT) :: FM_nod, FK_nod !output static and dynamic forces and moments + !Locals + INTEGER(IntKi) :: L !counter + REAL(DbKi), DIMENSION(12) :: FM_glb, FF_glb, FM_elm, FF_elm ! temporary storage + + FM_glb = matmul(Me,Udotdot) ! GLOBAL REFERENCE + FF_glb = matmul(Ke,Y2) ! GLOBAL REFERENCE + FF_glb = FF_glb - Fg ! GLOBAL REFERENCE ! NOTE: Fg is now 0, only the "Kx" part in Fk + DO L=1,4 ! Transforming coordinates 3 at a time + FM_elm((L-1)*3+1:L*3) = matmul(DIRCOS, FM_glb( (L-1)*3+1:L*3 ) ) + FF_elm((L-1)*3+1:L*3) = matmul(DIRCOS, FF_glb( (L-1)*3+1:L*3 ) ) + ENDDO + FM_nod = FM_elm(6*(FirstOrSecond-1)+1:FirstOrSecond*6) ! k2=1, 1:6, k2=2 7:12 + FK_nod = FF_elm(6*(FirstOrSecond-1)+1:FirstOrSecond*6) - !==================================================================================================== -SUBROUTINE SDOut_CloseSum( UnSum, ErrStat, ErrMsg ) + END SUBROUTINE CALC_NODE_FORCES +END SUBROUTINE SDOut_MapOutputs - ! Passed variables - +!==================================================================================================== +SUBROUTINE SDOut_CloseSum( UnSum, ErrStat, ErrMsg ) INTEGER, INTENT( IN ) :: UnSum ! the unit number for the SubDyn summary file INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - - ! Local variables + ! Local variables INTEGER :: Stat ! status from I/) operation - - ! Initialize ErrStat - ErrStat = ErrID_None ErrMsg = "" - - ! Write any closing information in the summary file - + ! Write any closing information in the summary file IF ( UnSum > 0 ) THEN - - WRITE (UnSum,'(/,A/)', IOSTAT=Stat) 'This summary file was closed on '//CurDate()//' at '//CurTime()//'.' + WRITE (UnSum,'(/,A/)', IOSTAT=Stat) '#This summary file was closed on '//CurDate()//' at '//CurTime()//'.' IF (Stat /= 0) THEN ErrStat = ErrID_FATAL ErrMsg = ' Problem writing to summary file.' END IF - ! Close the file - CLOSE( UnSum, IOSTAT=Stat ) IF (Stat /= 0) THEN ErrStat = ErrID_FATAL ErrMsg = TRIM(ErrMsg)//' Problem closing summary file.' END IF - IF ( ErrStat /= ErrID_None ) ErrMsg = 'SDOut_CloseSum'//TRIM(ErrMsg) - END IF - END SUBROUTINE SDOut_CloseSum !==================================================================================================== SUBROUTINE SDOut_OpenSum( UnSum, SummaryName, SD_Prog, ErrStat, ErrMsg ) - - - ! Passed variables - INTEGER, INTENT( OUT ) :: UnSum ! the unit number for the SubDyn summary file CHARACTER(*), INTENT( IN ) :: SummaryName ! the name of the SubDyn summary file TYPE(ProgDesc), INTENT( IN ) :: SD_Prog ! the name/version/date of the program INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - integer :: ErrStat2 - ! Initialize ErrStat - ErrStat = ErrID_None ErrMsg = "" - CALL GetNewUnit( UnSum ) CALL OpenFOutFile ( UnSum, SummaryName, ErrStat, ErrMsg ) @@ -4556,12 +518,9 @@ SUBROUTINE SDOut_OpenSum( UnSum, SummaryName, SD_Prog, ErrStat, ErrMsg ) RETURN END IF - - ! Write the summary file header - - WRITE (UnSum,'(/,A/)', IOSTAT=ErrStat2) 'This summary file was generated by '//TRIM( SD_Prog%Name )//& + ! Write the summary file header + WRITE (UnSum,'(/,A/)', IOSTAT=ErrStat2) '#This summary file was generated by '//TRIM( SD_Prog%Name )//& ' '//TRIM( SD_Prog%Ver )//' on '//CurDate()//' at '//CurTime()//'.' - END SUBROUTINE SDOut_OpenSum !==================================================================================================== @@ -4569,37 +528,23 @@ SUBROUTINE SDOut_OpenOutput( ProgVer, OutRootName, p, InitOut, ErrStat, ErrMsg ! This subroutine initialized the output module, checking if the output parameter list (OutList) ! contains valid names, and opening the output file if there are any requested outputs !---------------------------------------------------------------------------------------------------- - - - - ! Passed variables - + ! Passed variables TYPE(ProgDesc), INTENT( IN ) :: ProgVer CHARACTER(*), INTENT( IN ) :: OutRootName ! Root name for the output file TYPE(SD_ParameterType), INTENT( INOUT ) :: p TYPE(SD_InitOutPutType ), INTENT( IN ) :: InitOut ! INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - ! Local variables + ! Local variables INTEGER :: I ! Generic loop counter CHARACTER(1024) :: OutFileName ! The name of the output file including the full path. CHARACTER(200) :: Frmt ! a string to hold a format statement INTEGER :: ErrStat2 - - !------------------------------------------------------------------------------------------------- - ! Initialize local variables - !------------------------------------------------------------------------------------------------- ErrStat = ErrID_None ErrMsg = "" - - !------------------------------------------------------------------------------------------------- ! Open the output file, if necessary, and write the header - !------------------------------------------------------------------------------------------------- - IF ( ALLOCATED( p%OutParam ) .AND. p%NumOuts > 0 ) THEN ! Output has been requested so let's open an output file - - ! Open the file for output + ! Open the file for output OutFileName = TRIM(OutRootName)//'.out' CALL GetNewUnit( p%UnJckF ) @@ -4608,31 +553,20 @@ SUBROUTINE SDOut_OpenOutput( ProgVer, OutRootName, p, InitOut, ErrStat, ErrMsg ErrMsg = ' Error opening SubDyn-level output file: '//TRIM(ErrMsg) RETURN END IF - - ! Write the output file header - + ! Write the output file header WRITE (p%UnJckF,'(/,A/)', IOSTAT=ErrStat2) 'These predictions were generated by '//TRIM(GETNVD(ProgVer))//& ' on '//CurDate()//' at '//CurTime()//'.' WRITE(p%UnJckF, '(//)') ! add 3 lines to make file format consistant with FAST v8 (headers on line 7; units on line 8) [this allows easier post-processing] - ! Write the names of the output parameters: - + ! Write the names of the output parameters: Frmt = '(A8,'//TRIM(Int2LStr(p%NumOuts+p%OutAllInt*p%OutAllDims))//'(:,A,'//TRIM( p%OutSFmt )//'))' - WRITE(p%UnJckF,Frmt, IOSTAT=ErrStat2) TRIM( 'Time' ), ( p%Delim, TRIM( InitOut%WriteOutputHdr(I) ), I=1,p%NumOuts+p%OutAllInt*p%OutAllDims ) - - ! Write the units of the output parameters: + ! Write the units of the output parameters: WRITE(p%UnJckF,Frmt, IOSTAT=ErrStat2) TRIM( 's'), ( p%Delim, TRIM( InitOut%WriteOutputUnt(I) ), I=1,p%NumOuts+p%OutAllInt*p%OutAllDims ) - - - END IF ! there are any requested outputs - - RETURN - END SUBROUTINE SDOut_OpenOutput !==================================================================================================== @@ -4643,44 +577,26 @@ SUBROUTINE SDOut_CloseOutput ( p, ErrStat, ErrMsg ) ! This function cleans up after running the SubDyn output module. It closes the output file, ! releases memory, and resets the number of outputs requested to 0. !---------------------------------------------------------------------------------------------------- - - ! Passed variables - - TYPE(SD_ParameterType), INTENT( INOUT ) :: p ! data for this instance of the floating platform module - INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred + TYPE(SD_ParameterType), INTENT( INOUT ) :: p ! data for this instance of the floating platform module + INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - -! ! Internal variables LOGICAL :: Err - - !------------------------------------------------------------------------------------------------- - ! Initialize error information - !------------------------------------------------------------------------------------------------- ErrStat = 0 ErrMsg = "" - Err = .FALSE. - !------------------------------------------------------------------------------------------------- ! Close our output file - !------------------------------------------------------------------------------------------------- CLOSE( p%UnJckF, IOSTAT = ErrStat ) IF ( ErrStat /= 0 ) Err = .TRUE. - - - !------------------------------------------------------------------------------------------------- ! Make sure ErrStat is non-zero if an error occurred - !------------------------------------------------------------------------------------------------- IF ( Err ) ErrStat = ErrID_Fatal - RETURN END SUBROUTINE SDOut_CloseOutput !==================================================================================================== - SUBROUTINE SDOut_WriteOutputNames( UnJckF, p, ErrStat, ErrMsg ) INTEGER, INTENT( IN ) :: UnJckF ! file unit for the output file @@ -4702,17 +618,13 @@ END SUBROUTINE SDOut_WriteOutputNames !==================================================================================================== - SUBROUTINE SDOut_WriteOutputUnits( UnJckF, p, ErrStat, ErrMsg ) - INTEGER, INTENT( IN ) :: UnJckF ! file unit for the output file TYPE(SD_ParameterType), INTENT( IN ) :: p ! SubDyn module's parameter data INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - CHARACTER(200) :: Frmt ! a string to hold a format statement INTEGER :: I ! Generic loop counter - ErrStat = ErrID_None ErrMsg = "" @@ -4727,24 +639,19 @@ SUBROUTINE SDOut_WriteOutputs( UnJckF, Time, SDWrOutput, p, ErrStat, ErrMsg ) ! This subroutine writes the data stored in WriteOutputs (and indexed in OutParam) to the file ! opened in SDOut_Init() !---------------------------------------------------------------------------------------------------- - - ! Passed variables INTEGER, INTENT( IN ) :: UnJckF ! file unit for the output file REAL(DbKi), INTENT( IN ) :: Time ! Time for this output REAL(ReKi), INTENT( IN ) :: SDWrOutput(:) ! SubDyn module's output data TYPE(SD_ParameterType), INTENT( IN ) :: p ! SubDyn module's parameter data INTEGER, INTENT( OUT ) :: ErrStat ! returns a non-zero value when an error occurs CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - ! Local variables - ! REAL(ReKi) :: OutData (0:p%NumOuts) ! an output array + ! Local variables INTEGER :: I ! Generic loop counter CHARACTER(200) :: Frmt ! a string to hold a format statement + ErrStat = ErrID_None + ErrMsg = "" - - ! Initialize ErrStat and determine if it makes any sense to write output - IF ( .NOT. ALLOCATED( p%OutParam ) .OR. UnJckF < 0 ) THEN ErrStat = ErrID_Fatal ErrMsg = ' To write outputs for SubDyn there must be a valid file ID and OutParam must be allocated.' @@ -4753,18 +660,11 @@ SUBROUTINE SDOut_WriteOutputs( UnJckF, Time, SDWrOutput, p, ErrStat, ErrMsg ) ErrStat = ErrID_None END IF - ! Write the output parameters to the file - Frmt = '(F10.4,'//TRIM(Int2LStr(p%NumOuts+p%OutAllInt*p%OutAllDims))//'(:,A,'//TRIM( p%OutFmt )//'))' - WRITE(UnJckF,Frmt) Time, ( p%Delim, SDWrOutput(I), I=1,p%NumOuts+p%OutAllInt*p%OutAllDims ) - - RETURN - - END SUBROUTINE SDOut_WriteOutputs !==================================================================================================== @@ -4777,36 +677,25 @@ SUBROUTINE SDOut_ChkOutLst( OutList, p, ErrStat, ErrMsg ) ! name, and units of the output channels). ! NOTE OutParam is populated here !---------------------------------------------------------------------------------------------------- - - - - ! Passed variables - TYPE(SD_ParameterType), INTENT( INOUT ) :: p ! SubDyn module parameter data CHARACTER(ChanLen), INTENT( IN ) :: OutList (:) ! An array holding the names of the requested output channels. INTEGER, INTENT( OUT ) :: ErrStat ! a non-zero value indicates an error occurred CHARACTER(*), INTENT( OUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - ! Local variables. - + ! Local variables. INTEGER :: I,J,K ! Generic loop-counting index. INTEGER :: INDX ! Index for valid arrays - CHARACTER(ChanLen) :: OutListTmp ! A string to temporarily hold OutList(I). !CHARACTER(28), PARAMETER :: OutPFmt = "( I4, 3X,A 10,1 X, A10 )" ! Output format parameter output list. CHARACTER(ChanLen), DIMENSION(24) :: ToTUnits,ToTNames,ToTNames0 - LOGICAL :: InvalidOutput(0:MaxOutPts) ! This array determines if the output channel is valid for this configuration - LOGICAL :: CheckOutListAgain + ErrStat = ErrID_None + ErrMsg = "" InvalidOutput = .FALSE. -!End of code generated by Matlab script - ! mark invalid output channels: - - DO k=p%Nmodes+1,99 + DO k=p%nDOFM+1,99 InvalidOutput(SSqm01 +k-1) = .true. InvalidOutput(SSqmd01 +k-1) = .true. InvalidOutput(SSqmdd01+k-1) = .true. @@ -4815,7 +704,7 @@ SUBROUTINE SDOut_ChkOutLst( OutList, p, ErrStat, ErrMsg ) DO I=1,9 !I know el # and whether it is 1st node or second node if (I <= p%NMOutputs) then - INDX=p%MoutLst(I)%NOutCnt+1 + INDX=p%MOutLst(I)%NOutCnt+1 else INDX = 1 end if @@ -4832,7 +721,6 @@ SUBROUTINE SDOut_ChkOutLst( OutList, p, ErrStat, ErrMsg ) END DO END DO - !------------------------------------------------------------------------------------------------- ! ALLOCATE the OutParam array !------------------------------------------------------------------------------------------------- @@ -4852,7 +740,6 @@ SUBROUTINE SDOut_ChkOutLst( OutList, p, ErrStat, ErrMsg ) !!!p%OutParam(0)%Units = '(sec)' ! !!!p%OutParam(0)%Indx = Time !!!p%OutParam(0)%SignM = 1 - DO I = 1,p%NumOuts @@ -4898,7 +785,6 @@ SUBROUTINE SDOut_ChkOutLst( OutList, p, ErrStat, ErrMsg ) ELSE ErrMsg = p%OutParam(I)%Name//' is not an available output channel.' ErrStat = ErrID_Fatal -! RETURN p%OutParam(I)%Units = 'INVALID' p%OutParam(I)%Indx = 0 p%OutParam(I)%SignM = 0 ! this will print all zeros @@ -4909,9 +795,9 @@ SUBROUTINE SDOut_ChkOutLst( OutList, p, ErrStat, ErrMsg ) IF (p%OutAll) THEN !Finish populating the OutParam with all the joint forces and moments ToTNames0=RESHAPE(SPREAD( (/"FKxe", "FKye", "FKze", "MKxe", "MKye", "MKze", "FMxe", "FMye", "FMze", "MMxe", "MMye", "MMze"/), 2, 2), (/24/) ) ToTUnits=RESHAPE(SPREAD( (/"(N) ","(N) ","(N) ", "(N*m)","(N*m)","(N*m)", "(N) ","(N) ","(N) ", "(N*m)","(N*m)","(N*m)"/), 2, 2), (/24/) ) - DO I=1,p%Nmembers + DO I=1,p%NMembers DO K=1,2 - DO J=1,12 !looks like I cnanot vectorize TRIM etc in Fortran + DO J=1,12 TotNames(J+(K-1)*12)=TRIM("M"//Int2Lstr(I))//TRIM("J"//Int2Lstr(K))//TRIM(TotNames0(J)) ENDDO ENDDO @@ -4922,11 +808,244 @@ SUBROUTINE SDOut_ChkOutLst( OutList, p, ErrStat, ErrMsg ) p%OutParam(p%NumOuts+1:p%NumOuts+p%OutAllDims)%Indx= MaxOutPts+(/(J, J=1, p%OutAllDims)/) ENDIF - RETURN END SUBROUTINE SDOut_ChkOutLst - - !==================================================================================================== - +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +!> This routine initializes the array that maps rows/columns of the Jacobian to specific mesh fields. +!! Do not change the order of this packing without changing subroutine ! +SUBROUTINE SD_Init_Jacobian(Init, p, u, y, InitOut, ErrStat, ErrMsg) + TYPE(SD_InitType) , INTENT(IN ) :: Init !< Init + TYPE(SD_ParameterType) , INTENT(INOUT) :: p !< parameters + TYPE(SD_InputType) , INTENT(IN ) :: u !< inputs + TYPE(SD_OutputType) , INTENT(IN ) :: y !< outputs + TYPE(SD_InitOutputType) , INTENT(INOUT) :: InitOut !< Initialization output data (for Jacobian row/column names) + INTEGER(IntKi) , INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*) , INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_Init_Jacobian' + real(ReKi) :: dx, dy, dz, maxDim + ! local variables: + ErrStat = ErrID_None + ErrMsg = "" + ! --- System dimension + dx = maxval(Init%Nodes(:,2))- minval(Init%Nodes(:,2)) + dy = maxval(Init%Nodes(:,3))- minval(Init%Nodes(:,3)) + dz = maxval(Init%Nodes(:,4))- minval(Init%Nodes(:,4)) + maxDim = max(dx, dy, dz) + + ! --- System dimension + call Init_Jacobian_y(); if (Failed()) return + call Init_Jacobian_x(); if (Failed()) return + call Init_Jacobian_u(); if (Failed()) return + +contains + LOGICAL FUNCTION Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SD_Init_Jacobian') + Failed = ErrStat >= AbortErrLev + END FUNCTION Failed + !> This routine initializes the Jacobian parameters and initialization outputs for the linearized outputs. + + SUBROUTINE Init_Jacobian_y() + INTEGER(IntKi) :: index_next, i + ! Number of outputs + p%Jac_ny = y%Y1Mesh%nNodes * 6 & ! 3 forces + 3 moments at each node + + y%Y2Mesh%nNodes * 18 & ! 6 displacements + 6 velocities + 6 accelerations at each node + + p%NumOuts ! WriteOutput values + ! Storage info for each output (names, rotframe) + call AllocAry(InitOut%LinNames_y, p%Jac_ny, 'LinNames_y',ErrStat2,ErrMsg2); if(ErrStat2/=ErrID_None) return + call AllocAry(InitOut%RotFrame_y, p%Jac_ny, 'RotFrame_y',ErrStat2,ErrMsg2); if(ErrStat2/=ErrID_None) return + ! Names + index_next = 1 + call PackLoadMesh_Names( y%Y1Mesh, 'Interface displacement', InitOut%LinNames_y, index_next) + call PackMotionMesh_Names(y%Y2Mesh, 'Nodes motion' , InitOut%LinNames_y, index_next) + do i=1,p%NumOuts + InitOut%LinNames_y(i+index_next-1) = trim(InitOut%WriteOutputHdr(i))//', '//trim(InitOut%WriteOutputUnt(i)) + end do + ! RotFrame + InitOut%RotFrame_y(:) = .false. + END SUBROUTINE Init_Jacobian_y + + !> This routine initializes the Jacobian parameters and initialization outputs for the linearized continuous states. + SUBROUTINE Init_Jacobian_x() + INTEGER(IntKi) :: i + p%Jac_nx = p%nDOFM ! qm + ! allocate space for the row/column names and for perturbation sizes + CALL AllocAry(InitOut%LinNames_x , 2*p%Jac_nx, 'LinNames_x' , ErrStat2, ErrMsg2); if(ErrStat/=ErrID_None) return + CALL AllocAry(InitOut%RotFrame_x , 2*p%Jac_nx, 'RotFrame_x' , ErrStat2, ErrMsg2); if(ErrStat/=ErrID_None) return + CALL AllocAry(InitOut%DerivOrder_x, 2*p%Jac_nx, 'DerivOrder_x', ErrStat2, ErrMsg2); if(ErrStat/=ErrID_None) return + ! default perturbations, p%dx: + p%dx(1) = 2.0_ReKi*D2R_D ! deflection states in rad and rad/s + p%dx(2) = 2.0_ReKi*D2R_D ! deflection states in rad and rad/s + InitOut%RotFrame_x = .false. + InitOut%DerivOrder_x = 2 + ! set linearization output names: + do i=1,p%Jac_nx + InitOut%LinNames_x(i) = 'Craig-Bampton mode '//trim(num2lstr(i))//' amplitude, -'; + end do + do i=1,p%Jac_nx + InitOut%LinNames_x(i+p%Jac_nx) = 'First time derivative of '//trim(InitOut%LinNames_x(i))//'/s' + InitOut%RotFrame_x(i+p%Jac_nx) = InitOut%RotFrame_x(i) + end do + END SUBROUTINE Init_Jacobian_x + + SUBROUTINE Init_Jacobian_u() + REAL(R8Ki) :: perturb + INTEGER(IntKi) :: i, j, idx, nu, i_meshField + ! Number of inputs + nu = u%TPMesh%nNodes * 18 & ! 3 Translation Displacements + 3 orientations + 6 velocities + 6 accelerations at each node + + u%LMesh%nNodes * 6 ! 3 forces + 3 moments at each node + ! --- Info of linearized inputs (Names, RotFrame, IsLoad) + call AllocAry(InitOut%LinNames_u, nu, 'LinNames_u', ErrStat2, ErrMsg2); if(ErrStat2/=ErrID_None) return + call AllocAry(InitOut%RotFrame_u, nu, 'RotFrame_u', ErrStat2, ErrMsg2); if(ErrStat2/=ErrID_None) return + call AllocAry(InitOut%IsLoad_u , nu, 'IsLoad_u' , ErrStat2, ErrMsg2); if(ErrStat2/=ErrID_None) return + InitOut%RotFrame_u = .false. ! every input is on a mesh, which stores values in the global (not rotating) frame + idx = 1 + call PackMotionMesh_Names(u%TPMesh, 'TPMesh', InitOut%LinNames_u, idx) ! all 6 motion fields + InitOut%IsLoad_u(1:idx-1) = .false. ! the TPMesh inputs are not loads + InitOut%IsLoad_u(idx:) = .true. ! the remaining inputs are loads + call PackLoadMesh_Names( u%LMesh, 'LMesh', InitOut%LinNames_u, idx) + + ! --- Jac_u_indx: matrix to store index to help us figure out what the ith value of the u vector really means + ! (see perturb_u ... these MUST match ) + ! column 1 indicates module's mesh and field + ! column 2 indicates the first index (x-y-z component) of the field + ! column 3 is the node + call allocAry( p%Jac_u_indx, nu, 3, 'p%Jac_u_indx', ErrStat2, ErrMsg2); if(ErrStat2/=ErrID_None) return + idx = 1 + !Module/Mesh/Field: u%TPMesh%TranslationDisp = 1; + !Module/Mesh/Field: u%TPMesh%Orientation = 2; + !Module/Mesh/Field: u%TPMesh%TranslationVel = 3; + !Module/Mesh/Field: u%TPMesh%RotationVel = 4; + !Module/Mesh/Field: u%TPMesh%TranslationAcc = 5; + !Module/Mesh/Field: u%TPMesh%RotationAcc = 6; + do i_meshField = 1,6 + do i=1,u%TPMesh%nNodes + do j=1,3 + p%Jac_u_indx(idx,1) = i_meshField + p%Jac_u_indx(idx,2) = j !component idx: j + p%Jac_u_indx(idx,3) = i !Node: i + idx = idx + 1 + end do !j + end do !i + end do + !Module/Mesh/Field: u%LMesh%Force = 7; + !Module/Mesh/Field: u%LMesh%Moment = 8; + do i_meshField = 7,8 + do i=1,u%LMesh%nNodes + do j=1,3 + p%Jac_u_indx(idx,1) = i_meshField + p%Jac_u_indx(idx,2) = j !component idx: j + p%Jac_u_indx(idx,3) = i !Node: i + idx = idx + 1 + end do !j + end do !i + end do + + ! --- Default perturbations, p%du: + call allocAry( p%du, 8, 'p%du', ErrStat2, ErrMsg2); if(ErrStat2/=ErrID_None) return ! 8 = number of unique values in p%Jac_u_indx(:,1) + perturb = 2.0_R8Ki*D2R_D + p%du( 1) = perturb ! u%TPMesh%TranslationDisp = 1; + p%du( 2) = perturb ! u%TPMesh%Orientation = 2; + p%du( 3) = perturb ! u%TPMesh%TranslationVel = 3; + p%du( 4) = perturb ! u%TPMesh%RotationVel = 4; + p%du( 5) = perturb ! u%TPMesh%TranslationAcc = 5; + p%du( 6) = perturb ! u%TPMesh%RotationAcc = 6; + p%du( 7) = 170*maxDim**2 ! u%LMesh%Force = 7; + p%du( 8) = 14*maxDim**3 ! u%LMesh%Moment = 8; + END SUBROUTINE Init_Jacobian_u + +END SUBROUTINE SD_Init_Jacobian +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine perturbs the nth element of the u array (and mesh/field it corresponds to) +!! Do not change this without making sure subroutine beamdyn::init_jacobian is consistant with this routine! +SUBROUTINE SD_Perturb_u( p, n, perturb_sign, u, du ) + TYPE(SD_ParameterType) , INTENT(IN ) :: p !< parameters + INTEGER( IntKi ) , INTENT(IN ) :: n !< number of array element to use + INTEGER( IntKi ) , INTENT(IN ) :: perturb_sign !< +1 or -1 (value to multiply perturbation by; positive or negative difference) + TYPE(SD_InputType) , INTENT(INOUT) :: u !< perturbed SD inputs + REAL( R8Ki ) , INTENT( OUT) :: du !< amount that specific input was perturbed + ! local variables + INTEGER :: fieldIndx + INTEGER :: node + fieldIndx = p%Jac_u_indx(n,2) + node = p%Jac_u_indx(n,3) + du = p%du( p%Jac_u_indx(n,1) ) + ! determine which mesh we're trying to perturb and perturb the input: + SELECT CASE( p%Jac_u_indx(n,1) ) + CASE ( 1) !Module/Mesh/Field: u%TPMesh%TranslationDisp = 1; + u%TPMesh%TranslationDisp( fieldIndx,node) = u%TPMesh%TranslationDisp( fieldIndx,node) + du * perturb_sign + CASE ( 2) !Module/Mesh/Field: u%TPMesh%Orientation = 2; + CALL PerturbOrientationMatrix( u%TPMesh%Orientation(:,:,node), du * perturb_sign, fieldIndx ) + CASE ( 3) !Module/Mesh/Field: u%TPMesh%TranslationVel = 3; + u%TPMesh%TranslationVel( fieldIndx,node) = u%TPMesh%TranslationVel( fieldIndx,node) + du * perturb_sign + CASE ( 4) !Module/Mesh/Field: u%TPMesh%RotationVel = 4; + u%TPMesh%RotationVel(fieldIndx,node) = u%TPMesh%RotationVel(fieldIndx,node) + du * perturb_sign + CASE ( 5) !Module/Mesh/Field: u%TPMesh%TranslationAcc = 5; + u%TPMesh%TranslationAcc( fieldIndx,node) = u%TPMesh%TranslationAcc( fieldIndx,node) + du * perturb_sign + CASE ( 6) !Module/Mesh/Field: u%TPMesh%RotationAcc = 6; + u%TPMesh%RotationAcc(fieldIndx,node) = u%TPMesh%RotationAcc(fieldIndx,node) + du * perturb_sign + CASE ( 7) !Module/Mesh/Field: u%LMesh%Force = 7; + u%LMesh%Force(fieldIndx,node) = u%LMesh%Force(fieldIndx,node) + du * perturb_sign + CASE ( 8) !Module/Mesh/Field: u%LMesh%Moment = 8; + u%LMesh%Moment(fieldIndx,node) = u%LMesh%Moment(fieldIndx,node) + du * perturb_sign + END SELECT +END SUBROUTINE SD_Perturb_u +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine uses values of two output types to compute an array of differences. +!! Do not change this packing without making sure subroutine beamdyn::init_jacobian is consistant with this routine! +SUBROUTINE SD_Compute_dY(p, y_p, y_m, delta, dY) + TYPE(SD_ParameterType) , INTENT(IN ) :: p !< parameters + TYPE(SD_OutputType) , INTENT(IN ) :: y_p !< SD outputs at \f$ u + \Delta_p u \f$ or \f$ z + \Delta_p z \f$ (p=plus) + TYPE(SD_OutputType) , INTENT(IN ) :: y_m !< SD outputs at \f$ u - \Delta_m u \f$ or \f$ z - \Delta_m z \f$ (m=minus) + REAL(R8Ki) , INTENT(IN ) :: delta !< difference in inputs or states \f$ delta_p = \Delta_p u \f$ or \f$ delta_p = \Delta_p x \f$ + REAL(R8Ki) , INTENT(INOUT) :: dY(:) !< column of dYdu or dYdx: \f$ \frac{\partial Y}{\partial u_i} = \frac{y_p - y_m}{2 \, \Delta u}\f$ or \f$ \frac{\partial Y}{\partial z_i} = \frac{y_p - y_m}{2 \, \Delta x}\f$ + ! local variables: + INTEGER(IntKi) :: i ! loop over outputs + INTEGER(IntKi) :: indx_first ! index indicating next value of dY to be filled + indx_first = 1 + call PackLoadMesh_dY( y_p%Y1Mesh, y_m%Y1Mesh, dY, indx_first) + call PackMotionMesh_dY(y_p%Y2Mesh, y_m%Y2Mesh, dY, indx_first) ! all 6 motion fields + do i=1,p%NumOuts + dY(i+indx_first-1) = y_p%WriteOutput(i) - y_m%WriteOutput(i) + end do + dY = dY / (2.0_R8Ki*delta) +END SUBROUTINE SD_Compute_dY +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine perturbs the nth element of the x array (and mesh/field it corresponds to) +!! Do not change this without making sure subroutine sd_init_jacobian is consistant with this routine! +SUBROUTINE SD_Perturb_x( p, fieldIndx, mode, perturb_sign, x, dx ) + TYPE(SD_ParameterType) , INTENT(IN ) :: p !< parameters + INTEGER( IntKi ) , INTENT(IN ) :: fieldIndx !< field in the state type: 1=displacements; 2=velocities + INTEGER( IntKi ) , INTENT(IN ) :: mode !< node number + INTEGER( IntKi ) , INTENT(IN ) :: perturb_sign !< +1 or -1 (value to multiply perturbation by; positive or negative difference) + TYPE(SD_ContinuousStateType), INTENT(INOUT) :: x !< perturbed SD states + REAL( R8Ki ) , INTENT( OUT) :: dx !< amount that specific state was perturbed + if (fieldIndx==1) then + dx=p%dx(1) + x%qm(mode) = x%qm(mode) + dx * perturb_sign + else + dx=p%dx(2) + x%qmdot(mode) = x%qmdot(mode) + dx * perturb_sign + end if +END SUBROUTINE SD_Perturb_x +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine uses values of two output types to compute an array of differences. +!! Do not change this packing without making sure subroutine sd_init_jacobian is consistant with this routine! +SUBROUTINE SD_Compute_dX(p, x_p, x_m, delta, dX) + TYPE(SD_ParameterType) , INTENT(IN ) :: p !< parameters + TYPE(SD_ContinuousStateType), INTENT(IN ) :: x_p !< SD continuous states at \f$ u + \Delta_p u \f$ or \f$ x + \Delta_p x \f$ (p=plus) + TYPE(SD_ContinuousStateType), INTENT(IN ) :: x_m !< SD continuous states at \f$ u - \Delta_m u \f$ or \f$ x - \Delta_m x \f$ (m=minus) + REAL(R8Ki) , INTENT(IN ) :: delta !< difference in inputs or states \f$ delta_p = \Delta_p u \f$ or \f$ delta_p = \Delta_p x \f$ + REAL(R8Ki) , INTENT(INOUT) :: dX(:) !< column of dXdu or dXdx: \f$ \frac{\partial X}{\partial u_i} = \frac{x_p - x_m}{2 \, \Delta u}\f$ or \f$ \frac{\partial X}{\partial x_i} = \frac{x_p - x_m}{2 \, \Delta x}\f$ + INTEGER(IntKi) :: i ! loop over modes + do i=1,p%Jac_nx + dX(i) = x_p%qm(i) - x_m%qm(i) + end do + do i=1,p%Jac_nx + dX(p%Jac_nx+i) = x_p%qmdot(i) - x_m%qmdot(i) + end do + dX = dX / (2.0_R8Ki*delta) +END SUBROUTINE SD_Compute_dX END MODULE SubDyn_Output diff --git a/modules/subdyn/src/SubDyn_Output_Params.f90 b/modules/subdyn/src/SubDyn_Output_Params.f90 new file mode 100644 index 0000000000..4844a51f18 --- /dev/null +++ b/modules/subdyn/src/SubDyn_Output_Params.f90 @@ -0,0 +1,3723 @@ +module SubDyn_Output_Params + use NWTC_Library + + ! Indices for computing output channels: + ! NOTES: + ! (1) These parameters are in the order stored in "OutListParameters.xlsx" + ! (2) Array AllOuts() must be dimensioned to the value of the largest output parameter + IMPLICIT NONE + + PUBLIC + + ! Time: + INTEGER, PARAMETER :: Time = 0 + + ! Member Forces: + + INTEGER(IntKi), PARAMETER :: M1N1FKxe = 1 + INTEGER(IntKi), PARAMETER :: M1N2FKxe = 2 + INTEGER(IntKi), PARAMETER :: M1N3FKxe = 3 + INTEGER(IntKi), PARAMETER :: M1N4FKxe = 4 + INTEGER(IntKi), PARAMETER :: M1N5FKxe = 5 + INTEGER(IntKi), PARAMETER :: M1N6FKxe = 6 + INTEGER(IntKi), PARAMETER :: M1N7FKxe = 7 + INTEGER(IntKi), PARAMETER :: M1N8FKxe = 8 + INTEGER(IntKi), PARAMETER :: M1N9FKxe = 9 + INTEGER(IntKi), PARAMETER :: M2N1FKxe = 10 + INTEGER(IntKi), PARAMETER :: M2N2FKxe = 11 + INTEGER(IntKi), PARAMETER :: M2N3FKxe = 12 + INTEGER(IntKi), PARAMETER :: M2N4FKxe = 13 + INTEGER(IntKi), PARAMETER :: M2N5FKxe = 14 + INTEGER(IntKi), PARAMETER :: M2N6FKxe = 15 + INTEGER(IntKi), PARAMETER :: M2N7FKxe = 16 + INTEGER(IntKi), PARAMETER :: M2N8FKxe = 17 + INTEGER(IntKi), PARAMETER :: M2N9FKxe = 18 + INTEGER(IntKi), PARAMETER :: M3N1FKxe = 19 + INTEGER(IntKi), PARAMETER :: M3N2FKxe = 20 + INTEGER(IntKi), PARAMETER :: M3N3FKxe = 21 + INTEGER(IntKi), PARAMETER :: M3N4FKxe = 22 + INTEGER(IntKi), PARAMETER :: M3N5FKxe = 23 + INTEGER(IntKi), PARAMETER :: M3N6FKxe = 24 + INTEGER(IntKi), PARAMETER :: M3N7FKxe = 25 + INTEGER(IntKi), PARAMETER :: M3N8FKxe = 26 + INTEGER(IntKi), PARAMETER :: M3N9FKxe = 27 + INTEGER(IntKi), PARAMETER :: M4N1FKxe = 28 + INTEGER(IntKi), PARAMETER :: M4N2FKxe = 29 + INTEGER(IntKi), PARAMETER :: M4N3FKxe = 30 + INTEGER(IntKi), PARAMETER :: M4N4FKxe = 31 + INTEGER(IntKi), PARAMETER :: M4N5FKxe = 32 + INTEGER(IntKi), PARAMETER :: M4N6FKxe = 33 + INTEGER(IntKi), PARAMETER :: M4N7FKxe = 34 + INTEGER(IntKi), PARAMETER :: M4N8FKxe = 35 + INTEGER(IntKi), PARAMETER :: M4N9FKxe = 36 + INTEGER(IntKi), PARAMETER :: M5N1FKxe = 37 + INTEGER(IntKi), PARAMETER :: M5N2FKxe = 38 + INTEGER(IntKi), PARAMETER :: M5N3FKxe = 39 + INTEGER(IntKi), PARAMETER :: M5N4FKxe = 40 + INTEGER(IntKi), PARAMETER :: M5N5FKxe = 41 + INTEGER(IntKi), PARAMETER :: M5N6FKxe = 42 + INTEGER(IntKi), PARAMETER :: M5N7FKxe = 43 + INTEGER(IntKi), PARAMETER :: M5N8FKxe = 44 + INTEGER(IntKi), PARAMETER :: M5N9FKxe = 45 + INTEGER(IntKi), PARAMETER :: M6N1FKxe = 46 + INTEGER(IntKi), PARAMETER :: M6N2FKxe = 47 + INTEGER(IntKi), PARAMETER :: M6N3FKxe = 48 + INTEGER(IntKi), PARAMETER :: M6N4FKxe = 49 + INTEGER(IntKi), PARAMETER :: M6N5FKxe = 50 + INTEGER(IntKi), PARAMETER :: M6N6FKxe = 51 + INTEGER(IntKi), PARAMETER :: M6N7FKxe = 52 + INTEGER(IntKi), PARAMETER :: M6N8FKxe = 53 + INTEGER(IntKi), PARAMETER :: M6N9FKxe = 54 + INTEGER(IntKi), PARAMETER :: M7N1FKxe = 55 + INTEGER(IntKi), PARAMETER :: M7N2FKxe = 56 + INTEGER(IntKi), PARAMETER :: M7N3FKxe = 57 + INTEGER(IntKi), PARAMETER :: M7N4FKxe = 58 + INTEGER(IntKi), PARAMETER :: M7N5FKxe = 59 + INTEGER(IntKi), PARAMETER :: M7N6FKxe = 60 + INTEGER(IntKi), PARAMETER :: M7N7FKxe = 61 + INTEGER(IntKi), PARAMETER :: M7N8FKxe = 62 + INTEGER(IntKi), PARAMETER :: M7N9FKxe = 63 + INTEGER(IntKi), PARAMETER :: M8N1FKxe = 64 + INTEGER(IntKi), PARAMETER :: M8N2FKxe = 65 + INTEGER(IntKi), PARAMETER :: M8N3FKxe = 66 + INTEGER(IntKi), PARAMETER :: M8N4FKxe = 67 + INTEGER(IntKi), PARAMETER :: M8N5FKxe = 68 + INTEGER(IntKi), PARAMETER :: M8N6FKxe = 69 + INTEGER(IntKi), PARAMETER :: M8N7FKxe = 70 + INTEGER(IntKi), PARAMETER :: M8N8FKxe = 71 + INTEGER(IntKi), PARAMETER :: M8N9FKxe = 72 + INTEGER(IntKi), PARAMETER :: M9N1FKxe = 73 + INTEGER(IntKi), PARAMETER :: M9N2FKxe = 74 + INTEGER(IntKi), PARAMETER :: M9N3FKxe = 75 + INTEGER(IntKi), PARAMETER :: M9N4FKxe = 76 + INTEGER(IntKi), PARAMETER :: M9N5FKxe = 77 + INTEGER(IntKi), PARAMETER :: M9N6FKxe = 78 + INTEGER(IntKi), PARAMETER :: M9N7FKxe = 79 + INTEGER(IntKi), PARAMETER :: M9N8FKxe = 80 + INTEGER(IntKi), PARAMETER :: M9N9FKxe = 81 + INTEGER(IntKi), PARAMETER :: M1N1FKye = 82 + INTEGER(IntKi), PARAMETER :: M1N2FKye = 83 + INTEGER(IntKi), PARAMETER :: M1N3FKye = 84 + INTEGER(IntKi), PARAMETER :: M1N4FKye = 85 + INTEGER(IntKi), PARAMETER :: M1N5FKye = 86 + INTEGER(IntKi), PARAMETER :: M1N6FKye = 87 + INTEGER(IntKi), PARAMETER :: M1N7FKye = 88 + INTEGER(IntKi), PARAMETER :: M1N8FKye = 89 + INTEGER(IntKi), PARAMETER :: M1N9FKye = 90 + INTEGER(IntKi), PARAMETER :: M2N1FKye = 91 + INTEGER(IntKi), PARAMETER :: M2N2FKye = 92 + INTEGER(IntKi), PARAMETER :: M2N3FKye = 93 + INTEGER(IntKi), PARAMETER :: M2N4FKye = 94 + INTEGER(IntKi), PARAMETER :: M2N5FKye = 95 + INTEGER(IntKi), PARAMETER :: M2N6FKye = 96 + INTEGER(IntKi), PARAMETER :: M2N7FKye = 97 + INTEGER(IntKi), PARAMETER :: M2N8FKye = 98 + INTEGER(IntKi), PARAMETER :: M2N9FKye = 99 + INTEGER(IntKi), PARAMETER :: M3N1FKye = 100 + INTEGER(IntKi), PARAMETER :: M3N2FKye = 101 + INTEGER(IntKi), PARAMETER :: M3N3FKye = 102 + INTEGER(IntKi), PARAMETER :: M3N4FKye = 103 + INTEGER(IntKi), PARAMETER :: M3N5FKye = 104 + INTEGER(IntKi), PARAMETER :: M3N6FKye = 105 + INTEGER(IntKi), PARAMETER :: M3N7FKye = 106 + INTEGER(IntKi), PARAMETER :: M3N8FKye = 107 + INTEGER(IntKi), PARAMETER :: M3N9FKye = 108 + INTEGER(IntKi), PARAMETER :: M4N1FKye = 109 + INTEGER(IntKi), PARAMETER :: M4N2FKye = 110 + INTEGER(IntKi), PARAMETER :: M4N3FKye = 111 + INTEGER(IntKi), PARAMETER :: M4N4FKye = 112 + INTEGER(IntKi), PARAMETER :: M4N5FKye = 113 + INTEGER(IntKi), PARAMETER :: M4N6FKye = 114 + INTEGER(IntKi), PARAMETER :: M4N7FKye = 115 + INTEGER(IntKi), PARAMETER :: M4N8FKye = 116 + INTEGER(IntKi), PARAMETER :: M4N9FKye = 117 + INTEGER(IntKi), PARAMETER :: M5N1FKye = 118 + INTEGER(IntKi), PARAMETER :: M5N2FKye = 119 + INTEGER(IntKi), PARAMETER :: M5N3FKye = 120 + INTEGER(IntKi), PARAMETER :: M5N4FKye = 121 + INTEGER(IntKi), PARAMETER :: M5N5FKye = 122 + INTEGER(IntKi), PARAMETER :: M5N6FKye = 123 + INTEGER(IntKi), PARAMETER :: M5N7FKye = 124 + INTEGER(IntKi), PARAMETER :: M5N8FKye = 125 + INTEGER(IntKi), PARAMETER :: M5N9FKye = 126 + INTEGER(IntKi), PARAMETER :: M6N1FKye = 127 + INTEGER(IntKi), PARAMETER :: M6N2FKye = 128 + INTEGER(IntKi), PARAMETER :: M6N3FKye = 129 + INTEGER(IntKi), PARAMETER :: M6N4FKye = 130 + INTEGER(IntKi), PARAMETER :: M6N5FKye = 131 + INTEGER(IntKi), PARAMETER :: M6N6FKye = 132 + INTEGER(IntKi), PARAMETER :: M6N7FKye = 133 + INTEGER(IntKi), PARAMETER :: M6N8FKye = 134 + INTEGER(IntKi), PARAMETER :: M6N9FKye = 135 + INTEGER(IntKi), PARAMETER :: M7N1FKye = 136 + INTEGER(IntKi), PARAMETER :: M7N2FKye = 137 + INTEGER(IntKi), PARAMETER :: M7N3FKye = 138 + INTEGER(IntKi), PARAMETER :: M7N4FKye = 139 + INTEGER(IntKi), PARAMETER :: M7N5FKye = 140 + INTEGER(IntKi), PARAMETER :: M7N6FKye = 141 + INTEGER(IntKi), PARAMETER :: M7N7FKye = 142 + INTEGER(IntKi), PARAMETER :: M7N8FKye = 143 + INTEGER(IntKi), PARAMETER :: M7N9FKye = 144 + INTEGER(IntKi), PARAMETER :: M8N1FKye = 145 + INTEGER(IntKi), PARAMETER :: M8N2FKye = 146 + INTEGER(IntKi), PARAMETER :: M8N3FKye = 147 + INTEGER(IntKi), PARAMETER :: M8N4FKye = 148 + INTEGER(IntKi), PARAMETER :: M8N5FKye = 149 + INTEGER(IntKi), PARAMETER :: M8N6FKye = 150 + INTEGER(IntKi), PARAMETER :: M8N7FKye = 151 + INTEGER(IntKi), PARAMETER :: M8N8FKye = 152 + INTEGER(IntKi), PARAMETER :: M8N9FKye = 153 + INTEGER(IntKi), PARAMETER :: M9N1FKye = 154 + INTEGER(IntKi), PARAMETER :: M9N2FKye = 155 + INTEGER(IntKi), PARAMETER :: M9N3FKye = 156 + INTEGER(IntKi), PARAMETER :: M9N4FKye = 157 + INTEGER(IntKi), PARAMETER :: M9N5FKye = 158 + INTEGER(IntKi), PARAMETER :: M9N6FKye = 159 + INTEGER(IntKi), PARAMETER :: M9N7FKye = 160 + INTEGER(IntKi), PARAMETER :: M9N8FKye = 161 + INTEGER(IntKi), PARAMETER :: M9N9FKye = 162 + INTEGER(IntKi), PARAMETER :: M1N1FKze = 163 + INTEGER(IntKi), PARAMETER :: M1N2FKze = 164 + INTEGER(IntKi), PARAMETER :: M1N3FKze = 165 + INTEGER(IntKi), PARAMETER :: M1N4FKze = 166 + INTEGER(IntKi), PARAMETER :: M1N5FKze = 167 + INTEGER(IntKi), PARAMETER :: M1N6FKze = 168 + INTEGER(IntKi), PARAMETER :: M1N7FKze = 169 + INTEGER(IntKi), PARAMETER :: M1N8FKze = 170 + INTEGER(IntKi), PARAMETER :: M1N9FKze = 171 + INTEGER(IntKi), PARAMETER :: M2N1FKze = 172 + INTEGER(IntKi), PARAMETER :: M2N2FKze = 173 + INTEGER(IntKi), PARAMETER :: M2N3FKze = 174 + INTEGER(IntKi), PARAMETER :: M2N4FKze = 175 + INTEGER(IntKi), PARAMETER :: M2N5FKze = 176 + INTEGER(IntKi), PARAMETER :: M2N6FKze = 177 + INTEGER(IntKi), PARAMETER :: M2N7FKze = 178 + INTEGER(IntKi), PARAMETER :: M2N8FKze = 179 + INTEGER(IntKi), PARAMETER :: M2N9FKze = 180 + INTEGER(IntKi), PARAMETER :: M3N1FKze = 181 + INTEGER(IntKi), PARAMETER :: M3N2FKze = 182 + INTEGER(IntKi), PARAMETER :: M3N3FKze = 183 + INTEGER(IntKi), PARAMETER :: M3N4FKze = 184 + INTEGER(IntKi), PARAMETER :: M3N5FKze = 185 + INTEGER(IntKi), PARAMETER :: M3N6FKze = 186 + INTEGER(IntKi), PARAMETER :: M3N7FKze = 187 + INTEGER(IntKi), PARAMETER :: M3N8FKze = 188 + INTEGER(IntKi), PARAMETER :: M3N9FKze = 189 + INTEGER(IntKi), PARAMETER :: M4N1FKze = 190 + INTEGER(IntKi), PARAMETER :: M4N2FKze = 191 + INTEGER(IntKi), PARAMETER :: M4N3FKze = 192 + INTEGER(IntKi), PARAMETER :: M4N4FKze = 193 + INTEGER(IntKi), PARAMETER :: M4N5FKze = 194 + INTEGER(IntKi), PARAMETER :: M4N6FKze = 195 + INTEGER(IntKi), PARAMETER :: M4N7FKze = 196 + INTEGER(IntKi), PARAMETER :: M4N8FKze = 197 + INTEGER(IntKi), PARAMETER :: M4N9FKze = 198 + INTEGER(IntKi), PARAMETER :: M5N1FKze = 199 + INTEGER(IntKi), PARAMETER :: M5N2FKze = 200 + INTEGER(IntKi), PARAMETER :: M5N3FKze = 201 + INTEGER(IntKi), PARAMETER :: M5N4FKze = 202 + INTEGER(IntKi), PARAMETER :: M5N5FKze = 203 + INTEGER(IntKi), PARAMETER :: M5N6FKze = 204 + INTEGER(IntKi), PARAMETER :: M5N7FKze = 205 + INTEGER(IntKi), PARAMETER :: M5N8FKze = 206 + INTEGER(IntKi), PARAMETER :: M5N9FKze = 207 + INTEGER(IntKi), PARAMETER :: M6N1FKze = 208 + INTEGER(IntKi), PARAMETER :: M6N2FKze = 209 + INTEGER(IntKi), PARAMETER :: M6N3FKze = 210 + INTEGER(IntKi), PARAMETER :: M6N4FKze = 211 + INTEGER(IntKi), PARAMETER :: M6N5FKze = 212 + INTEGER(IntKi), PARAMETER :: M6N6FKze = 213 + INTEGER(IntKi), PARAMETER :: M6N7FKze = 214 + INTEGER(IntKi), PARAMETER :: M6N8FKze = 215 + INTEGER(IntKi), PARAMETER :: M6N9FKze = 216 + INTEGER(IntKi), PARAMETER :: M7N1FKze = 217 + INTEGER(IntKi), PARAMETER :: M7N2FKze = 218 + INTEGER(IntKi), PARAMETER :: M7N3FKze = 219 + INTEGER(IntKi), PARAMETER :: M7N4FKze = 220 + INTEGER(IntKi), PARAMETER :: M7N5FKze = 221 + INTEGER(IntKi), PARAMETER :: M7N6FKze = 222 + INTEGER(IntKi), PARAMETER :: M7N7FKze = 223 + INTEGER(IntKi), PARAMETER :: M7N8FKze = 224 + INTEGER(IntKi), PARAMETER :: M7N9FKze = 225 + INTEGER(IntKi), PARAMETER :: M8N1FKze = 226 + INTEGER(IntKi), PARAMETER :: M8N2FKze = 227 + INTEGER(IntKi), PARAMETER :: M8N3FKze = 228 + INTEGER(IntKi), PARAMETER :: M8N4FKze = 229 + INTEGER(IntKi), PARAMETER :: M8N5FKze = 230 + INTEGER(IntKi), PARAMETER :: M8N6FKze = 231 + INTEGER(IntKi), PARAMETER :: M8N7FKze = 232 + INTEGER(IntKi), PARAMETER :: M8N8FKze = 233 + INTEGER(IntKi), PARAMETER :: M8N9FKze = 234 + INTEGER(IntKi), PARAMETER :: M9N1FKze = 235 + INTEGER(IntKi), PARAMETER :: M9N2FKze = 236 + INTEGER(IntKi), PARAMETER :: M9N3FKze = 237 + INTEGER(IntKi), PARAMETER :: M9N4FKze = 238 + INTEGER(IntKi), PARAMETER :: M9N5FKze = 239 + INTEGER(IntKi), PARAMETER :: M9N6FKze = 240 + INTEGER(IntKi), PARAMETER :: M9N7FKze = 241 + INTEGER(IntKi), PARAMETER :: M9N8FKze = 242 + INTEGER(IntKi), PARAMETER :: M9N9FKze = 243 + INTEGER(IntKi), PARAMETER :: M1N1FMxe = 244 + INTEGER(IntKi), PARAMETER :: M1N2FMxe = 245 + INTEGER(IntKi), PARAMETER :: M1N3FMxe = 246 + INTEGER(IntKi), PARAMETER :: M1N4FMxe = 247 + INTEGER(IntKi), PARAMETER :: M1N5FMxe = 248 + INTEGER(IntKi), PARAMETER :: M1N6FMxe = 249 + INTEGER(IntKi), PARAMETER :: M1N7FMxe = 250 + INTEGER(IntKi), PARAMETER :: M1N8FMxe = 251 + INTEGER(IntKi), PARAMETER :: M1N9FMxe = 252 + INTEGER(IntKi), PARAMETER :: M2N1FMxe = 253 + INTEGER(IntKi), PARAMETER :: M2N2FMxe = 254 + INTEGER(IntKi), PARAMETER :: M2N3FMxe = 255 + INTEGER(IntKi), PARAMETER :: M2N4FMxe = 256 + INTEGER(IntKi), PARAMETER :: M2N5FMxe = 257 + INTEGER(IntKi), PARAMETER :: M2N6FMxe = 258 + INTEGER(IntKi), PARAMETER :: M2N7FMxe = 259 + INTEGER(IntKi), PARAMETER :: M2N8FMxe = 260 + INTEGER(IntKi), PARAMETER :: M2N9FMxe = 261 + INTEGER(IntKi), PARAMETER :: M3N1FMxe = 262 + INTEGER(IntKi), PARAMETER :: M3N2FMxe = 263 + INTEGER(IntKi), PARAMETER :: M3N3FMxe = 264 + INTEGER(IntKi), PARAMETER :: M3N4FMxe = 265 + INTEGER(IntKi), PARAMETER :: M3N5FMxe = 266 + INTEGER(IntKi), PARAMETER :: M3N6FMxe = 267 + INTEGER(IntKi), PARAMETER :: M3N7FMxe = 268 + INTEGER(IntKi), PARAMETER :: M3N8FMxe = 269 + INTEGER(IntKi), PARAMETER :: M3N9FMxe = 270 + INTEGER(IntKi), PARAMETER :: M4N1FMxe = 271 + INTEGER(IntKi), PARAMETER :: M4N2FMxe = 272 + INTEGER(IntKi), PARAMETER :: M4N3FMxe = 273 + INTEGER(IntKi), PARAMETER :: M4N4FMxe = 274 + INTEGER(IntKi), PARAMETER :: M4N5FMxe = 275 + INTEGER(IntKi), PARAMETER :: M4N6FMxe = 276 + INTEGER(IntKi), PARAMETER :: M4N7FMxe = 277 + INTEGER(IntKi), PARAMETER :: M4N8FMxe = 278 + INTEGER(IntKi), PARAMETER :: M4N9FMxe = 279 + INTEGER(IntKi), PARAMETER :: M5N1FMxe = 280 + INTEGER(IntKi), PARAMETER :: M5N2FMxe = 281 + INTEGER(IntKi), PARAMETER :: M5N3FMxe = 282 + INTEGER(IntKi), PARAMETER :: M5N4FMxe = 283 + INTEGER(IntKi), PARAMETER :: M5N5FMxe = 284 + INTEGER(IntKi), PARAMETER :: M5N6FMxe = 285 + INTEGER(IntKi), PARAMETER :: M5N7FMxe = 286 + INTEGER(IntKi), PARAMETER :: M5N8FMxe = 287 + INTEGER(IntKi), PARAMETER :: M5N9FMxe = 288 + INTEGER(IntKi), PARAMETER :: M6N1FMxe = 289 + INTEGER(IntKi), PARAMETER :: M6N2FMxe = 290 + INTEGER(IntKi), PARAMETER :: M6N3FMxe = 291 + INTEGER(IntKi), PARAMETER :: M6N4FMxe = 292 + INTEGER(IntKi), PARAMETER :: M6N5FMxe = 293 + INTEGER(IntKi), PARAMETER :: M6N6FMxe = 294 + INTEGER(IntKi), PARAMETER :: M6N7FMxe = 295 + INTEGER(IntKi), PARAMETER :: M6N8FMxe = 296 + INTEGER(IntKi), PARAMETER :: M6N9FMxe = 297 + INTEGER(IntKi), PARAMETER :: M7N1FMxe = 298 + INTEGER(IntKi), PARAMETER :: M7N2FMxe = 299 + INTEGER(IntKi), PARAMETER :: M7N3FMxe = 300 + INTEGER(IntKi), PARAMETER :: M7N4FMxe = 301 + INTEGER(IntKi), PARAMETER :: M7N5FMxe = 302 + INTEGER(IntKi), PARAMETER :: M7N6FMxe = 303 + INTEGER(IntKi), PARAMETER :: M7N7FMxe = 304 + INTEGER(IntKi), PARAMETER :: M7N8FMxe = 305 + INTEGER(IntKi), PARAMETER :: M7N9FMxe = 306 + INTEGER(IntKi), PARAMETER :: M8N1FMxe = 307 + INTEGER(IntKi), PARAMETER :: M8N2FMxe = 308 + INTEGER(IntKi), PARAMETER :: M8N3FMxe = 309 + INTEGER(IntKi), PARAMETER :: M8N4FMxe = 310 + INTEGER(IntKi), PARAMETER :: M8N5FMxe = 311 + INTEGER(IntKi), PARAMETER :: M8N6FMxe = 312 + INTEGER(IntKi), PARAMETER :: M8N7FMxe = 313 + INTEGER(IntKi), PARAMETER :: M8N8FMxe = 314 + INTEGER(IntKi), PARAMETER :: M8N9FMxe = 315 + INTEGER(IntKi), PARAMETER :: M9N1FMxe = 316 + INTEGER(IntKi), PARAMETER :: M9N2FMxe = 317 + INTEGER(IntKi), PARAMETER :: M9N3FMxe = 318 + INTEGER(IntKi), PARAMETER :: M9N4FMxe = 319 + INTEGER(IntKi), PARAMETER :: M9N5FMxe = 320 + INTEGER(IntKi), PARAMETER :: M9N6FMxe = 321 + INTEGER(IntKi), PARAMETER :: M9N7FMxe = 322 + INTEGER(IntKi), PARAMETER :: M9N8FMxe = 323 + INTEGER(IntKi), PARAMETER :: M9N9FMxe = 324 + INTEGER(IntKi), PARAMETER :: M1N1FMye = 325 + INTEGER(IntKi), PARAMETER :: M1N2FMye = 326 + INTEGER(IntKi), PARAMETER :: M1N3FMye = 327 + INTEGER(IntKi), PARAMETER :: M1N4FMye = 328 + INTEGER(IntKi), PARAMETER :: M1N5FMye = 329 + INTEGER(IntKi), PARAMETER :: M1N6FMye = 330 + INTEGER(IntKi), PARAMETER :: M1N7FMye = 331 + INTEGER(IntKi), PARAMETER :: M1N8FMye = 332 + INTEGER(IntKi), PARAMETER :: M1N9FMye = 333 + INTEGER(IntKi), PARAMETER :: M2N1FMye = 334 + INTEGER(IntKi), PARAMETER :: M2N2FMye = 335 + INTEGER(IntKi), PARAMETER :: M2N3FMye = 336 + INTEGER(IntKi), PARAMETER :: M2N4FMye = 337 + INTEGER(IntKi), PARAMETER :: M2N5FMye = 338 + INTEGER(IntKi), PARAMETER :: M2N6FMye = 339 + INTEGER(IntKi), PARAMETER :: M2N7FMye = 340 + INTEGER(IntKi), PARAMETER :: M2N8FMye = 341 + INTEGER(IntKi), PARAMETER :: M2N9FMye = 342 + INTEGER(IntKi), PARAMETER :: M3N1FMye = 343 + INTEGER(IntKi), PARAMETER :: M3N2FMye = 344 + INTEGER(IntKi), PARAMETER :: M3N3FMye = 345 + INTEGER(IntKi), PARAMETER :: M3N4FMye = 346 + INTEGER(IntKi), PARAMETER :: M3N5FMye = 347 + INTEGER(IntKi), PARAMETER :: M3N6FMye = 348 + INTEGER(IntKi), PARAMETER :: M3N7FMye = 349 + INTEGER(IntKi), PARAMETER :: M3N8FMye = 350 + INTEGER(IntKi), PARAMETER :: M3N9FMye = 351 + INTEGER(IntKi), PARAMETER :: M4N1FMye = 352 + INTEGER(IntKi), PARAMETER :: M4N2FMye = 353 + INTEGER(IntKi), PARAMETER :: M4N3FMye = 354 + INTEGER(IntKi), PARAMETER :: M4N4FMye = 355 + INTEGER(IntKi), PARAMETER :: M4N5FMye = 356 + INTEGER(IntKi), PARAMETER :: M4N6FMye = 357 + INTEGER(IntKi), PARAMETER :: M4N7FMye = 358 + INTEGER(IntKi), PARAMETER :: M4N8FMye = 359 + INTEGER(IntKi), PARAMETER :: M4N9FMye = 360 + INTEGER(IntKi), PARAMETER :: M5N1FMye = 361 + INTEGER(IntKi), PARAMETER :: M5N2FMye = 362 + INTEGER(IntKi), PARAMETER :: M5N3FMye = 363 + INTEGER(IntKi), PARAMETER :: M5N4FMye = 364 + INTEGER(IntKi), PARAMETER :: M5N5FMye = 365 + INTEGER(IntKi), PARAMETER :: M5N6FMye = 366 + INTEGER(IntKi), PARAMETER :: M5N7FMye = 367 + INTEGER(IntKi), PARAMETER :: M5N8FMye = 368 + INTEGER(IntKi), PARAMETER :: M5N9FMye = 369 + INTEGER(IntKi), PARAMETER :: M6N1FMye = 370 + INTEGER(IntKi), PARAMETER :: M6N2FMye = 371 + INTEGER(IntKi), PARAMETER :: M6N3FMye = 372 + INTEGER(IntKi), PARAMETER :: M6N4FMye = 373 + INTEGER(IntKi), PARAMETER :: M6N5FMye = 374 + INTEGER(IntKi), PARAMETER :: M6N6FMye = 375 + INTEGER(IntKi), PARAMETER :: M6N7FMye = 376 + INTEGER(IntKi), PARAMETER :: M6N8FMye = 377 + INTEGER(IntKi), PARAMETER :: M6N9FMye = 378 + INTEGER(IntKi), PARAMETER :: M7N1FMye = 379 + INTEGER(IntKi), PARAMETER :: M7N2FMye = 380 + INTEGER(IntKi), PARAMETER :: M7N3FMye = 381 + INTEGER(IntKi), PARAMETER :: M7N4FMye = 382 + INTEGER(IntKi), PARAMETER :: M7N5FMye = 383 + INTEGER(IntKi), PARAMETER :: M7N6FMye = 384 + INTEGER(IntKi), PARAMETER :: M7N7FMye = 385 + INTEGER(IntKi), PARAMETER :: M7N8FMye = 386 + INTEGER(IntKi), PARAMETER :: M7N9FMye = 387 + INTEGER(IntKi), PARAMETER :: M8N1FMye = 388 + INTEGER(IntKi), PARAMETER :: M8N2FMye = 389 + INTEGER(IntKi), PARAMETER :: M8N3FMye = 390 + INTEGER(IntKi), PARAMETER :: M8N4FMye = 391 + INTEGER(IntKi), PARAMETER :: M8N5FMye = 392 + INTEGER(IntKi), PARAMETER :: M8N6FMye = 393 + INTEGER(IntKi), PARAMETER :: M8N7FMye = 394 + INTEGER(IntKi), PARAMETER :: M8N8FMye = 395 + INTEGER(IntKi), PARAMETER :: M8N9FMye = 396 + INTEGER(IntKi), PARAMETER :: M9N1FMye = 397 + INTEGER(IntKi), PARAMETER :: M9N2FMye = 398 + INTEGER(IntKi), PARAMETER :: M9N3FMye = 399 + INTEGER(IntKi), PARAMETER :: M9N4FMye = 400 + INTEGER(IntKi), PARAMETER :: M9N5FMye = 401 + INTEGER(IntKi), PARAMETER :: M9N6FMye = 402 + INTEGER(IntKi), PARAMETER :: M9N7FMye = 403 + INTEGER(IntKi), PARAMETER :: M9N8FMye = 404 + INTEGER(IntKi), PARAMETER :: M9N9FMye = 405 + INTEGER(IntKi), PARAMETER :: M1N1FMze = 406 + INTEGER(IntKi), PARAMETER :: M1N2FMze = 407 + INTEGER(IntKi), PARAMETER :: M1N3FMze = 408 + INTEGER(IntKi), PARAMETER :: M1N4FMze = 409 + INTEGER(IntKi), PARAMETER :: M1N5FMze = 410 + INTEGER(IntKi), PARAMETER :: M1N6FMze = 411 + INTEGER(IntKi), PARAMETER :: M1N7FMze = 412 + INTEGER(IntKi), PARAMETER :: M1N8FMze = 413 + INTEGER(IntKi), PARAMETER :: M1N9FMze = 414 + INTEGER(IntKi), PARAMETER :: M2N1FMze = 415 + INTEGER(IntKi), PARAMETER :: M2N2FMze = 416 + INTEGER(IntKi), PARAMETER :: M2N3FMze = 417 + INTEGER(IntKi), PARAMETER :: M2N4FMze = 418 + INTEGER(IntKi), PARAMETER :: M2N5FMze = 419 + INTEGER(IntKi), PARAMETER :: M2N6FMze = 420 + INTEGER(IntKi), PARAMETER :: M2N7FMze = 421 + INTEGER(IntKi), PARAMETER :: M2N8FMze = 422 + INTEGER(IntKi), PARAMETER :: M2N9FMze = 423 + INTEGER(IntKi), PARAMETER :: M3N1FMze = 424 + INTEGER(IntKi), PARAMETER :: M3N2FMze = 425 + INTEGER(IntKi), PARAMETER :: M3N3FMze = 426 + INTEGER(IntKi), PARAMETER :: M3N4FMze = 427 + INTEGER(IntKi), PARAMETER :: M3N5FMze = 428 + INTEGER(IntKi), PARAMETER :: M3N6FMze = 429 + INTEGER(IntKi), PARAMETER :: M3N7FMze = 430 + INTEGER(IntKi), PARAMETER :: M3N8FMze = 431 + INTEGER(IntKi), PARAMETER :: M3N9FMze = 432 + INTEGER(IntKi), PARAMETER :: M4N1FMze = 433 + INTEGER(IntKi), PARAMETER :: M4N2FMze = 434 + INTEGER(IntKi), PARAMETER :: M4N3FMze = 435 + INTEGER(IntKi), PARAMETER :: M4N4FMze = 436 + INTEGER(IntKi), PARAMETER :: M4N5FMze = 437 + INTEGER(IntKi), PARAMETER :: M4N6FMze = 438 + INTEGER(IntKi), PARAMETER :: M4N7FMze = 439 + INTEGER(IntKi), PARAMETER :: M4N8FMze = 440 + INTEGER(IntKi), PARAMETER :: M4N9FMze = 441 + INTEGER(IntKi), PARAMETER :: M5N1FMze = 442 + INTEGER(IntKi), PARAMETER :: M5N2FMze = 443 + INTEGER(IntKi), PARAMETER :: M5N3FMze = 444 + INTEGER(IntKi), PARAMETER :: M5N4FMze = 445 + INTEGER(IntKi), PARAMETER :: M5N5FMze = 446 + INTEGER(IntKi), PARAMETER :: M5N6FMze = 447 + INTEGER(IntKi), PARAMETER :: M5N7FMze = 448 + INTEGER(IntKi), PARAMETER :: M5N8FMze = 449 + INTEGER(IntKi), PARAMETER :: M5N9FMze = 450 + INTEGER(IntKi), PARAMETER :: M6N1FMze = 451 + INTEGER(IntKi), PARAMETER :: M6N2FMze = 452 + INTEGER(IntKi), PARAMETER :: M6N3FMze = 453 + INTEGER(IntKi), PARAMETER :: M6N4FMze = 454 + INTEGER(IntKi), PARAMETER :: M6N5FMze = 455 + INTEGER(IntKi), PARAMETER :: M6N6FMze = 456 + INTEGER(IntKi), PARAMETER :: M6N7FMze = 457 + INTEGER(IntKi), PARAMETER :: M6N8FMze = 458 + INTEGER(IntKi), PARAMETER :: M6N9FMze = 459 + INTEGER(IntKi), PARAMETER :: M7N1FMze = 460 + INTEGER(IntKi), PARAMETER :: M7N2FMze = 461 + INTEGER(IntKi), PARAMETER :: M7N3FMze = 462 + INTEGER(IntKi), PARAMETER :: M7N4FMze = 463 + INTEGER(IntKi), PARAMETER :: M7N5FMze = 464 + INTEGER(IntKi), PARAMETER :: M7N6FMze = 465 + INTEGER(IntKi), PARAMETER :: M7N7FMze = 466 + INTEGER(IntKi), PARAMETER :: M7N8FMze = 467 + INTEGER(IntKi), PARAMETER :: M7N9FMze = 468 + INTEGER(IntKi), PARAMETER :: M8N1FMze = 469 + INTEGER(IntKi), PARAMETER :: M8N2FMze = 470 + INTEGER(IntKi), PARAMETER :: M8N3FMze = 471 + INTEGER(IntKi), PARAMETER :: M8N4FMze = 472 + INTEGER(IntKi), PARAMETER :: M8N5FMze = 473 + INTEGER(IntKi), PARAMETER :: M8N6FMze = 474 + INTEGER(IntKi), PARAMETER :: M8N7FMze = 475 + INTEGER(IntKi), PARAMETER :: M8N8FMze = 476 + INTEGER(IntKi), PARAMETER :: M8N9FMze = 477 + INTEGER(IntKi), PARAMETER :: M9N1FMze = 478 + INTEGER(IntKi), PARAMETER :: M9N2FMze = 479 + INTEGER(IntKi), PARAMETER :: M9N3FMze = 480 + INTEGER(IntKi), PARAMETER :: M9N4FMze = 481 + INTEGER(IntKi), PARAMETER :: M9N5FMze = 482 + INTEGER(IntKi), PARAMETER :: M9N6FMze = 483 + INTEGER(IntKi), PARAMETER :: M9N7FMze = 484 + INTEGER(IntKi), PARAMETER :: M9N8FMze = 485 + INTEGER(IntKi), PARAMETER :: M9N9FMze = 486 + INTEGER(IntKi), PARAMETER :: M1N1MKxe = 487 + INTEGER(IntKi), PARAMETER :: M1N2MKxe = 488 + INTEGER(IntKi), PARAMETER :: M1N3MKxe = 489 + INTEGER(IntKi), PARAMETER :: M1N4MKxe = 490 + INTEGER(IntKi), PARAMETER :: M1N5MKxe = 491 + INTEGER(IntKi), PARAMETER :: M1N6MKxe = 492 + INTEGER(IntKi), PARAMETER :: M1N7MKxe = 493 + INTEGER(IntKi), PARAMETER :: M1N8MKxe = 494 + INTEGER(IntKi), PARAMETER :: M1N9MKxe = 495 + INTEGER(IntKi), PARAMETER :: M2N1MKxe = 496 + INTEGER(IntKi), PARAMETER :: M2N2MKxe = 497 + INTEGER(IntKi), PARAMETER :: M2N3MKxe = 498 + INTEGER(IntKi), PARAMETER :: M2N4MKxe = 499 + INTEGER(IntKi), PARAMETER :: M2N5MKxe = 500 + INTEGER(IntKi), PARAMETER :: M2N6MKxe = 501 + INTEGER(IntKi), PARAMETER :: M2N7MKxe = 502 + INTEGER(IntKi), PARAMETER :: M2N8MKxe = 503 + INTEGER(IntKi), PARAMETER :: M2N9MKxe = 504 + INTEGER(IntKi), PARAMETER :: M3N1MKxe = 505 + INTEGER(IntKi), PARAMETER :: M3N2MKxe = 506 + INTEGER(IntKi), PARAMETER :: M3N3MKxe = 507 + INTEGER(IntKi), PARAMETER :: M3N4MKxe = 508 + INTEGER(IntKi), PARAMETER :: M3N5MKxe = 509 + INTEGER(IntKi), PARAMETER :: M3N6MKxe = 510 + INTEGER(IntKi), PARAMETER :: M3N7MKxe = 511 + INTEGER(IntKi), PARAMETER :: M3N8MKxe = 512 + INTEGER(IntKi), PARAMETER :: M3N9MKxe = 513 + INTEGER(IntKi), PARAMETER :: M4N1MKxe = 514 + INTEGER(IntKi), PARAMETER :: M4N2MKxe = 515 + INTEGER(IntKi), PARAMETER :: M4N3MKxe = 516 + INTEGER(IntKi), PARAMETER :: M4N4MKxe = 517 + INTEGER(IntKi), PARAMETER :: M4N5MKxe = 518 + INTEGER(IntKi), PARAMETER :: M4N6MKxe = 519 + INTEGER(IntKi), PARAMETER :: M4N7MKxe = 520 + INTEGER(IntKi), PARAMETER :: M4N8MKxe = 521 + INTEGER(IntKi), PARAMETER :: M4N9MKxe = 522 + INTEGER(IntKi), PARAMETER :: M5N1MKxe = 523 + INTEGER(IntKi), PARAMETER :: M5N2MKxe = 524 + INTEGER(IntKi), PARAMETER :: M5N3MKxe = 525 + INTEGER(IntKi), PARAMETER :: M5N4MKxe = 526 + INTEGER(IntKi), PARAMETER :: M5N5MKxe = 527 + INTEGER(IntKi), PARAMETER :: M5N6MKxe = 528 + INTEGER(IntKi), PARAMETER :: M5N7MKxe = 529 + INTEGER(IntKi), PARAMETER :: M5N8MKxe = 530 + INTEGER(IntKi), PARAMETER :: M5N9MKxe = 531 + INTEGER(IntKi), PARAMETER :: M6N1MKxe = 532 + INTEGER(IntKi), PARAMETER :: M6N2MKxe = 533 + INTEGER(IntKi), PARAMETER :: M6N3MKxe = 534 + INTEGER(IntKi), PARAMETER :: M6N4MKxe = 535 + INTEGER(IntKi), PARAMETER :: M6N5MKxe = 536 + INTEGER(IntKi), PARAMETER :: M6N6MKxe = 537 + INTEGER(IntKi), PARAMETER :: M6N7MKxe = 538 + INTEGER(IntKi), PARAMETER :: M6N8MKxe = 539 + INTEGER(IntKi), PARAMETER :: M6N9MKxe = 540 + INTEGER(IntKi), PARAMETER :: M7N1MKxe = 541 + INTEGER(IntKi), PARAMETER :: M7N2MKxe = 542 + INTEGER(IntKi), PARAMETER :: M7N3MKxe = 543 + INTEGER(IntKi), PARAMETER :: M7N4MKxe = 544 + INTEGER(IntKi), PARAMETER :: M7N5MKxe = 545 + INTEGER(IntKi), PARAMETER :: M7N6MKxe = 546 + INTEGER(IntKi), PARAMETER :: M7N7MKxe = 547 + INTEGER(IntKi), PARAMETER :: M7N8MKxe = 548 + INTEGER(IntKi), PARAMETER :: M7N9MKxe = 549 + INTEGER(IntKi), PARAMETER :: M8N1MKxe = 550 + INTEGER(IntKi), PARAMETER :: M8N2MKxe = 551 + INTEGER(IntKi), PARAMETER :: M8N3MKxe = 552 + INTEGER(IntKi), PARAMETER :: M8N4MKxe = 553 + INTEGER(IntKi), PARAMETER :: M8N5MKxe = 554 + INTEGER(IntKi), PARAMETER :: M8N6MKxe = 555 + INTEGER(IntKi), PARAMETER :: M8N7MKxe = 556 + INTEGER(IntKi), PARAMETER :: M8N8MKxe = 557 + INTEGER(IntKi), PARAMETER :: M8N9MKxe = 558 + INTEGER(IntKi), PARAMETER :: M9N1MKxe = 559 + INTEGER(IntKi), PARAMETER :: M9N2MKxe = 560 + INTEGER(IntKi), PARAMETER :: M9N3MKxe = 561 + INTEGER(IntKi), PARAMETER :: M9N4MKxe = 562 + INTEGER(IntKi), PARAMETER :: M9N5MKxe = 563 + INTEGER(IntKi), PARAMETER :: M9N6MKxe = 564 + INTEGER(IntKi), PARAMETER :: M9N7MKxe = 565 + INTEGER(IntKi), PARAMETER :: M9N8MKxe = 566 + INTEGER(IntKi), PARAMETER :: M9N9MKxe = 567 + INTEGER(IntKi), PARAMETER :: M1N1MKye = 568 + INTEGER(IntKi), PARAMETER :: M1N2MKye = 569 + INTEGER(IntKi), PARAMETER :: M1N3MKye = 570 + INTEGER(IntKi), PARAMETER :: M1N4MKye = 571 + INTEGER(IntKi), PARAMETER :: M1N5MKye = 572 + INTEGER(IntKi), PARAMETER :: M1N6MKye = 573 + INTEGER(IntKi), PARAMETER :: M1N7MKye = 574 + INTEGER(IntKi), PARAMETER :: M1N8MKye = 575 + INTEGER(IntKi), PARAMETER :: M1N9MKye = 576 + INTEGER(IntKi), PARAMETER :: M2N1MKye = 577 + INTEGER(IntKi), PARAMETER :: M2N2MKye = 578 + INTEGER(IntKi), PARAMETER :: M2N3MKye = 579 + INTEGER(IntKi), PARAMETER :: M2N4MKye = 580 + INTEGER(IntKi), PARAMETER :: M2N5MKye = 581 + INTEGER(IntKi), PARAMETER :: M2N6MKye = 582 + INTEGER(IntKi), PARAMETER :: M2N7MKye = 583 + INTEGER(IntKi), PARAMETER :: M2N8MKye = 584 + INTEGER(IntKi), PARAMETER :: M2N9MKye = 585 + INTEGER(IntKi), PARAMETER :: M3N1MKye = 586 + INTEGER(IntKi), PARAMETER :: M3N2MKye = 587 + INTEGER(IntKi), PARAMETER :: M3N3MKye = 588 + INTEGER(IntKi), PARAMETER :: M3N4MKye = 589 + INTEGER(IntKi), PARAMETER :: M3N5MKye = 590 + INTEGER(IntKi), PARAMETER :: M3N6MKye = 591 + INTEGER(IntKi), PARAMETER :: M3N7MKye = 592 + INTEGER(IntKi), PARAMETER :: M3N8MKye = 593 + INTEGER(IntKi), PARAMETER :: M3N9MKye = 594 + INTEGER(IntKi), PARAMETER :: M4N1MKye = 595 + INTEGER(IntKi), PARAMETER :: M4N2MKye = 596 + INTEGER(IntKi), PARAMETER :: M4N3MKye = 597 + INTEGER(IntKi), PARAMETER :: M4N4MKye = 598 + INTEGER(IntKi), PARAMETER :: M4N5MKye = 599 + INTEGER(IntKi), PARAMETER :: M4N6MKye = 600 + INTEGER(IntKi), PARAMETER :: M4N7MKye = 601 + INTEGER(IntKi), PARAMETER :: M4N8MKye = 602 + INTEGER(IntKi), PARAMETER :: M4N9MKye = 603 + INTEGER(IntKi), PARAMETER :: M5N1MKye = 604 + INTEGER(IntKi), PARAMETER :: M5N2MKye = 605 + INTEGER(IntKi), PARAMETER :: M5N3MKye = 606 + INTEGER(IntKi), PARAMETER :: M5N4MKye = 607 + INTEGER(IntKi), PARAMETER :: M5N5MKye = 608 + INTEGER(IntKi), PARAMETER :: M5N6MKye = 609 + INTEGER(IntKi), PARAMETER :: M5N7MKye = 610 + INTEGER(IntKi), PARAMETER :: M5N8MKye = 611 + INTEGER(IntKi), PARAMETER :: M5N9MKye = 612 + INTEGER(IntKi), PARAMETER :: M6N1MKye = 613 + INTEGER(IntKi), PARAMETER :: M6N2MKye = 614 + INTEGER(IntKi), PARAMETER :: M6N3MKye = 615 + INTEGER(IntKi), PARAMETER :: M6N4MKye = 616 + INTEGER(IntKi), PARAMETER :: M6N5MKye = 617 + INTEGER(IntKi), PARAMETER :: M6N6MKye = 618 + INTEGER(IntKi), PARAMETER :: M6N7MKye = 619 + INTEGER(IntKi), PARAMETER :: M6N8MKye = 620 + INTEGER(IntKi), PARAMETER :: M6N9MKye = 621 + INTEGER(IntKi), PARAMETER :: M7N1MKye = 622 + INTEGER(IntKi), PARAMETER :: M7N2MKye = 623 + INTEGER(IntKi), PARAMETER :: M7N3MKye = 624 + INTEGER(IntKi), PARAMETER :: M7N4MKye = 625 + INTEGER(IntKi), PARAMETER :: M7N5MKye = 626 + INTEGER(IntKi), PARAMETER :: M7N6MKye = 627 + INTEGER(IntKi), PARAMETER :: M7N7MKye = 628 + INTEGER(IntKi), PARAMETER :: M7N8MKye = 629 + INTEGER(IntKi), PARAMETER :: M7N9MKye = 630 + INTEGER(IntKi), PARAMETER :: M8N1MKye = 631 + INTEGER(IntKi), PARAMETER :: M8N2MKye = 632 + INTEGER(IntKi), PARAMETER :: M8N3MKye = 633 + INTEGER(IntKi), PARAMETER :: M8N4MKye = 634 + INTEGER(IntKi), PARAMETER :: M8N5MKye = 635 + INTEGER(IntKi), PARAMETER :: M8N6MKye = 636 + INTEGER(IntKi), PARAMETER :: M8N7MKye = 637 + INTEGER(IntKi), PARAMETER :: M8N8MKye = 638 + INTEGER(IntKi), PARAMETER :: M8N9MKye = 639 + INTEGER(IntKi), PARAMETER :: M9N1MKye = 640 + INTEGER(IntKi), PARAMETER :: M9N2MKye = 641 + INTEGER(IntKi), PARAMETER :: M9N3MKye = 642 + INTEGER(IntKi), PARAMETER :: M9N4MKye = 643 + INTEGER(IntKi), PARAMETER :: M9N5MKye = 644 + INTEGER(IntKi), PARAMETER :: M9N6MKye = 645 + INTEGER(IntKi), PARAMETER :: M9N7MKye = 646 + INTEGER(IntKi), PARAMETER :: M9N8MKye = 647 + INTEGER(IntKi), PARAMETER :: M9N9MKye = 648 + INTEGER(IntKi), PARAMETER :: M1N1MKze = 649 + INTEGER(IntKi), PARAMETER :: M1N2MKze = 650 + INTEGER(IntKi), PARAMETER :: M1N3MKze = 651 + INTEGER(IntKi), PARAMETER :: M1N4MKze = 652 + INTEGER(IntKi), PARAMETER :: M1N5MKze = 653 + INTEGER(IntKi), PARAMETER :: M1N6MKze = 654 + INTEGER(IntKi), PARAMETER :: M1N7MKze = 655 + INTEGER(IntKi), PARAMETER :: M1N8MKze = 656 + INTEGER(IntKi), PARAMETER :: M1N9MKze = 657 + INTEGER(IntKi), PARAMETER :: M2N1MKze = 658 + INTEGER(IntKi), PARAMETER :: M2N2MKze = 659 + INTEGER(IntKi), PARAMETER :: M2N3MKze = 660 + INTEGER(IntKi), PARAMETER :: M2N4MKze = 661 + INTEGER(IntKi), PARAMETER :: M2N5MKze = 662 + INTEGER(IntKi), PARAMETER :: M2N6MKze = 663 + INTEGER(IntKi), PARAMETER :: M2N7MKze = 664 + INTEGER(IntKi), PARAMETER :: M2N8MKze = 665 + INTEGER(IntKi), PARAMETER :: M2N9MKze = 666 + INTEGER(IntKi), PARAMETER :: M3N1MKze = 667 + INTEGER(IntKi), PARAMETER :: M3N2MKze = 668 + INTEGER(IntKi), PARAMETER :: M3N3MKze = 669 + INTEGER(IntKi), PARAMETER :: M3N4MKze = 670 + INTEGER(IntKi), PARAMETER :: M3N5MKze = 671 + INTEGER(IntKi), PARAMETER :: M3N6MKze = 672 + INTEGER(IntKi), PARAMETER :: M3N7MKze = 673 + INTEGER(IntKi), PARAMETER :: M3N8MKze = 674 + INTEGER(IntKi), PARAMETER :: M3N9MKze = 675 + INTEGER(IntKi), PARAMETER :: M4N1MKze = 676 + INTEGER(IntKi), PARAMETER :: M4N2MKze = 677 + INTEGER(IntKi), PARAMETER :: M4N3MKze = 678 + INTEGER(IntKi), PARAMETER :: M4N4MKze = 679 + INTEGER(IntKi), PARAMETER :: M4N5MKze = 680 + INTEGER(IntKi), PARAMETER :: M4N6MKze = 681 + INTEGER(IntKi), PARAMETER :: M4N7MKze = 682 + INTEGER(IntKi), PARAMETER :: M4N8MKze = 683 + INTEGER(IntKi), PARAMETER :: M4N9MKze = 684 + INTEGER(IntKi), PARAMETER :: M5N1MKze = 685 + INTEGER(IntKi), PARAMETER :: M5N2MKze = 686 + INTEGER(IntKi), PARAMETER :: M5N3MKze = 687 + INTEGER(IntKi), PARAMETER :: M5N4MKze = 688 + INTEGER(IntKi), PARAMETER :: M5N5MKze = 689 + INTEGER(IntKi), PARAMETER :: M5N6MKze = 690 + INTEGER(IntKi), PARAMETER :: M5N7MKze = 691 + INTEGER(IntKi), PARAMETER :: M5N8MKze = 692 + INTEGER(IntKi), PARAMETER :: M5N9MKze = 693 + INTEGER(IntKi), PARAMETER :: M6N1MKze = 694 + INTEGER(IntKi), PARAMETER :: M6N2MKze = 695 + INTEGER(IntKi), PARAMETER :: M6N3MKze = 696 + INTEGER(IntKi), PARAMETER :: M6N4MKze = 697 + INTEGER(IntKi), PARAMETER :: M6N5MKze = 698 + INTEGER(IntKi), PARAMETER :: M6N6MKze = 699 + INTEGER(IntKi), PARAMETER :: M6N7MKze = 700 + INTEGER(IntKi), PARAMETER :: M6N8MKze = 701 + INTEGER(IntKi), PARAMETER :: M6N9MKze = 702 + INTEGER(IntKi), PARAMETER :: M7N1MKze = 703 + INTEGER(IntKi), PARAMETER :: M7N2MKze = 704 + INTEGER(IntKi), PARAMETER :: M7N3MKze = 705 + INTEGER(IntKi), PARAMETER :: M7N4MKze = 706 + INTEGER(IntKi), PARAMETER :: M7N5MKze = 707 + INTEGER(IntKi), PARAMETER :: M7N6MKze = 708 + INTEGER(IntKi), PARAMETER :: M7N7MKze = 709 + INTEGER(IntKi), PARAMETER :: M7N8MKze = 710 + INTEGER(IntKi), PARAMETER :: M7N9MKze = 711 + INTEGER(IntKi), PARAMETER :: M8N1MKze = 712 + INTEGER(IntKi), PARAMETER :: M8N2MKze = 713 + INTEGER(IntKi), PARAMETER :: M8N3MKze = 714 + INTEGER(IntKi), PARAMETER :: M8N4MKze = 715 + INTEGER(IntKi), PARAMETER :: M8N5MKze = 716 + INTEGER(IntKi), PARAMETER :: M8N6MKze = 717 + INTEGER(IntKi), PARAMETER :: M8N7MKze = 718 + INTEGER(IntKi), PARAMETER :: M8N8MKze = 719 + INTEGER(IntKi), PARAMETER :: M8N9MKze = 720 + INTEGER(IntKi), PARAMETER :: M9N1MKze = 721 + INTEGER(IntKi), PARAMETER :: M9N2MKze = 722 + INTEGER(IntKi), PARAMETER :: M9N3MKze = 723 + INTEGER(IntKi), PARAMETER :: M9N4MKze = 724 + INTEGER(IntKi), PARAMETER :: M9N5MKze = 725 + INTEGER(IntKi), PARAMETER :: M9N6MKze = 726 + INTEGER(IntKi), PARAMETER :: M9N7MKze = 727 + INTEGER(IntKi), PARAMETER :: M9N8MKze = 728 + INTEGER(IntKi), PARAMETER :: M9N9MKze = 729 + INTEGER(IntKi), PARAMETER :: M1N1MMxe = 730 + INTEGER(IntKi), PARAMETER :: M1N2MMxe = 731 + INTEGER(IntKi), PARAMETER :: M1N3MMxe = 732 + INTEGER(IntKi), PARAMETER :: M1N4MMxe = 733 + INTEGER(IntKi), PARAMETER :: M1N5MMxe = 734 + INTEGER(IntKi), PARAMETER :: M1N6MMxe = 735 + INTEGER(IntKi), PARAMETER :: M1N7MMxe = 736 + INTEGER(IntKi), PARAMETER :: M1N8MMxe = 737 + INTEGER(IntKi), PARAMETER :: M1N9MMxe = 738 + INTEGER(IntKi), PARAMETER :: M2N1MMxe = 739 + INTEGER(IntKi), PARAMETER :: M2N2MMxe = 740 + INTEGER(IntKi), PARAMETER :: M2N3MMxe = 741 + INTEGER(IntKi), PARAMETER :: M2N4MMxe = 742 + INTEGER(IntKi), PARAMETER :: M2N5MMxe = 743 + INTEGER(IntKi), PARAMETER :: M2N6MMxe = 744 + INTEGER(IntKi), PARAMETER :: M2N7MMxe = 745 + INTEGER(IntKi), PARAMETER :: M2N8MMxe = 746 + INTEGER(IntKi), PARAMETER :: M2N9MMxe = 747 + INTEGER(IntKi), PARAMETER :: M3N1MMxe = 748 + INTEGER(IntKi), PARAMETER :: M3N2MMxe = 749 + INTEGER(IntKi), PARAMETER :: M3N3MMxe = 750 + INTEGER(IntKi), PARAMETER :: M3N4MMxe = 751 + INTEGER(IntKi), PARAMETER :: M3N5MMxe = 752 + INTEGER(IntKi), PARAMETER :: M3N6MMxe = 753 + INTEGER(IntKi), PARAMETER :: M3N7MMxe = 754 + INTEGER(IntKi), PARAMETER :: M3N8MMxe = 755 + INTEGER(IntKi), PARAMETER :: M3N9MMxe = 756 + INTEGER(IntKi), PARAMETER :: M4N1MMxe = 757 + INTEGER(IntKi), PARAMETER :: M4N2MMxe = 758 + INTEGER(IntKi), PARAMETER :: M4N3MMxe = 759 + INTEGER(IntKi), PARAMETER :: M4N4MMxe = 760 + INTEGER(IntKi), PARAMETER :: M4N5MMxe = 761 + INTEGER(IntKi), PARAMETER :: M4N6MMxe = 762 + INTEGER(IntKi), PARAMETER :: M4N7MMxe = 763 + INTEGER(IntKi), PARAMETER :: M4N8MMxe = 764 + INTEGER(IntKi), PARAMETER :: M4N9MMxe = 765 + INTEGER(IntKi), PARAMETER :: M5N1MMxe = 766 + INTEGER(IntKi), PARAMETER :: M5N2MMxe = 767 + INTEGER(IntKi), PARAMETER :: M5N3MMxe = 768 + INTEGER(IntKi), PARAMETER :: M5N4MMxe = 769 + INTEGER(IntKi), PARAMETER :: M5N5MMxe = 770 + INTEGER(IntKi), PARAMETER :: M5N6MMxe = 771 + INTEGER(IntKi), PARAMETER :: M5N7MMxe = 772 + INTEGER(IntKi), PARAMETER :: M5N8MMxe = 773 + INTEGER(IntKi), PARAMETER :: M5N9MMxe = 774 + INTEGER(IntKi), PARAMETER :: M6N1MMxe = 775 + INTEGER(IntKi), PARAMETER :: M6N2MMxe = 776 + INTEGER(IntKi), PARAMETER :: M6N3MMxe = 777 + INTEGER(IntKi), PARAMETER :: M6N4MMxe = 778 + INTEGER(IntKi), PARAMETER :: M6N5MMxe = 779 + INTEGER(IntKi), PARAMETER :: M6N6MMxe = 780 + INTEGER(IntKi), PARAMETER :: M6N7MMxe = 781 + INTEGER(IntKi), PARAMETER :: M6N8MMxe = 782 + INTEGER(IntKi), PARAMETER :: M6N9MMxe = 783 + INTEGER(IntKi), PARAMETER :: M7N1MMxe = 784 + INTEGER(IntKi), PARAMETER :: M7N2MMxe = 785 + INTEGER(IntKi), PARAMETER :: M7N3MMxe = 786 + INTEGER(IntKi), PARAMETER :: M7N4MMxe = 787 + INTEGER(IntKi), PARAMETER :: M7N5MMxe = 788 + INTEGER(IntKi), PARAMETER :: M7N6MMxe = 789 + INTEGER(IntKi), PARAMETER :: M7N7MMxe = 790 + INTEGER(IntKi), PARAMETER :: M7N8MMxe = 791 + INTEGER(IntKi), PARAMETER :: M7N9MMxe = 792 + INTEGER(IntKi), PARAMETER :: M8N1MMxe = 793 + INTEGER(IntKi), PARAMETER :: M8N2MMxe = 794 + INTEGER(IntKi), PARAMETER :: M8N3MMxe = 795 + INTEGER(IntKi), PARAMETER :: M8N4MMxe = 796 + INTEGER(IntKi), PARAMETER :: M8N5MMxe = 797 + INTEGER(IntKi), PARAMETER :: M8N6MMxe = 798 + INTEGER(IntKi), PARAMETER :: M8N7MMxe = 799 + INTEGER(IntKi), PARAMETER :: M8N8MMxe = 800 + INTEGER(IntKi), PARAMETER :: M8N9MMxe = 801 + INTEGER(IntKi), PARAMETER :: M9N1MMxe = 802 + INTEGER(IntKi), PARAMETER :: M9N2MMxe = 803 + INTEGER(IntKi), PARAMETER :: M9N3MMxe = 804 + INTEGER(IntKi), PARAMETER :: M9N4MMxe = 805 + INTEGER(IntKi), PARAMETER :: M9N5MMxe = 806 + INTEGER(IntKi), PARAMETER :: M9N6MMxe = 807 + INTEGER(IntKi), PARAMETER :: M9N7MMxe = 808 + INTEGER(IntKi), PARAMETER :: M9N8MMxe = 809 + INTEGER(IntKi), PARAMETER :: M9N9MMxe = 810 + INTEGER(IntKi), PARAMETER :: M1N1MMye = 811 + INTEGER(IntKi), PARAMETER :: M1N2MMye = 812 + INTEGER(IntKi), PARAMETER :: M1N3MMye = 813 + INTEGER(IntKi), PARAMETER :: M1N4MMye = 814 + INTEGER(IntKi), PARAMETER :: M1N5MMye = 815 + INTEGER(IntKi), PARAMETER :: M1N6MMye = 816 + INTEGER(IntKi), PARAMETER :: M1N7MMye = 817 + INTEGER(IntKi), PARAMETER :: M1N8MMye = 818 + INTEGER(IntKi), PARAMETER :: M1N9MMye = 819 + INTEGER(IntKi), PARAMETER :: M2N1MMye = 820 + INTEGER(IntKi), PARAMETER :: M2N2MMye = 821 + INTEGER(IntKi), PARAMETER :: M2N3MMye = 822 + INTEGER(IntKi), PARAMETER :: M2N4MMye = 823 + INTEGER(IntKi), PARAMETER :: M2N5MMye = 824 + INTEGER(IntKi), PARAMETER :: M2N6MMye = 825 + INTEGER(IntKi), PARAMETER :: M2N7MMye = 826 + INTEGER(IntKi), PARAMETER :: M2N8MMye = 827 + INTEGER(IntKi), PARAMETER :: M2N9MMye = 828 + INTEGER(IntKi), PARAMETER :: M3N1MMye = 829 + INTEGER(IntKi), PARAMETER :: M3N2MMye = 830 + INTEGER(IntKi), PARAMETER :: M3N3MMye = 831 + INTEGER(IntKi), PARAMETER :: M3N4MMye = 832 + INTEGER(IntKi), PARAMETER :: M3N5MMye = 833 + INTEGER(IntKi), PARAMETER :: M3N6MMye = 834 + INTEGER(IntKi), PARAMETER :: M3N7MMye = 835 + INTEGER(IntKi), PARAMETER :: M3N8MMye = 836 + INTEGER(IntKi), PARAMETER :: M3N9MMye = 837 + INTEGER(IntKi), PARAMETER :: M4N1MMye = 838 + INTEGER(IntKi), PARAMETER :: M4N2MMye = 839 + INTEGER(IntKi), PARAMETER :: M4N3MMye = 840 + INTEGER(IntKi), PARAMETER :: M4N4MMye = 841 + INTEGER(IntKi), PARAMETER :: M4N5MMye = 842 + INTEGER(IntKi), PARAMETER :: M4N6MMye = 843 + INTEGER(IntKi), PARAMETER :: M4N7MMye = 844 + INTEGER(IntKi), PARAMETER :: M4N8MMye = 845 + INTEGER(IntKi), PARAMETER :: M4N9MMye = 846 + INTEGER(IntKi), PARAMETER :: M5N1MMye = 847 + INTEGER(IntKi), PARAMETER :: M5N2MMye = 848 + INTEGER(IntKi), PARAMETER :: M5N3MMye = 849 + INTEGER(IntKi), PARAMETER :: M5N4MMye = 850 + INTEGER(IntKi), PARAMETER :: M5N5MMye = 851 + INTEGER(IntKi), PARAMETER :: M5N6MMye = 852 + INTEGER(IntKi), PARAMETER :: M5N7MMye = 853 + INTEGER(IntKi), PARAMETER :: M5N8MMye = 854 + INTEGER(IntKi), PARAMETER :: M5N9MMye = 855 + INTEGER(IntKi), PARAMETER :: M6N1MMye = 856 + INTEGER(IntKi), PARAMETER :: M6N2MMye = 857 + INTEGER(IntKi), PARAMETER :: M6N3MMye = 858 + INTEGER(IntKi), PARAMETER :: M6N4MMye = 859 + INTEGER(IntKi), PARAMETER :: M6N5MMye = 860 + INTEGER(IntKi), PARAMETER :: M6N6MMye = 861 + INTEGER(IntKi), PARAMETER :: M6N7MMye = 862 + INTEGER(IntKi), PARAMETER :: M6N8MMye = 863 + INTEGER(IntKi), PARAMETER :: M6N9MMye = 864 + INTEGER(IntKi), PARAMETER :: M7N1MMye = 865 + INTEGER(IntKi), PARAMETER :: M7N2MMye = 866 + INTEGER(IntKi), PARAMETER :: M7N3MMye = 867 + INTEGER(IntKi), PARAMETER :: M7N4MMye = 868 + INTEGER(IntKi), PARAMETER :: M7N5MMye = 869 + INTEGER(IntKi), PARAMETER :: M7N6MMye = 870 + INTEGER(IntKi), PARAMETER :: M7N7MMye = 871 + INTEGER(IntKi), PARAMETER :: M7N8MMye = 872 + INTEGER(IntKi), PARAMETER :: M7N9MMye = 873 + INTEGER(IntKi), PARAMETER :: M8N1MMye = 874 + INTEGER(IntKi), PARAMETER :: M8N2MMye = 875 + INTEGER(IntKi), PARAMETER :: M8N3MMye = 876 + INTEGER(IntKi), PARAMETER :: M8N4MMye = 877 + INTEGER(IntKi), PARAMETER :: M8N5MMye = 878 + INTEGER(IntKi), PARAMETER :: M8N6MMye = 879 + INTEGER(IntKi), PARAMETER :: M8N7MMye = 880 + INTEGER(IntKi), PARAMETER :: M8N8MMye = 881 + INTEGER(IntKi), PARAMETER :: M8N9MMye = 882 + INTEGER(IntKi), PARAMETER :: M9N1MMye = 883 + INTEGER(IntKi), PARAMETER :: M9N2MMye = 884 + INTEGER(IntKi), PARAMETER :: M9N3MMye = 885 + INTEGER(IntKi), PARAMETER :: M9N4MMye = 886 + INTEGER(IntKi), PARAMETER :: M9N5MMye = 887 + INTEGER(IntKi), PARAMETER :: M9N6MMye = 888 + INTEGER(IntKi), PARAMETER :: M9N7MMye = 889 + INTEGER(IntKi), PARAMETER :: M9N8MMye = 890 + INTEGER(IntKi), PARAMETER :: M9N9MMye = 891 + INTEGER(IntKi), PARAMETER :: M1N1MMze = 892 + INTEGER(IntKi), PARAMETER :: M1N2MMze = 893 + INTEGER(IntKi), PARAMETER :: M1N3MMze = 894 + INTEGER(IntKi), PARAMETER :: M1N4MMze = 895 + INTEGER(IntKi), PARAMETER :: M1N5MMze = 896 + INTEGER(IntKi), PARAMETER :: M1N6MMze = 897 + INTEGER(IntKi), PARAMETER :: M1N7MMze = 898 + INTEGER(IntKi), PARAMETER :: M1N8MMze = 899 + INTEGER(IntKi), PARAMETER :: M1N9MMze = 900 + INTEGER(IntKi), PARAMETER :: M2N1MMze = 901 + INTEGER(IntKi), PARAMETER :: M2N2MMze = 902 + INTEGER(IntKi), PARAMETER :: M2N3MMze = 903 + INTEGER(IntKi), PARAMETER :: M2N4MMze = 904 + INTEGER(IntKi), PARAMETER :: M2N5MMze = 905 + INTEGER(IntKi), PARAMETER :: M2N6MMze = 906 + INTEGER(IntKi), PARAMETER :: M2N7MMze = 907 + INTEGER(IntKi), PARAMETER :: M2N8MMze = 908 + INTEGER(IntKi), PARAMETER :: M2N9MMze = 909 + INTEGER(IntKi), PARAMETER :: M3N1MMze = 910 + INTEGER(IntKi), PARAMETER :: M3N2MMze = 911 + INTEGER(IntKi), PARAMETER :: M3N3MMze = 912 + INTEGER(IntKi), PARAMETER :: M3N4MMze = 913 + INTEGER(IntKi), PARAMETER :: M3N5MMze = 914 + INTEGER(IntKi), PARAMETER :: M3N6MMze = 915 + INTEGER(IntKi), PARAMETER :: M3N7MMze = 916 + INTEGER(IntKi), PARAMETER :: M3N8MMze = 917 + INTEGER(IntKi), PARAMETER :: M3N9MMze = 918 + INTEGER(IntKi), PARAMETER :: M4N1MMze = 919 + INTEGER(IntKi), PARAMETER :: M4N2MMze = 920 + INTEGER(IntKi), PARAMETER :: M4N3MMze = 921 + INTEGER(IntKi), PARAMETER :: M4N4MMze = 922 + INTEGER(IntKi), PARAMETER :: M4N5MMze = 923 + INTEGER(IntKi), PARAMETER :: M4N6MMze = 924 + INTEGER(IntKi), PARAMETER :: M4N7MMze = 925 + INTEGER(IntKi), PARAMETER :: M4N8MMze = 926 + INTEGER(IntKi), PARAMETER :: M4N9MMze = 927 + INTEGER(IntKi), PARAMETER :: M5N1MMze = 928 + INTEGER(IntKi), PARAMETER :: M5N2MMze = 929 + INTEGER(IntKi), PARAMETER :: M5N3MMze = 930 + INTEGER(IntKi), PARAMETER :: M5N4MMze = 931 + INTEGER(IntKi), PARAMETER :: M5N5MMze = 932 + INTEGER(IntKi), PARAMETER :: M5N6MMze = 933 + INTEGER(IntKi), PARAMETER :: M5N7MMze = 934 + INTEGER(IntKi), PARAMETER :: M5N8MMze = 935 + INTEGER(IntKi), PARAMETER :: M5N9MMze = 936 + INTEGER(IntKi), PARAMETER :: M6N1MMze = 937 + INTEGER(IntKi), PARAMETER :: M6N2MMze = 938 + INTEGER(IntKi), PARAMETER :: M6N3MMze = 939 + INTEGER(IntKi), PARAMETER :: M6N4MMze = 940 + INTEGER(IntKi), PARAMETER :: M6N5MMze = 941 + INTEGER(IntKi), PARAMETER :: M6N6MMze = 942 + INTEGER(IntKi), PARAMETER :: M6N7MMze = 943 + INTEGER(IntKi), PARAMETER :: M6N8MMze = 944 + INTEGER(IntKi), PARAMETER :: M6N9MMze = 945 + INTEGER(IntKi), PARAMETER :: M7N1MMze = 946 + INTEGER(IntKi), PARAMETER :: M7N2MMze = 947 + INTEGER(IntKi), PARAMETER :: M7N3MMze = 948 + INTEGER(IntKi), PARAMETER :: M7N4MMze = 949 + INTEGER(IntKi), PARAMETER :: M7N5MMze = 950 + INTEGER(IntKi), PARAMETER :: M7N6MMze = 951 + INTEGER(IntKi), PARAMETER :: M7N7MMze = 952 + INTEGER(IntKi), PARAMETER :: M7N8MMze = 953 + INTEGER(IntKi), PARAMETER :: M7N9MMze = 954 + INTEGER(IntKi), PARAMETER :: M8N1MMze = 955 + INTEGER(IntKi), PARAMETER :: M8N2MMze = 956 + INTEGER(IntKi), PARAMETER :: M8N3MMze = 957 + INTEGER(IntKi), PARAMETER :: M8N4MMze = 958 + INTEGER(IntKi), PARAMETER :: M8N5MMze = 959 + INTEGER(IntKi), PARAMETER :: M8N6MMze = 960 + INTEGER(IntKi), PARAMETER :: M8N7MMze = 961 + INTEGER(IntKi), PARAMETER :: M8N8MMze = 962 + INTEGER(IntKi), PARAMETER :: M8N9MMze = 963 + INTEGER(IntKi), PARAMETER :: M9N1MMze = 964 + INTEGER(IntKi), PARAMETER :: M9N2MMze = 965 + INTEGER(IntKi), PARAMETER :: M9N3MMze = 966 + INTEGER(IntKi), PARAMETER :: M9N4MMze = 967 + INTEGER(IntKi), PARAMETER :: M9N5MMze = 968 + INTEGER(IntKi), PARAMETER :: M9N6MMze = 969 + INTEGER(IntKi), PARAMETER :: M9N7MMze = 970 + INTEGER(IntKi), PARAMETER :: M9N8MMze = 971 + INTEGER(IntKi), PARAMETER :: M9N9MMze = 972 + + + ! Displacements: + + INTEGER(IntKi), PARAMETER :: M1N1TDxss = 973 + INTEGER(IntKi), PARAMETER :: M1N2TDxss = 974 + INTEGER(IntKi), PARAMETER :: M1N3TDxss = 975 + INTEGER(IntKi), PARAMETER :: M1N4TDxss = 976 + INTEGER(IntKi), PARAMETER :: M1N5TDxss = 977 + INTEGER(IntKi), PARAMETER :: M1N6TDxss = 978 + INTEGER(IntKi), PARAMETER :: M1N7TDxss = 979 + INTEGER(IntKi), PARAMETER :: M1N8TDxss = 980 + INTEGER(IntKi), PARAMETER :: M1N9TDxss = 981 + INTEGER(IntKi), PARAMETER :: M2N1TDxss = 982 + INTEGER(IntKi), PARAMETER :: M2N2TDxss = 983 + INTEGER(IntKi), PARAMETER :: M2N3TDxss = 984 + INTEGER(IntKi), PARAMETER :: M2N4TDxss = 985 + INTEGER(IntKi), PARAMETER :: M2N5TDxss = 986 + INTEGER(IntKi), PARAMETER :: M2N6TDxss = 987 + INTEGER(IntKi), PARAMETER :: M2N7TDxss = 988 + INTEGER(IntKi), PARAMETER :: M2N8TDxss = 989 + INTEGER(IntKi), PARAMETER :: M2N9TDxss = 990 + INTEGER(IntKi), PARAMETER :: M3N1TDxss = 991 + INTEGER(IntKi), PARAMETER :: M3N2TDxss = 992 + INTEGER(IntKi), PARAMETER :: M3N3TDxss = 993 + INTEGER(IntKi), PARAMETER :: M3N4TDxss = 994 + INTEGER(IntKi), PARAMETER :: M3N5TDxss = 995 + INTEGER(IntKi), PARAMETER :: M3N6TDxss = 996 + INTEGER(IntKi), PARAMETER :: M3N7TDxss = 997 + INTEGER(IntKi), PARAMETER :: M3N8TDxss = 998 + INTEGER(IntKi), PARAMETER :: M3N9TDxss = 999 + INTEGER(IntKi), PARAMETER :: M4N1TDxss = 1000 + INTEGER(IntKi), PARAMETER :: M4N2TDxss = 1001 + INTEGER(IntKi), PARAMETER :: M4N3TDxss = 1002 + INTEGER(IntKi), PARAMETER :: M4N4TDxss = 1003 + INTEGER(IntKi), PARAMETER :: M4N5TDxss = 1004 + INTEGER(IntKi), PARAMETER :: M4N6TDxss = 1005 + INTEGER(IntKi), PARAMETER :: M4N7TDxss = 1006 + INTEGER(IntKi), PARAMETER :: M4N8TDxss = 1007 + INTEGER(IntKi), PARAMETER :: M4N9TDxss = 1008 + INTEGER(IntKi), PARAMETER :: M5N1TDxss = 1009 + INTEGER(IntKi), PARAMETER :: M5N2TDxss = 1010 + INTEGER(IntKi), PARAMETER :: M5N3TDxss = 1011 + INTEGER(IntKi), PARAMETER :: M5N4TDxss = 1012 + INTEGER(IntKi), PARAMETER :: M5N5TDxss = 1013 + INTEGER(IntKi), PARAMETER :: M5N6TDxss = 1014 + INTEGER(IntKi), PARAMETER :: M5N7TDxss = 1015 + INTEGER(IntKi), PARAMETER :: M5N8TDxss = 1016 + INTEGER(IntKi), PARAMETER :: M5N9TDxss = 1017 + INTEGER(IntKi), PARAMETER :: M6N1TDxss = 1018 + INTEGER(IntKi), PARAMETER :: M6N2TDxss = 1019 + INTEGER(IntKi), PARAMETER :: M6N3TDxss = 1020 + INTEGER(IntKi), PARAMETER :: M6N4TDxss = 1021 + INTEGER(IntKi), PARAMETER :: M6N5TDxss = 1022 + INTEGER(IntKi), PARAMETER :: M6N6TDxss = 1023 + INTEGER(IntKi), PARAMETER :: M6N7TDxss = 1024 + INTEGER(IntKi), PARAMETER :: M6N8TDxss = 1025 + INTEGER(IntKi), PARAMETER :: M6N9TDxss = 1026 + INTEGER(IntKi), PARAMETER :: M7N1TDxss = 1027 + INTEGER(IntKi), PARAMETER :: M7N2TDxss = 1028 + INTEGER(IntKi), PARAMETER :: M7N3TDxss = 1029 + INTEGER(IntKi), PARAMETER :: M7N4TDxss = 1030 + INTEGER(IntKi), PARAMETER :: M7N5TDxss = 1031 + INTEGER(IntKi), PARAMETER :: M7N6TDxss = 1032 + INTEGER(IntKi), PARAMETER :: M7N7TDxss = 1033 + INTEGER(IntKi), PARAMETER :: M7N8TDxss = 1034 + INTEGER(IntKi), PARAMETER :: M7N9TDxss = 1035 + INTEGER(IntKi), PARAMETER :: M8N1TDxss = 1036 + INTEGER(IntKi), PARAMETER :: M8N2TDxss = 1037 + INTEGER(IntKi), PARAMETER :: M8N3TDxss = 1038 + INTEGER(IntKi), PARAMETER :: M8N4TDxss = 1039 + INTEGER(IntKi), PARAMETER :: M8N5TDxss = 1040 + INTEGER(IntKi), PARAMETER :: M8N6TDxss = 1041 + INTEGER(IntKi), PARAMETER :: M8N7TDxss = 1042 + INTEGER(IntKi), PARAMETER :: M8N8TDxss = 1043 + INTEGER(IntKi), PARAMETER :: M8N9TDxss = 1044 + INTEGER(IntKi), PARAMETER :: M9N1TDxss = 1045 + INTEGER(IntKi), PARAMETER :: M9N2TDxss = 1046 + INTEGER(IntKi), PARAMETER :: M9N3TDxss = 1047 + INTEGER(IntKi), PARAMETER :: M9N4TDxss = 1048 + INTEGER(IntKi), PARAMETER :: M9N5TDxss = 1049 + INTEGER(IntKi), PARAMETER :: M9N6TDxss = 1050 + INTEGER(IntKi), PARAMETER :: M9N7TDxss = 1051 + INTEGER(IntKi), PARAMETER :: M9N8TDxss = 1052 + INTEGER(IntKi), PARAMETER :: M9N9TDxss = 1053 + INTEGER(IntKi), PARAMETER :: M1N1TDyss = 1054 + INTEGER(IntKi), PARAMETER :: M1N2TDyss = 1055 + INTEGER(IntKi), PARAMETER :: M1N3TDyss = 1056 + INTEGER(IntKi), PARAMETER :: M1N4TDyss = 1057 + INTEGER(IntKi), PARAMETER :: M1N5TDyss = 1058 + INTEGER(IntKi), PARAMETER :: M1N6TDyss = 1059 + INTEGER(IntKi), PARAMETER :: M1N7TDyss = 1060 + INTEGER(IntKi), PARAMETER :: M1N8TDyss = 1061 + INTEGER(IntKi), PARAMETER :: M1N9TDyss = 1062 + INTEGER(IntKi), PARAMETER :: M2N1TDyss = 1063 + INTEGER(IntKi), PARAMETER :: M2N2TDyss = 1064 + INTEGER(IntKi), PARAMETER :: M2N3TDyss = 1065 + INTEGER(IntKi), PARAMETER :: M2N4TDyss = 1066 + INTEGER(IntKi), PARAMETER :: M2N5TDyss = 1067 + INTEGER(IntKi), PARAMETER :: M2N6TDyss = 1068 + INTEGER(IntKi), PARAMETER :: M2N7TDyss = 1069 + INTEGER(IntKi), PARAMETER :: M2N8TDyss = 1070 + INTEGER(IntKi), PARAMETER :: M2N9TDyss = 1071 + INTEGER(IntKi), PARAMETER :: M3N1TDyss = 1072 + INTEGER(IntKi), PARAMETER :: M3N2TDyss = 1073 + INTEGER(IntKi), PARAMETER :: M3N3TDyss = 1074 + INTEGER(IntKi), PARAMETER :: M3N4TDyss = 1075 + INTEGER(IntKi), PARAMETER :: M3N5TDyss = 1076 + INTEGER(IntKi), PARAMETER :: M3N6TDyss = 1077 + INTEGER(IntKi), PARAMETER :: M3N7TDyss = 1078 + INTEGER(IntKi), PARAMETER :: M3N8TDyss = 1079 + INTEGER(IntKi), PARAMETER :: M3N9TDyss = 1080 + INTEGER(IntKi), PARAMETER :: M4N1TDyss = 1081 + INTEGER(IntKi), PARAMETER :: M4N2TDyss = 1082 + INTEGER(IntKi), PARAMETER :: M4N3TDyss = 1083 + INTEGER(IntKi), PARAMETER :: M4N4TDyss = 1084 + INTEGER(IntKi), PARAMETER :: M4N5TDyss = 1085 + INTEGER(IntKi), PARAMETER :: M4N6TDyss = 1086 + INTEGER(IntKi), PARAMETER :: M4N7TDyss = 1087 + INTEGER(IntKi), PARAMETER :: M4N8TDyss = 1088 + INTEGER(IntKi), PARAMETER :: M4N9TDyss = 1089 + INTEGER(IntKi), PARAMETER :: M5N1TDyss = 1090 + INTEGER(IntKi), PARAMETER :: M5N2TDyss = 1091 + INTEGER(IntKi), PARAMETER :: M5N3TDyss = 1092 + INTEGER(IntKi), PARAMETER :: M5N4TDyss = 1093 + INTEGER(IntKi), PARAMETER :: M5N5TDyss = 1094 + INTEGER(IntKi), PARAMETER :: M5N6TDyss = 1095 + INTEGER(IntKi), PARAMETER :: M5N7TDyss = 1096 + INTEGER(IntKi), PARAMETER :: M5N8TDyss = 1097 + INTEGER(IntKi), PARAMETER :: M5N9TDyss = 1098 + INTEGER(IntKi), PARAMETER :: M6N1TDyss = 1099 + INTEGER(IntKi), PARAMETER :: M6N2TDyss = 1100 + INTEGER(IntKi), PARAMETER :: M6N3TDyss = 1101 + INTEGER(IntKi), PARAMETER :: M6N4TDyss = 1102 + INTEGER(IntKi), PARAMETER :: M6N5TDyss = 1103 + INTEGER(IntKi), PARAMETER :: M6N6TDyss = 1104 + INTEGER(IntKi), PARAMETER :: M6N7TDyss = 1105 + INTEGER(IntKi), PARAMETER :: M6N8TDyss = 1106 + INTEGER(IntKi), PARAMETER :: M6N9TDyss = 1107 + INTEGER(IntKi), PARAMETER :: M7N1TDyss = 1108 + INTEGER(IntKi), PARAMETER :: M7N2TDyss = 1109 + INTEGER(IntKi), PARAMETER :: M7N3TDyss = 1110 + INTEGER(IntKi), PARAMETER :: M7N4TDyss = 1111 + INTEGER(IntKi), PARAMETER :: M7N5TDyss = 1112 + INTEGER(IntKi), PARAMETER :: M7N6TDyss = 1113 + INTEGER(IntKi), PARAMETER :: M7N7TDyss = 1114 + INTEGER(IntKi), PARAMETER :: M7N8TDyss = 1115 + INTEGER(IntKi), PARAMETER :: M7N9TDyss = 1116 + INTEGER(IntKi), PARAMETER :: M8N1TDyss = 1117 + INTEGER(IntKi), PARAMETER :: M8N2TDyss = 1118 + INTEGER(IntKi), PARAMETER :: M8N3TDyss = 1119 + INTEGER(IntKi), PARAMETER :: M8N4TDyss = 1120 + INTEGER(IntKi), PARAMETER :: M8N5TDyss = 1121 + INTEGER(IntKi), PARAMETER :: M8N6TDyss = 1122 + INTEGER(IntKi), PARAMETER :: M8N7TDyss = 1123 + INTEGER(IntKi), PARAMETER :: M8N8TDyss = 1124 + INTEGER(IntKi), PARAMETER :: M8N9TDyss = 1125 + INTEGER(IntKi), PARAMETER :: M9N1TDyss = 1126 + INTEGER(IntKi), PARAMETER :: M9N2TDyss = 1127 + INTEGER(IntKi), PARAMETER :: M9N3TDyss = 1128 + INTEGER(IntKi), PARAMETER :: M9N4TDyss = 1129 + INTEGER(IntKi), PARAMETER :: M9N5TDyss = 1130 + INTEGER(IntKi), PARAMETER :: M9N6TDyss = 1131 + INTEGER(IntKi), PARAMETER :: M9N7TDyss = 1132 + INTEGER(IntKi), PARAMETER :: M9N8TDyss = 1133 + INTEGER(IntKi), PARAMETER :: M9N9TDyss = 1134 + INTEGER(IntKi), PARAMETER :: M1N1TDzss = 1135 + INTEGER(IntKi), PARAMETER :: M1N2TDzss = 1136 + INTEGER(IntKi), PARAMETER :: M1N3TDzss = 1137 + INTEGER(IntKi), PARAMETER :: M1N4TDzss = 1138 + INTEGER(IntKi), PARAMETER :: M1N5TDzss = 1139 + INTEGER(IntKi), PARAMETER :: M1N6TDzss = 1140 + INTEGER(IntKi), PARAMETER :: M1N7TDzss = 1141 + INTEGER(IntKi), PARAMETER :: M1N8TDzss = 1142 + INTEGER(IntKi), PARAMETER :: M1N9TDzss = 1143 + INTEGER(IntKi), PARAMETER :: M2N1TDzss = 1144 + INTEGER(IntKi), PARAMETER :: M2N2TDzss = 1145 + INTEGER(IntKi), PARAMETER :: M2N3TDzss = 1146 + INTEGER(IntKi), PARAMETER :: M2N4TDzss = 1147 + INTEGER(IntKi), PARAMETER :: M2N5TDzss = 1148 + INTEGER(IntKi), PARAMETER :: M2N6TDzss = 1149 + INTEGER(IntKi), PARAMETER :: M2N7TDzss = 1150 + INTEGER(IntKi), PARAMETER :: M2N8TDzss = 1151 + INTEGER(IntKi), PARAMETER :: M2N9TDzss = 1152 + INTEGER(IntKi), PARAMETER :: M3N1TDzss = 1153 + INTEGER(IntKi), PARAMETER :: M3N2TDzss = 1154 + INTEGER(IntKi), PARAMETER :: M3N3TDzss = 1155 + INTEGER(IntKi), PARAMETER :: M3N4TDzss = 1156 + INTEGER(IntKi), PARAMETER :: M3N5TDzss = 1157 + INTEGER(IntKi), PARAMETER :: M3N6TDzss = 1158 + INTEGER(IntKi), PARAMETER :: M3N7TDzss = 1159 + INTEGER(IntKi), PARAMETER :: M3N8TDzss = 1160 + INTEGER(IntKi), PARAMETER :: M3N9TDzss = 1161 + INTEGER(IntKi), PARAMETER :: M4N1TDzss = 1162 + INTEGER(IntKi), PARAMETER :: M4N2TDzss = 1163 + INTEGER(IntKi), PARAMETER :: M4N3TDzss = 1164 + INTEGER(IntKi), PARAMETER :: M4N4TDzss = 1165 + INTEGER(IntKi), PARAMETER :: M4N5TDzss = 1166 + INTEGER(IntKi), PARAMETER :: M4N6TDzss = 1167 + INTEGER(IntKi), PARAMETER :: M4N7TDzss = 1168 + INTEGER(IntKi), PARAMETER :: M4N8TDzss = 1169 + INTEGER(IntKi), PARAMETER :: M4N9TDzss = 1170 + INTEGER(IntKi), PARAMETER :: M5N1TDzss = 1171 + INTEGER(IntKi), PARAMETER :: M5N2TDzss = 1172 + INTEGER(IntKi), PARAMETER :: M5N3TDzss = 1173 + INTEGER(IntKi), PARAMETER :: M5N4TDzss = 1174 + INTEGER(IntKi), PARAMETER :: M5N5TDzss = 1175 + INTEGER(IntKi), PARAMETER :: M5N6TDzss = 1176 + INTEGER(IntKi), PARAMETER :: M5N7TDzss = 1177 + INTEGER(IntKi), PARAMETER :: M5N8TDzss = 1178 + INTEGER(IntKi), PARAMETER :: M5N9TDzss = 1179 + INTEGER(IntKi), PARAMETER :: M6N1TDzss = 1180 + INTEGER(IntKi), PARAMETER :: M6N2TDzss = 1181 + INTEGER(IntKi), PARAMETER :: M6N3TDzss = 1182 + INTEGER(IntKi), PARAMETER :: M6N4TDzss = 1183 + INTEGER(IntKi), PARAMETER :: M6N5TDzss = 1184 + INTEGER(IntKi), PARAMETER :: M6N6TDzss = 1185 + INTEGER(IntKi), PARAMETER :: M6N7TDzss = 1186 + INTEGER(IntKi), PARAMETER :: M6N8TDzss = 1187 + INTEGER(IntKi), PARAMETER :: M6N9TDzss = 1188 + INTEGER(IntKi), PARAMETER :: M7N1TDzss = 1189 + INTEGER(IntKi), PARAMETER :: M7N2TDzss = 1190 + INTEGER(IntKi), PARAMETER :: M7N3TDzss = 1191 + INTEGER(IntKi), PARAMETER :: M7N4TDzss = 1192 + INTEGER(IntKi), PARAMETER :: M7N5TDzss = 1193 + INTEGER(IntKi), PARAMETER :: M7N6TDzss = 1194 + INTEGER(IntKi), PARAMETER :: M7N7TDzss = 1195 + INTEGER(IntKi), PARAMETER :: M7N8TDzss = 1196 + INTEGER(IntKi), PARAMETER :: M7N9TDzss = 1197 + INTEGER(IntKi), PARAMETER :: M8N1TDzss = 1198 + INTEGER(IntKi), PARAMETER :: M8N2TDzss = 1199 + INTEGER(IntKi), PARAMETER :: M8N3TDzss = 1200 + INTEGER(IntKi), PARAMETER :: M8N4TDzss = 1201 + INTEGER(IntKi), PARAMETER :: M8N5TDzss = 1202 + INTEGER(IntKi), PARAMETER :: M8N6TDzss = 1203 + INTEGER(IntKi), PARAMETER :: M8N7TDzss = 1204 + INTEGER(IntKi), PARAMETER :: M8N8TDzss = 1205 + INTEGER(IntKi), PARAMETER :: M8N9TDzss = 1206 + INTEGER(IntKi), PARAMETER :: M9N1TDzss = 1207 + INTEGER(IntKi), PARAMETER :: M9N2TDzss = 1208 + INTEGER(IntKi), PARAMETER :: M9N3TDzss = 1209 + INTEGER(IntKi), PARAMETER :: M9N4TDzss = 1210 + INTEGER(IntKi), PARAMETER :: M9N5TDzss = 1211 + INTEGER(IntKi), PARAMETER :: M9N6TDzss = 1212 + INTEGER(IntKi), PARAMETER :: M9N7TDzss = 1213 + INTEGER(IntKi), PARAMETER :: M9N8TDzss = 1214 + INTEGER(IntKi), PARAMETER :: M9N9TDzss = 1215 + INTEGER(IntKi), PARAMETER :: M1N1RDxe = 1216 + INTEGER(IntKi), PARAMETER :: M1N2RDxe = 1217 + INTEGER(IntKi), PARAMETER :: M1N3RDxe = 1218 + INTEGER(IntKi), PARAMETER :: M1N4RDxe = 1219 + INTEGER(IntKi), PARAMETER :: M1N5RDxe = 1220 + INTEGER(IntKi), PARAMETER :: M1N6RDxe = 1221 + INTEGER(IntKi), PARAMETER :: M1N7RDxe = 1222 + INTEGER(IntKi), PARAMETER :: M1N8RDxe = 1223 + INTEGER(IntKi), PARAMETER :: M1N9RDxe = 1224 + INTEGER(IntKi), PARAMETER :: M2N1RDxe = 1225 + INTEGER(IntKi), PARAMETER :: M2N2RDxe = 1226 + INTEGER(IntKi), PARAMETER :: M2N3RDxe = 1227 + INTEGER(IntKi), PARAMETER :: M2N4RDxe = 1228 + INTEGER(IntKi), PARAMETER :: M2N5RDxe = 1229 + INTEGER(IntKi), PARAMETER :: M2N6RDxe = 1230 + INTEGER(IntKi), PARAMETER :: M2N7RDxe = 1231 + INTEGER(IntKi), PARAMETER :: M2N8RDxe = 1232 + INTEGER(IntKi), PARAMETER :: M2N9RDxe = 1233 + INTEGER(IntKi), PARAMETER :: M3N1RDxe = 1234 + INTEGER(IntKi), PARAMETER :: M3N2RDxe = 1235 + INTEGER(IntKi), PARAMETER :: M3N3RDxe = 1236 + INTEGER(IntKi), PARAMETER :: M3N4RDxe = 1237 + INTEGER(IntKi), PARAMETER :: M3N5RDxe = 1238 + INTEGER(IntKi), PARAMETER :: M3N6RDxe = 1239 + INTEGER(IntKi), PARAMETER :: M3N7RDxe = 1240 + INTEGER(IntKi), PARAMETER :: M3N8RDxe = 1241 + INTEGER(IntKi), PARAMETER :: M3N9RDxe = 1242 + INTEGER(IntKi), PARAMETER :: M4N1RDxe = 1243 + INTEGER(IntKi), PARAMETER :: M4N2RDxe = 1244 + INTEGER(IntKi), PARAMETER :: M4N3RDxe = 1245 + INTEGER(IntKi), PARAMETER :: M4N4RDxe = 1246 + INTEGER(IntKi), PARAMETER :: M4N5RDxe = 1247 + INTEGER(IntKi), PARAMETER :: M4N6RDxe = 1248 + INTEGER(IntKi), PARAMETER :: M4N7RDxe = 1249 + INTEGER(IntKi), PARAMETER :: M4N8RDxe = 1250 + INTEGER(IntKi), PARAMETER :: M4N9RDxe = 1251 + INTEGER(IntKi), PARAMETER :: M5N1RDxe = 1252 + INTEGER(IntKi), PARAMETER :: M5N2RDxe = 1253 + INTEGER(IntKi), PARAMETER :: M5N3RDxe = 1254 + INTEGER(IntKi), PARAMETER :: M5N4RDxe = 1255 + INTEGER(IntKi), PARAMETER :: M5N5RDxe = 1256 + INTEGER(IntKi), PARAMETER :: M5N6RDxe = 1257 + INTEGER(IntKi), PARAMETER :: M5N7RDxe = 1258 + INTEGER(IntKi), PARAMETER :: M5N8RDxe = 1259 + INTEGER(IntKi), PARAMETER :: M5N9RDxe = 1260 + INTEGER(IntKi), PARAMETER :: M6N1RDxe = 1261 + INTEGER(IntKi), PARAMETER :: M6N2RDxe = 1262 + INTEGER(IntKi), PARAMETER :: M6N3RDxe = 1263 + INTEGER(IntKi), PARAMETER :: M6N4RDxe = 1264 + INTEGER(IntKi), PARAMETER :: M6N5RDxe = 1265 + INTEGER(IntKi), PARAMETER :: M6N6RDxe = 1266 + INTEGER(IntKi), PARAMETER :: M6N7RDxe = 1267 + INTEGER(IntKi), PARAMETER :: M6N8RDxe = 1268 + INTEGER(IntKi), PARAMETER :: M6N9RDxe = 1269 + INTEGER(IntKi), PARAMETER :: M7N1RDxe = 1270 + INTEGER(IntKi), PARAMETER :: M7N2RDxe = 1271 + INTEGER(IntKi), PARAMETER :: M7N3RDxe = 1272 + INTEGER(IntKi), PARAMETER :: M7N4RDxe = 1273 + INTEGER(IntKi), PARAMETER :: M7N5RDxe = 1274 + INTEGER(IntKi), PARAMETER :: M7N6RDxe = 1275 + INTEGER(IntKi), PARAMETER :: M7N7RDxe = 1276 + INTEGER(IntKi), PARAMETER :: M7N8RDxe = 1277 + INTEGER(IntKi), PARAMETER :: M7N9RDxe = 1278 + INTEGER(IntKi), PARAMETER :: M8N1RDxe = 1279 + INTEGER(IntKi), PARAMETER :: M8N2RDxe = 1280 + INTEGER(IntKi), PARAMETER :: M8N3RDxe = 1281 + INTEGER(IntKi), PARAMETER :: M8N4RDxe = 1282 + INTEGER(IntKi), PARAMETER :: M8N5RDxe = 1283 + INTEGER(IntKi), PARAMETER :: M8N6RDxe = 1284 + INTEGER(IntKi), PARAMETER :: M8N7RDxe = 1285 + INTEGER(IntKi), PARAMETER :: M8N8RDxe = 1286 + INTEGER(IntKi), PARAMETER :: M8N9RDxe = 1287 + INTEGER(IntKi), PARAMETER :: M9N1RDxe = 1288 + INTEGER(IntKi), PARAMETER :: M9N2RDxe = 1289 + INTEGER(IntKi), PARAMETER :: M9N3RDxe = 1290 + INTEGER(IntKi), PARAMETER :: M9N4RDxe = 1291 + INTEGER(IntKi), PARAMETER :: M9N5RDxe = 1292 + INTEGER(IntKi), PARAMETER :: M9N6RDxe = 1293 + INTEGER(IntKi), PARAMETER :: M9N7RDxe = 1294 + INTEGER(IntKi), PARAMETER :: M9N8RDxe = 1295 + INTEGER(IntKi), PARAMETER :: M9N9RDxe = 1296 + INTEGER(IntKi), PARAMETER :: M1N1RDye = 1297 + INTEGER(IntKi), PARAMETER :: M1N2RDye = 1298 + INTEGER(IntKi), PARAMETER :: M1N3RDye = 1299 + INTEGER(IntKi), PARAMETER :: M1N4RDye = 1300 + INTEGER(IntKi), PARAMETER :: M1N5RDye = 1301 + INTEGER(IntKi), PARAMETER :: M1N6RDye = 1302 + INTEGER(IntKi), PARAMETER :: M1N7RDye = 1303 + INTEGER(IntKi), PARAMETER :: M1N8RDye = 1304 + INTEGER(IntKi), PARAMETER :: M1N9RDye = 1305 + INTEGER(IntKi), PARAMETER :: M2N1RDye = 1306 + INTEGER(IntKi), PARAMETER :: M2N2RDye = 1307 + INTEGER(IntKi), PARAMETER :: M2N3RDye = 1308 + INTEGER(IntKi), PARAMETER :: M2N4RDye = 1309 + INTEGER(IntKi), PARAMETER :: M2N5RDye = 1310 + INTEGER(IntKi), PARAMETER :: M2N6RDye = 1311 + INTEGER(IntKi), PARAMETER :: M2N7RDye = 1312 + INTEGER(IntKi), PARAMETER :: M2N8RDye = 1313 + INTEGER(IntKi), PARAMETER :: M2N9RDye = 1314 + INTEGER(IntKi), PARAMETER :: M3N1RDye = 1315 + INTEGER(IntKi), PARAMETER :: M3N2RDye = 1316 + INTEGER(IntKi), PARAMETER :: M3N3RDye = 1317 + INTEGER(IntKi), PARAMETER :: M3N4RDye = 1318 + INTEGER(IntKi), PARAMETER :: M3N5RDye = 1319 + INTEGER(IntKi), PARAMETER :: M3N6RDye = 1320 + INTEGER(IntKi), PARAMETER :: M3N7RDye = 1321 + INTEGER(IntKi), PARAMETER :: M3N8RDye = 1322 + INTEGER(IntKi), PARAMETER :: M3N9RDye = 1323 + INTEGER(IntKi), PARAMETER :: M4N1RDye = 1324 + INTEGER(IntKi), PARAMETER :: M4N2RDye = 1325 + INTEGER(IntKi), PARAMETER :: M4N3RDye = 1326 + INTEGER(IntKi), PARAMETER :: M4N4RDye = 1327 + INTEGER(IntKi), PARAMETER :: M4N5RDye = 1328 + INTEGER(IntKi), PARAMETER :: M4N6RDye = 1329 + INTEGER(IntKi), PARAMETER :: M4N7RDye = 1330 + INTEGER(IntKi), PARAMETER :: M4N8RDye = 1331 + INTEGER(IntKi), PARAMETER :: M4N9RDye = 1332 + INTEGER(IntKi), PARAMETER :: M5N1RDye = 1333 + INTEGER(IntKi), PARAMETER :: M5N2RDye = 1334 + INTEGER(IntKi), PARAMETER :: M5N3RDye = 1335 + INTEGER(IntKi), PARAMETER :: M5N4RDye = 1336 + INTEGER(IntKi), PARAMETER :: M5N5RDye = 1337 + INTEGER(IntKi), PARAMETER :: M5N6RDye = 1338 + INTEGER(IntKi), PARAMETER :: M5N7RDye = 1339 + INTEGER(IntKi), PARAMETER :: M5N8RDye = 1340 + INTEGER(IntKi), PARAMETER :: M5N9RDye = 1341 + INTEGER(IntKi), PARAMETER :: M6N1RDye = 1342 + INTEGER(IntKi), PARAMETER :: M6N2RDye = 1343 + INTEGER(IntKi), PARAMETER :: M6N3RDye = 1344 + INTEGER(IntKi), PARAMETER :: M6N4RDye = 1345 + INTEGER(IntKi), PARAMETER :: M6N5RDye = 1346 + INTEGER(IntKi), PARAMETER :: M6N6RDye = 1347 + INTEGER(IntKi), PARAMETER :: M6N7RDye = 1348 + INTEGER(IntKi), PARAMETER :: M6N8RDye = 1349 + INTEGER(IntKi), PARAMETER :: M6N9RDye = 1350 + INTEGER(IntKi), PARAMETER :: M7N1RDye = 1351 + INTEGER(IntKi), PARAMETER :: M7N2RDye = 1352 + INTEGER(IntKi), PARAMETER :: M7N3RDye = 1353 + INTEGER(IntKi), PARAMETER :: M7N4RDye = 1354 + INTEGER(IntKi), PARAMETER :: M7N5RDye = 1355 + INTEGER(IntKi), PARAMETER :: M7N6RDye = 1356 + INTEGER(IntKi), PARAMETER :: M7N7RDye = 1357 + INTEGER(IntKi), PARAMETER :: M7N8RDye = 1358 + INTEGER(IntKi), PARAMETER :: M7N9RDye = 1359 + INTEGER(IntKi), PARAMETER :: M8N1RDye = 1360 + INTEGER(IntKi), PARAMETER :: M8N2RDye = 1361 + INTEGER(IntKi), PARAMETER :: M8N3RDye = 1362 + INTEGER(IntKi), PARAMETER :: M8N4RDye = 1363 + INTEGER(IntKi), PARAMETER :: M8N5RDye = 1364 + INTEGER(IntKi), PARAMETER :: M8N6RDye = 1365 + INTEGER(IntKi), PARAMETER :: M8N7RDye = 1366 + INTEGER(IntKi), PARAMETER :: M8N8RDye = 1367 + INTEGER(IntKi), PARAMETER :: M8N9RDye = 1368 + INTEGER(IntKi), PARAMETER :: M9N1RDye = 1369 + INTEGER(IntKi), PARAMETER :: M9N2RDye = 1370 + INTEGER(IntKi), PARAMETER :: M9N3RDye = 1371 + INTEGER(IntKi), PARAMETER :: M9N4RDye = 1372 + INTEGER(IntKi), PARAMETER :: M9N5RDye = 1373 + INTEGER(IntKi), PARAMETER :: M9N6RDye = 1374 + INTEGER(IntKi), PARAMETER :: M9N7RDye = 1375 + INTEGER(IntKi), PARAMETER :: M9N8RDye = 1376 + INTEGER(IntKi), PARAMETER :: M9N9RDye = 1377 + INTEGER(IntKi), PARAMETER :: M1N1RDze = 1378 + INTEGER(IntKi), PARAMETER :: M1N2RDze = 1379 + INTEGER(IntKi), PARAMETER :: M1N3RDze = 1380 + INTEGER(IntKi), PARAMETER :: M1N4RDze = 1381 + INTEGER(IntKi), PARAMETER :: M1N5RDze = 1382 + INTEGER(IntKi), PARAMETER :: M1N6RDze = 1383 + INTEGER(IntKi), PARAMETER :: M1N7RDze = 1384 + INTEGER(IntKi), PARAMETER :: M1N8RDze = 1385 + INTEGER(IntKi), PARAMETER :: M1N9RDze = 1386 + INTEGER(IntKi), PARAMETER :: M2N1RDze = 1387 + INTEGER(IntKi), PARAMETER :: M2N2RDze = 1388 + INTEGER(IntKi), PARAMETER :: M2N3RDze = 1389 + INTEGER(IntKi), PARAMETER :: M2N4RDze = 1390 + INTEGER(IntKi), PARAMETER :: M2N5RDze = 1391 + INTEGER(IntKi), PARAMETER :: M2N6RDze = 1392 + INTEGER(IntKi), PARAMETER :: M2N7RDze = 1393 + INTEGER(IntKi), PARAMETER :: M2N8RDze = 1394 + INTEGER(IntKi), PARAMETER :: M2N9RDze = 1395 + INTEGER(IntKi), PARAMETER :: M3N1RDze = 1396 + INTEGER(IntKi), PARAMETER :: M3N2RDze = 1397 + INTEGER(IntKi), PARAMETER :: M3N3RDze = 1398 + INTEGER(IntKi), PARAMETER :: M3N4RDze = 1399 + INTEGER(IntKi), PARAMETER :: M3N5RDze = 1400 + INTEGER(IntKi), PARAMETER :: M3N6RDze = 1401 + INTEGER(IntKi), PARAMETER :: M3N7RDze = 1402 + INTEGER(IntKi), PARAMETER :: M3N8RDze = 1403 + INTEGER(IntKi), PARAMETER :: M3N9RDze = 1404 + INTEGER(IntKi), PARAMETER :: M4N1RDze = 1405 + INTEGER(IntKi), PARAMETER :: M4N2RDze = 1406 + INTEGER(IntKi), PARAMETER :: M4N3RDze = 1407 + INTEGER(IntKi), PARAMETER :: M4N4RDze = 1408 + INTEGER(IntKi), PARAMETER :: M4N5RDze = 1409 + INTEGER(IntKi), PARAMETER :: M4N6RDze = 1410 + INTEGER(IntKi), PARAMETER :: M4N7RDze = 1411 + INTEGER(IntKi), PARAMETER :: M4N8RDze = 1412 + INTEGER(IntKi), PARAMETER :: M4N9RDze = 1413 + INTEGER(IntKi), PARAMETER :: M5N1RDze = 1414 + INTEGER(IntKi), PARAMETER :: M5N2RDze = 1415 + INTEGER(IntKi), PARAMETER :: M5N3RDze = 1416 + INTEGER(IntKi), PARAMETER :: M5N4RDze = 1417 + INTEGER(IntKi), PARAMETER :: M5N5RDze = 1418 + INTEGER(IntKi), PARAMETER :: M5N6RDze = 1419 + INTEGER(IntKi), PARAMETER :: M5N7RDze = 1420 + INTEGER(IntKi), PARAMETER :: M5N8RDze = 1421 + INTEGER(IntKi), PARAMETER :: M5N9RDze = 1422 + INTEGER(IntKi), PARAMETER :: M6N1RDze = 1423 + INTEGER(IntKi), PARAMETER :: M6N2RDze = 1424 + INTEGER(IntKi), PARAMETER :: M6N3RDze = 1425 + INTEGER(IntKi), PARAMETER :: M6N4RDze = 1426 + INTEGER(IntKi), PARAMETER :: M6N5RDze = 1427 + INTEGER(IntKi), PARAMETER :: M6N6RDze = 1428 + INTEGER(IntKi), PARAMETER :: M6N7RDze = 1429 + INTEGER(IntKi), PARAMETER :: M6N8RDze = 1430 + INTEGER(IntKi), PARAMETER :: M6N9RDze = 1431 + INTEGER(IntKi), PARAMETER :: M7N1RDze = 1432 + INTEGER(IntKi), PARAMETER :: M7N2RDze = 1433 + INTEGER(IntKi), PARAMETER :: M7N3RDze = 1434 + INTEGER(IntKi), PARAMETER :: M7N4RDze = 1435 + INTEGER(IntKi), PARAMETER :: M7N5RDze = 1436 + INTEGER(IntKi), PARAMETER :: M7N6RDze = 1437 + INTEGER(IntKi), PARAMETER :: M7N7RDze = 1438 + INTEGER(IntKi), PARAMETER :: M7N8RDze = 1439 + INTEGER(IntKi), PARAMETER :: M7N9RDze = 1440 + INTEGER(IntKi), PARAMETER :: M8N1RDze = 1441 + INTEGER(IntKi), PARAMETER :: M8N2RDze = 1442 + INTEGER(IntKi), PARAMETER :: M8N3RDze = 1443 + INTEGER(IntKi), PARAMETER :: M8N4RDze = 1444 + INTEGER(IntKi), PARAMETER :: M8N5RDze = 1445 + INTEGER(IntKi), PARAMETER :: M8N6RDze = 1446 + INTEGER(IntKi), PARAMETER :: M8N7RDze = 1447 + INTEGER(IntKi), PARAMETER :: M8N8RDze = 1448 + INTEGER(IntKi), PARAMETER :: M8N9RDze = 1449 + INTEGER(IntKi), PARAMETER :: M9N1RDze = 1450 + INTEGER(IntKi), PARAMETER :: M9N2RDze = 1451 + INTEGER(IntKi), PARAMETER :: M9N3RDze = 1452 + INTEGER(IntKi), PARAMETER :: M9N4RDze = 1453 + INTEGER(IntKi), PARAMETER :: M9N5RDze = 1454 + INTEGER(IntKi), PARAMETER :: M9N6RDze = 1455 + INTEGER(IntKi), PARAMETER :: M9N7RDze = 1456 + INTEGER(IntKi), PARAMETER :: M9N8RDze = 1457 + INTEGER(IntKi), PARAMETER :: M9N9RDze = 1458 + + + ! Accelerations: + + INTEGER(IntKi), PARAMETER :: M1N1TAxe = 1459 + INTEGER(IntKi), PARAMETER :: M1N2TAxe = 1460 + INTEGER(IntKi), PARAMETER :: M1N3TAxe = 1461 + INTEGER(IntKi), PARAMETER :: M1N4TAxe = 1462 + INTEGER(IntKi), PARAMETER :: M1N5TAxe = 1463 + INTEGER(IntKi), PARAMETER :: M1N6TAxe = 1464 + INTEGER(IntKi), PARAMETER :: M1N7TAxe = 1465 + INTEGER(IntKi), PARAMETER :: M1N8TAxe = 1466 + INTEGER(IntKi), PARAMETER :: M1N9TAxe = 1467 + INTEGER(IntKi), PARAMETER :: M2N1TAxe = 1468 + INTEGER(IntKi), PARAMETER :: M2N2TAxe = 1469 + INTEGER(IntKi), PARAMETER :: M2N3TAxe = 1470 + INTEGER(IntKi), PARAMETER :: M2N4TAxe = 1471 + INTEGER(IntKi), PARAMETER :: M2N5TAxe = 1472 + INTEGER(IntKi), PARAMETER :: M2N6TAxe = 1473 + INTEGER(IntKi), PARAMETER :: M2N7TAxe = 1474 + INTEGER(IntKi), PARAMETER :: M2N8TAxe = 1475 + INTEGER(IntKi), PARAMETER :: M2N9TAxe = 1476 + INTEGER(IntKi), PARAMETER :: M3N1TAxe = 1477 + INTEGER(IntKi), PARAMETER :: M3N2TAxe = 1478 + INTEGER(IntKi), PARAMETER :: M3N3TAxe = 1479 + INTEGER(IntKi), PARAMETER :: M3N4TAxe = 1480 + INTEGER(IntKi), PARAMETER :: M3N5TAxe = 1481 + INTEGER(IntKi), PARAMETER :: M3N6TAxe = 1482 + INTEGER(IntKi), PARAMETER :: M3N7TAxe = 1483 + INTEGER(IntKi), PARAMETER :: M3N8TAxe = 1484 + INTEGER(IntKi), PARAMETER :: M3N9TAxe = 1485 + INTEGER(IntKi), PARAMETER :: M4N1TAxe = 1486 + INTEGER(IntKi), PARAMETER :: M4N2TAxe = 1487 + INTEGER(IntKi), PARAMETER :: M4N3TAxe = 1488 + INTEGER(IntKi), PARAMETER :: M4N4TAxe = 1489 + INTEGER(IntKi), PARAMETER :: M4N5TAxe = 1490 + INTEGER(IntKi), PARAMETER :: M4N6TAxe = 1491 + INTEGER(IntKi), PARAMETER :: M4N7TAxe = 1492 + INTEGER(IntKi), PARAMETER :: M4N8TAxe = 1493 + INTEGER(IntKi), PARAMETER :: M4N9TAxe = 1494 + INTEGER(IntKi), PARAMETER :: M5N1TAxe = 1495 + INTEGER(IntKi), PARAMETER :: M5N2TAxe = 1496 + INTEGER(IntKi), PARAMETER :: M5N3TAxe = 1497 + INTEGER(IntKi), PARAMETER :: M5N4TAxe = 1498 + INTEGER(IntKi), PARAMETER :: M5N5TAxe = 1499 + INTEGER(IntKi), PARAMETER :: M5N6TAxe = 1500 + INTEGER(IntKi), PARAMETER :: M5N7TAxe = 1501 + INTEGER(IntKi), PARAMETER :: M5N8TAxe = 1502 + INTEGER(IntKi), PARAMETER :: M5N9TAxe = 1503 + INTEGER(IntKi), PARAMETER :: M6N1TAxe = 1504 + INTEGER(IntKi), PARAMETER :: M6N2TAxe = 1505 + INTEGER(IntKi), PARAMETER :: M6N3TAxe = 1506 + INTEGER(IntKi), PARAMETER :: M6N4TAxe = 1507 + INTEGER(IntKi), PARAMETER :: M6N5TAxe = 1508 + INTEGER(IntKi), PARAMETER :: M6N6TAxe = 1509 + INTEGER(IntKi), PARAMETER :: M6N7TAxe = 1510 + INTEGER(IntKi), PARAMETER :: M6N8TAxe = 1511 + INTEGER(IntKi), PARAMETER :: M6N9TAxe = 1512 + INTEGER(IntKi), PARAMETER :: M7N1TAxe = 1513 + INTEGER(IntKi), PARAMETER :: M7N2TAxe = 1514 + INTEGER(IntKi), PARAMETER :: M7N3TAxe = 1515 + INTEGER(IntKi), PARAMETER :: M7N4TAxe = 1516 + INTEGER(IntKi), PARAMETER :: M7N5TAxe = 1517 + INTEGER(IntKi), PARAMETER :: M7N6TAxe = 1518 + INTEGER(IntKi), PARAMETER :: M7N7TAxe = 1519 + INTEGER(IntKi), PARAMETER :: M7N8TAxe = 1520 + INTEGER(IntKi), PARAMETER :: M7N9TAxe = 1521 + INTEGER(IntKi), PARAMETER :: M8N1TAxe = 1522 + INTEGER(IntKi), PARAMETER :: M8N2TAxe = 1523 + INTEGER(IntKi), PARAMETER :: M8N3TAxe = 1524 + INTEGER(IntKi), PARAMETER :: M8N4TAxe = 1525 + INTEGER(IntKi), PARAMETER :: M8N5TAxe = 1526 + INTEGER(IntKi), PARAMETER :: M8N6TAxe = 1527 + INTEGER(IntKi), PARAMETER :: M8N7TAxe = 1528 + INTEGER(IntKi), PARAMETER :: M8N8TAxe = 1529 + INTEGER(IntKi), PARAMETER :: M8N9TAxe = 1530 + INTEGER(IntKi), PARAMETER :: M9N1TAxe = 1531 + INTEGER(IntKi), PARAMETER :: M9N2TAxe = 1532 + INTEGER(IntKi), PARAMETER :: M9N3TAxe = 1533 + INTEGER(IntKi), PARAMETER :: M9N4TAxe = 1534 + INTEGER(IntKi), PARAMETER :: M9N5TAxe = 1535 + INTEGER(IntKi), PARAMETER :: M9N6TAxe = 1536 + INTEGER(IntKi), PARAMETER :: M9N7TAxe = 1537 + INTEGER(IntKi), PARAMETER :: M9N8TAxe = 1538 + INTEGER(IntKi), PARAMETER :: M9N9TAxe = 1539 + INTEGER(IntKi), PARAMETER :: M1N1TAye = 1540 + INTEGER(IntKi), PARAMETER :: M1N2TAye = 1541 + INTEGER(IntKi), PARAMETER :: M1N3TAye = 1542 + INTEGER(IntKi), PARAMETER :: M1N4TAye = 1543 + INTEGER(IntKi), PARAMETER :: M1N5TAye = 1544 + INTEGER(IntKi), PARAMETER :: M1N6TAye = 1545 + INTEGER(IntKi), PARAMETER :: M1N7TAye = 1546 + INTEGER(IntKi), PARAMETER :: M1N8TAye = 1547 + INTEGER(IntKi), PARAMETER :: M1N9TAye = 1548 + INTEGER(IntKi), PARAMETER :: M2N1TAye = 1549 + INTEGER(IntKi), PARAMETER :: M2N2TAye = 1550 + INTEGER(IntKi), PARAMETER :: M2N3TAye = 1551 + INTEGER(IntKi), PARAMETER :: M2N4TAye = 1552 + INTEGER(IntKi), PARAMETER :: M2N5TAye = 1553 + INTEGER(IntKi), PARAMETER :: M2N6TAye = 1554 + INTEGER(IntKi), PARAMETER :: M2N7TAye = 1555 + INTEGER(IntKi), PARAMETER :: M2N8TAye = 1556 + INTEGER(IntKi), PARAMETER :: M2N9TAye = 1557 + INTEGER(IntKi), PARAMETER :: M3N1TAye = 1558 + INTEGER(IntKi), PARAMETER :: M3N2TAye = 1559 + INTEGER(IntKi), PARAMETER :: M3N3TAye = 1560 + INTEGER(IntKi), PARAMETER :: M3N4TAye = 1561 + INTEGER(IntKi), PARAMETER :: M3N5TAye = 1562 + INTEGER(IntKi), PARAMETER :: M3N6TAye = 1563 + INTEGER(IntKi), PARAMETER :: M3N7TAye = 1564 + INTEGER(IntKi), PARAMETER :: M3N8TAye = 1565 + INTEGER(IntKi), PARAMETER :: M3N9TAye = 1566 + INTEGER(IntKi), PARAMETER :: M4N1TAye = 1567 + INTEGER(IntKi), PARAMETER :: M4N2TAye = 1568 + INTEGER(IntKi), PARAMETER :: M4N3TAye = 1569 + INTEGER(IntKi), PARAMETER :: M4N4TAye = 1570 + INTEGER(IntKi), PARAMETER :: M4N5TAye = 1571 + INTEGER(IntKi), PARAMETER :: M4N6TAye = 1572 + INTEGER(IntKi), PARAMETER :: M4N7TAye = 1573 + INTEGER(IntKi), PARAMETER :: M4N8TAye = 1574 + INTEGER(IntKi), PARAMETER :: M4N9TAye = 1575 + INTEGER(IntKi), PARAMETER :: M5N1TAye = 1576 + INTEGER(IntKi), PARAMETER :: M5N2TAye = 1577 + INTEGER(IntKi), PARAMETER :: M5N3TAye = 1578 + INTEGER(IntKi), PARAMETER :: M5N4TAye = 1579 + INTEGER(IntKi), PARAMETER :: M5N5TAye = 1580 + INTEGER(IntKi), PARAMETER :: M5N6TAye = 1581 + INTEGER(IntKi), PARAMETER :: M5N7TAye = 1582 + INTEGER(IntKi), PARAMETER :: M5N8TAye = 1583 + INTEGER(IntKi), PARAMETER :: M5N9TAye = 1584 + INTEGER(IntKi), PARAMETER :: M6N1TAye = 1585 + INTEGER(IntKi), PARAMETER :: M6N2TAye = 1586 + INTEGER(IntKi), PARAMETER :: M6N3TAye = 1587 + INTEGER(IntKi), PARAMETER :: M6N4TAye = 1588 + INTEGER(IntKi), PARAMETER :: M6N5TAye = 1589 + INTEGER(IntKi), PARAMETER :: M6N6TAye = 1590 + INTEGER(IntKi), PARAMETER :: M6N7TAye = 1591 + INTEGER(IntKi), PARAMETER :: M6N8TAye = 1592 + INTEGER(IntKi), PARAMETER :: M6N9TAye = 1593 + INTEGER(IntKi), PARAMETER :: M7N1TAye = 1594 + INTEGER(IntKi), PARAMETER :: M7N2TAye = 1595 + INTEGER(IntKi), PARAMETER :: M7N3TAye = 1596 + INTEGER(IntKi), PARAMETER :: M7N4TAye = 1597 + INTEGER(IntKi), PARAMETER :: M7N5TAye = 1598 + INTEGER(IntKi), PARAMETER :: M7N6TAye = 1599 + INTEGER(IntKi), PARAMETER :: M7N7TAye = 1600 + INTEGER(IntKi), PARAMETER :: M7N8TAye = 1601 + INTEGER(IntKi), PARAMETER :: M7N9TAye = 1602 + INTEGER(IntKi), PARAMETER :: M8N1TAye = 1603 + INTEGER(IntKi), PARAMETER :: M8N2TAye = 1604 + INTEGER(IntKi), PARAMETER :: M8N3TAye = 1605 + INTEGER(IntKi), PARAMETER :: M8N4TAye = 1606 + INTEGER(IntKi), PARAMETER :: M8N5TAye = 1607 + INTEGER(IntKi), PARAMETER :: M8N6TAye = 1608 + INTEGER(IntKi), PARAMETER :: M8N7TAye = 1609 + INTEGER(IntKi), PARAMETER :: M8N8TAye = 1610 + INTEGER(IntKi), PARAMETER :: M8N9TAye = 1611 + INTEGER(IntKi), PARAMETER :: M9N1TAye = 1612 + INTEGER(IntKi), PARAMETER :: M9N2TAye = 1613 + INTEGER(IntKi), PARAMETER :: M9N3TAye = 1614 + INTEGER(IntKi), PARAMETER :: M9N4TAye = 1615 + INTEGER(IntKi), PARAMETER :: M9N5TAye = 1616 + INTEGER(IntKi), PARAMETER :: M9N6TAye = 1617 + INTEGER(IntKi), PARAMETER :: M9N7TAye = 1618 + INTEGER(IntKi), PARAMETER :: M9N8TAye = 1619 + INTEGER(IntKi), PARAMETER :: M9N9TAye = 1620 + INTEGER(IntKi), PARAMETER :: M1N1TAze = 1621 + INTEGER(IntKi), PARAMETER :: M1N2TAze = 1622 + INTEGER(IntKi), PARAMETER :: M1N3TAze = 1623 + INTEGER(IntKi), PARAMETER :: M1N4TAze = 1624 + INTEGER(IntKi), PARAMETER :: M1N5TAze = 1625 + INTEGER(IntKi), PARAMETER :: M1N6TAze = 1626 + INTEGER(IntKi), PARAMETER :: M1N7TAze = 1627 + INTEGER(IntKi), PARAMETER :: M1N8TAze = 1628 + INTEGER(IntKi), PARAMETER :: M1N9TAze = 1629 + INTEGER(IntKi), PARAMETER :: M2N1TAze = 1630 + INTEGER(IntKi), PARAMETER :: M2N2TAze = 1631 + INTEGER(IntKi), PARAMETER :: M2N3TAze = 1632 + INTEGER(IntKi), PARAMETER :: M2N4TAze = 1633 + INTEGER(IntKi), PARAMETER :: M2N5TAze = 1634 + INTEGER(IntKi), PARAMETER :: M2N6TAze = 1635 + INTEGER(IntKi), PARAMETER :: M2N7TAze = 1636 + INTEGER(IntKi), PARAMETER :: M2N8TAze = 1637 + INTEGER(IntKi), PARAMETER :: M2N9TAze = 1638 + INTEGER(IntKi), PARAMETER :: M3N1TAze = 1639 + INTEGER(IntKi), PARAMETER :: M3N2TAze = 1640 + INTEGER(IntKi), PARAMETER :: M3N3TAze = 1641 + INTEGER(IntKi), PARAMETER :: M3N4TAze = 1642 + INTEGER(IntKi), PARAMETER :: M3N5TAze = 1643 + INTEGER(IntKi), PARAMETER :: M3N6TAze = 1644 + INTEGER(IntKi), PARAMETER :: M3N7TAze = 1645 + INTEGER(IntKi), PARAMETER :: M3N8TAze = 1646 + INTEGER(IntKi), PARAMETER :: M3N9TAze = 1647 + INTEGER(IntKi), PARAMETER :: M4N1TAze = 1648 + INTEGER(IntKi), PARAMETER :: M4N2TAze = 1649 + INTEGER(IntKi), PARAMETER :: M4N3TAze = 1650 + INTEGER(IntKi), PARAMETER :: M4N4TAze = 1651 + INTEGER(IntKi), PARAMETER :: M4N5TAze = 1652 + INTEGER(IntKi), PARAMETER :: M4N6TAze = 1653 + INTEGER(IntKi), PARAMETER :: M4N7TAze = 1654 + INTEGER(IntKi), PARAMETER :: M4N8TAze = 1655 + INTEGER(IntKi), PARAMETER :: M4N9TAze = 1656 + INTEGER(IntKi), PARAMETER :: M5N1TAze = 1657 + INTEGER(IntKi), PARAMETER :: M5N2TAze = 1658 + INTEGER(IntKi), PARAMETER :: M5N3TAze = 1659 + INTEGER(IntKi), PARAMETER :: M5N4TAze = 1660 + INTEGER(IntKi), PARAMETER :: M5N5TAze = 1661 + INTEGER(IntKi), PARAMETER :: M5N6TAze = 1662 + INTEGER(IntKi), PARAMETER :: M5N7TAze = 1663 + INTEGER(IntKi), PARAMETER :: M5N8TAze = 1664 + INTEGER(IntKi), PARAMETER :: M5N9TAze = 1665 + INTEGER(IntKi), PARAMETER :: M6N1TAze = 1666 + INTEGER(IntKi), PARAMETER :: M6N2TAze = 1667 + INTEGER(IntKi), PARAMETER :: M6N3TAze = 1668 + INTEGER(IntKi), PARAMETER :: M6N4TAze = 1669 + INTEGER(IntKi), PARAMETER :: M6N5TAze = 1670 + INTEGER(IntKi), PARAMETER :: M6N6TAze = 1671 + INTEGER(IntKi), PARAMETER :: M6N7TAze = 1672 + INTEGER(IntKi), PARAMETER :: M6N8TAze = 1673 + INTEGER(IntKi), PARAMETER :: M6N9TAze = 1674 + INTEGER(IntKi), PARAMETER :: M7N1TAze = 1675 + INTEGER(IntKi), PARAMETER :: M7N2TAze = 1676 + INTEGER(IntKi), PARAMETER :: M7N3TAze = 1677 + INTEGER(IntKi), PARAMETER :: M7N4TAze = 1678 + INTEGER(IntKi), PARAMETER :: M7N5TAze = 1679 + INTEGER(IntKi), PARAMETER :: M7N6TAze = 1680 + INTEGER(IntKi), PARAMETER :: M7N7TAze = 1681 + INTEGER(IntKi), PARAMETER :: M7N8TAze = 1682 + INTEGER(IntKi), PARAMETER :: M7N9TAze = 1683 + INTEGER(IntKi), PARAMETER :: M8N1TAze = 1684 + INTEGER(IntKi), PARAMETER :: M8N2TAze = 1685 + INTEGER(IntKi), PARAMETER :: M8N3TAze = 1686 + INTEGER(IntKi), PARAMETER :: M8N4TAze = 1687 + INTEGER(IntKi), PARAMETER :: M8N5TAze = 1688 + INTEGER(IntKi), PARAMETER :: M8N6TAze = 1689 + INTEGER(IntKi), PARAMETER :: M8N7TAze = 1690 + INTEGER(IntKi), PARAMETER :: M8N8TAze = 1691 + INTEGER(IntKi), PARAMETER :: M8N9TAze = 1692 + INTEGER(IntKi), PARAMETER :: M9N1TAze = 1693 + INTEGER(IntKi), PARAMETER :: M9N2TAze = 1694 + INTEGER(IntKi), PARAMETER :: M9N3TAze = 1695 + INTEGER(IntKi), PARAMETER :: M9N4TAze = 1696 + INTEGER(IntKi), PARAMETER :: M9N5TAze = 1697 + INTEGER(IntKi), PARAMETER :: M9N6TAze = 1698 + INTEGER(IntKi), PARAMETER :: M9N7TAze = 1699 + INTEGER(IntKi), PARAMETER :: M9N8TAze = 1700 + INTEGER(IntKi), PARAMETER :: M9N9TAze = 1701 + INTEGER(IntKi), PARAMETER :: M1N1RAxe = 1702 + INTEGER(IntKi), PARAMETER :: M1N2RAxe = 1703 + INTEGER(IntKi), PARAMETER :: M1N3RAxe = 1704 + INTEGER(IntKi), PARAMETER :: M1N4RAxe = 1705 + INTEGER(IntKi), PARAMETER :: M1N5RAxe = 1706 + INTEGER(IntKi), PARAMETER :: M1N6RAxe = 1707 + INTEGER(IntKi), PARAMETER :: M1N7RAxe = 1708 + INTEGER(IntKi), PARAMETER :: M1N8RAxe = 1709 + INTEGER(IntKi), PARAMETER :: M1N9RAxe = 1710 + INTEGER(IntKi), PARAMETER :: M2N1RAxe = 1711 + INTEGER(IntKi), PARAMETER :: M2N2RAxe = 1712 + INTEGER(IntKi), PARAMETER :: M2N3RAxe = 1713 + INTEGER(IntKi), PARAMETER :: M2N4RAxe = 1714 + INTEGER(IntKi), PARAMETER :: M2N5RAxe = 1715 + INTEGER(IntKi), PARAMETER :: M2N6RAxe = 1716 + INTEGER(IntKi), PARAMETER :: M2N7RAxe = 1717 + INTEGER(IntKi), PARAMETER :: M2N8RAxe = 1718 + INTEGER(IntKi), PARAMETER :: M2N9RAxe = 1719 + INTEGER(IntKi), PARAMETER :: M3N1RAxe = 1720 + INTEGER(IntKi), PARAMETER :: M3N2RAxe = 1721 + INTEGER(IntKi), PARAMETER :: M3N3RAxe = 1722 + INTEGER(IntKi), PARAMETER :: M3N4RAxe = 1723 + INTEGER(IntKi), PARAMETER :: M3N5RAxe = 1724 + INTEGER(IntKi), PARAMETER :: M3N6RAxe = 1725 + INTEGER(IntKi), PARAMETER :: M3N7RAxe = 1726 + INTEGER(IntKi), PARAMETER :: M3N8RAxe = 1727 + INTEGER(IntKi), PARAMETER :: M3N9RAxe = 1728 + INTEGER(IntKi), PARAMETER :: M4N1RAxe = 1729 + INTEGER(IntKi), PARAMETER :: M4N2RAxe = 1730 + INTEGER(IntKi), PARAMETER :: M4N3RAxe = 1731 + INTEGER(IntKi), PARAMETER :: M4N4RAxe = 1732 + INTEGER(IntKi), PARAMETER :: M4N5RAxe = 1733 + INTEGER(IntKi), PARAMETER :: M4N6RAxe = 1734 + INTEGER(IntKi), PARAMETER :: M4N7RAxe = 1735 + INTEGER(IntKi), PARAMETER :: M4N8RAxe = 1736 + INTEGER(IntKi), PARAMETER :: M4N9RAxe = 1737 + INTEGER(IntKi), PARAMETER :: M5N1RAxe = 1738 + INTEGER(IntKi), PARAMETER :: M5N2RAxe = 1739 + INTEGER(IntKi), PARAMETER :: M5N3RAxe = 1740 + INTEGER(IntKi), PARAMETER :: M5N4RAxe = 1741 + INTEGER(IntKi), PARAMETER :: M5N5RAxe = 1742 + INTEGER(IntKi), PARAMETER :: M5N6RAxe = 1743 + INTEGER(IntKi), PARAMETER :: M5N7RAxe = 1744 + INTEGER(IntKi), PARAMETER :: M5N8RAxe = 1745 + INTEGER(IntKi), PARAMETER :: M5N9RAxe = 1746 + INTEGER(IntKi), PARAMETER :: M6N1RAxe = 1747 + INTEGER(IntKi), PARAMETER :: M6N2RAxe = 1748 + INTEGER(IntKi), PARAMETER :: M6N3RAxe = 1749 + INTEGER(IntKi), PARAMETER :: M6N4RAxe = 1750 + INTEGER(IntKi), PARAMETER :: M6N5RAxe = 1751 + INTEGER(IntKi), PARAMETER :: M6N6RAxe = 1752 + INTEGER(IntKi), PARAMETER :: M6N7RAxe = 1753 + INTEGER(IntKi), PARAMETER :: M6N8RAxe = 1754 + INTEGER(IntKi), PARAMETER :: M6N9RAxe = 1755 + INTEGER(IntKi), PARAMETER :: M7N1RAxe = 1756 + INTEGER(IntKi), PARAMETER :: M7N2RAxe = 1757 + INTEGER(IntKi), PARAMETER :: M7N3RAxe = 1758 + INTEGER(IntKi), PARAMETER :: M7N4RAxe = 1759 + INTEGER(IntKi), PARAMETER :: M7N5RAxe = 1760 + INTEGER(IntKi), PARAMETER :: M7N6RAxe = 1761 + INTEGER(IntKi), PARAMETER :: M7N7RAxe = 1762 + INTEGER(IntKi), PARAMETER :: M7N8RAxe = 1763 + INTEGER(IntKi), PARAMETER :: M7N9RAxe = 1764 + INTEGER(IntKi), PARAMETER :: M8N1RAxe = 1765 + INTEGER(IntKi), PARAMETER :: M8N2RAxe = 1766 + INTEGER(IntKi), PARAMETER :: M8N3RAxe = 1767 + INTEGER(IntKi), PARAMETER :: M8N4RAxe = 1768 + INTEGER(IntKi), PARAMETER :: M8N5RAxe = 1769 + INTEGER(IntKi), PARAMETER :: M8N6RAxe = 1770 + INTEGER(IntKi), PARAMETER :: M8N7RAxe = 1771 + INTEGER(IntKi), PARAMETER :: M8N8RAxe = 1772 + INTEGER(IntKi), PARAMETER :: M8N9RAxe = 1773 + INTEGER(IntKi), PARAMETER :: M9N1RAxe = 1774 + INTEGER(IntKi), PARAMETER :: M9N2RAxe = 1775 + INTEGER(IntKi), PARAMETER :: M9N3RAxe = 1776 + INTEGER(IntKi), PARAMETER :: M9N4RAxe = 1777 + INTEGER(IntKi), PARAMETER :: M9N5RAxe = 1778 + INTEGER(IntKi), PARAMETER :: M9N6RAxe = 1779 + INTEGER(IntKi), PARAMETER :: M9N7RAxe = 1780 + INTEGER(IntKi), PARAMETER :: M9N8RAxe = 1781 + INTEGER(IntKi), PARAMETER :: M9N9RAxe = 1782 + INTEGER(IntKi), PARAMETER :: M1N1RAye = 1783 + INTEGER(IntKi), PARAMETER :: M1N2RAye = 1784 + INTEGER(IntKi), PARAMETER :: M1N3RAye = 1785 + INTEGER(IntKi), PARAMETER :: M1N4RAye = 1786 + INTEGER(IntKi), PARAMETER :: M1N5RAye = 1787 + INTEGER(IntKi), PARAMETER :: M1N6RAye = 1788 + INTEGER(IntKi), PARAMETER :: M1N7RAye = 1789 + INTEGER(IntKi), PARAMETER :: M1N8RAye = 1790 + INTEGER(IntKi), PARAMETER :: M1N9RAye = 1791 + INTEGER(IntKi), PARAMETER :: M2N1RAye = 1792 + INTEGER(IntKi), PARAMETER :: M2N2RAye = 1793 + INTEGER(IntKi), PARAMETER :: M2N3RAye = 1794 + INTEGER(IntKi), PARAMETER :: M2N4RAye = 1795 + INTEGER(IntKi), PARAMETER :: M2N5RAye = 1796 + INTEGER(IntKi), PARAMETER :: M2N6RAye = 1797 + INTEGER(IntKi), PARAMETER :: M2N7RAye = 1798 + INTEGER(IntKi), PARAMETER :: M2N8RAye = 1799 + INTEGER(IntKi), PARAMETER :: M2N9RAye = 1800 + INTEGER(IntKi), PARAMETER :: M3N1RAye = 1801 + INTEGER(IntKi), PARAMETER :: M3N2RAye = 1802 + INTEGER(IntKi), PARAMETER :: M3N3RAye = 1803 + INTEGER(IntKi), PARAMETER :: M3N4RAye = 1804 + INTEGER(IntKi), PARAMETER :: M3N5RAye = 1805 + INTEGER(IntKi), PARAMETER :: M3N6RAye = 1806 + INTEGER(IntKi), PARAMETER :: M3N7RAye = 1807 + INTEGER(IntKi), PARAMETER :: M3N8RAye = 1808 + INTEGER(IntKi), PARAMETER :: M3N9RAye = 1809 + INTEGER(IntKi), PARAMETER :: M4N1RAye = 1810 + INTEGER(IntKi), PARAMETER :: M4N2RAye = 1811 + INTEGER(IntKi), PARAMETER :: M4N3RAye = 1812 + INTEGER(IntKi), PARAMETER :: M4N4RAye = 1813 + INTEGER(IntKi), PARAMETER :: M4N5RAye = 1814 + INTEGER(IntKi), PARAMETER :: M4N6RAye = 1815 + INTEGER(IntKi), PARAMETER :: M4N7RAye = 1816 + INTEGER(IntKi), PARAMETER :: M4N8RAye = 1817 + INTEGER(IntKi), PARAMETER :: M4N9RAye = 1818 + INTEGER(IntKi), PARAMETER :: M5N1RAye = 1819 + INTEGER(IntKi), PARAMETER :: M5N2RAye = 1820 + INTEGER(IntKi), PARAMETER :: M5N3RAye = 1821 + INTEGER(IntKi), PARAMETER :: M5N4RAye = 1822 + INTEGER(IntKi), PARAMETER :: M5N5RAye = 1823 + INTEGER(IntKi), PARAMETER :: M5N6RAye = 1824 + INTEGER(IntKi), PARAMETER :: M5N7RAye = 1825 + INTEGER(IntKi), PARAMETER :: M5N8RAye = 1826 + INTEGER(IntKi), PARAMETER :: M5N9RAye = 1827 + INTEGER(IntKi), PARAMETER :: M6N1RAye = 1828 + INTEGER(IntKi), PARAMETER :: M6N2RAye = 1829 + INTEGER(IntKi), PARAMETER :: M6N3RAye = 1830 + INTEGER(IntKi), PARAMETER :: M6N4RAye = 1831 + INTEGER(IntKi), PARAMETER :: M6N5RAye = 1832 + INTEGER(IntKi), PARAMETER :: M6N6RAye = 1833 + INTEGER(IntKi), PARAMETER :: M6N7RAye = 1834 + INTEGER(IntKi), PARAMETER :: M6N8RAye = 1835 + INTEGER(IntKi), PARAMETER :: M6N9RAye = 1836 + INTEGER(IntKi), PARAMETER :: M7N1RAye = 1837 + INTEGER(IntKi), PARAMETER :: M7N2RAye = 1838 + INTEGER(IntKi), PARAMETER :: M7N3RAye = 1839 + INTEGER(IntKi), PARAMETER :: M7N4RAye = 1840 + INTEGER(IntKi), PARAMETER :: M7N5RAye = 1841 + INTEGER(IntKi), PARAMETER :: M7N6RAye = 1842 + INTEGER(IntKi), PARAMETER :: M7N7RAye = 1843 + INTEGER(IntKi), PARAMETER :: M7N8RAye = 1844 + INTEGER(IntKi), PARAMETER :: M7N9RAye = 1845 + INTEGER(IntKi), PARAMETER :: M8N1RAye = 1846 + INTEGER(IntKi), PARAMETER :: M8N2RAye = 1847 + INTEGER(IntKi), PARAMETER :: M8N3RAye = 1848 + INTEGER(IntKi), PARAMETER :: M8N4RAye = 1849 + INTEGER(IntKi), PARAMETER :: M8N5RAye = 1850 + INTEGER(IntKi), PARAMETER :: M8N6RAye = 1851 + INTEGER(IntKi), PARAMETER :: M8N7RAye = 1852 + INTEGER(IntKi), PARAMETER :: M8N8RAye = 1853 + INTEGER(IntKi), PARAMETER :: M8N9RAye = 1854 + INTEGER(IntKi), PARAMETER :: M9N1RAye = 1855 + INTEGER(IntKi), PARAMETER :: M9N2RAye = 1856 + INTEGER(IntKi), PARAMETER :: M9N3RAye = 1857 + INTEGER(IntKi), PARAMETER :: M9N4RAye = 1858 + INTEGER(IntKi), PARAMETER :: M9N5RAye = 1859 + INTEGER(IntKi), PARAMETER :: M9N6RAye = 1860 + INTEGER(IntKi), PARAMETER :: M9N7RAye = 1861 + INTEGER(IntKi), PARAMETER :: M9N8RAye = 1862 + INTEGER(IntKi), PARAMETER :: M9N9RAye = 1863 + INTEGER(IntKi), PARAMETER :: M1N1RAze = 1864 + INTEGER(IntKi), PARAMETER :: M1N2RAze = 1865 + INTEGER(IntKi), PARAMETER :: M1N3RAze = 1866 + INTEGER(IntKi), PARAMETER :: M1N4RAze = 1867 + INTEGER(IntKi), PARAMETER :: M1N5RAze = 1868 + INTEGER(IntKi), PARAMETER :: M1N6RAze = 1869 + INTEGER(IntKi), PARAMETER :: M1N7RAze = 1870 + INTEGER(IntKi), PARAMETER :: M1N8RAze = 1871 + INTEGER(IntKi), PARAMETER :: M1N9RAze = 1872 + INTEGER(IntKi), PARAMETER :: M2N1RAze = 1873 + INTEGER(IntKi), PARAMETER :: M2N2RAze = 1874 + INTEGER(IntKi), PARAMETER :: M2N3RAze = 1875 + INTEGER(IntKi), PARAMETER :: M2N4RAze = 1876 + INTEGER(IntKi), PARAMETER :: M2N5RAze = 1877 + INTEGER(IntKi), PARAMETER :: M2N6RAze = 1878 + INTEGER(IntKi), PARAMETER :: M2N7RAze = 1879 + INTEGER(IntKi), PARAMETER :: M2N8RAze = 1880 + INTEGER(IntKi), PARAMETER :: M2N9RAze = 1881 + INTEGER(IntKi), PARAMETER :: M3N1RAze = 1882 + INTEGER(IntKi), PARAMETER :: M3N2RAze = 1883 + INTEGER(IntKi), PARAMETER :: M3N3RAze = 1884 + INTEGER(IntKi), PARAMETER :: M3N4RAze = 1885 + INTEGER(IntKi), PARAMETER :: M3N5RAze = 1886 + INTEGER(IntKi), PARAMETER :: M3N6RAze = 1887 + INTEGER(IntKi), PARAMETER :: M3N7RAze = 1888 + INTEGER(IntKi), PARAMETER :: M3N8RAze = 1889 + INTEGER(IntKi), PARAMETER :: M3N9RAze = 1890 + INTEGER(IntKi), PARAMETER :: M4N1RAze = 1891 + INTEGER(IntKi), PARAMETER :: M4N2RAze = 1892 + INTEGER(IntKi), PARAMETER :: M4N3RAze = 1893 + INTEGER(IntKi), PARAMETER :: M4N4RAze = 1894 + INTEGER(IntKi), PARAMETER :: M4N5RAze = 1895 + INTEGER(IntKi), PARAMETER :: M4N6RAze = 1896 + INTEGER(IntKi), PARAMETER :: M4N7RAze = 1897 + INTEGER(IntKi), PARAMETER :: M4N8RAze = 1898 + INTEGER(IntKi), PARAMETER :: M4N9RAze = 1899 + INTEGER(IntKi), PARAMETER :: M5N1RAze = 1900 + INTEGER(IntKi), PARAMETER :: M5N2RAze = 1901 + INTEGER(IntKi), PARAMETER :: M5N3RAze = 1902 + INTEGER(IntKi), PARAMETER :: M5N4RAze = 1903 + INTEGER(IntKi), PARAMETER :: M5N5RAze = 1904 + INTEGER(IntKi), PARAMETER :: M5N6RAze = 1905 + INTEGER(IntKi), PARAMETER :: M5N7RAze = 1906 + INTEGER(IntKi), PARAMETER :: M5N8RAze = 1907 + INTEGER(IntKi), PARAMETER :: M5N9RAze = 1908 + INTEGER(IntKi), PARAMETER :: M6N1RAze = 1909 + INTEGER(IntKi), PARAMETER :: M6N2RAze = 1910 + INTEGER(IntKi), PARAMETER :: M6N3RAze = 1911 + INTEGER(IntKi), PARAMETER :: M6N4RAze = 1912 + INTEGER(IntKi), PARAMETER :: M6N5RAze = 1913 + INTEGER(IntKi), PARAMETER :: M6N6RAze = 1914 + INTEGER(IntKi), PARAMETER :: M6N7RAze = 1915 + INTEGER(IntKi), PARAMETER :: M6N8RAze = 1916 + INTEGER(IntKi), PARAMETER :: M6N9RAze = 1917 + INTEGER(IntKi), PARAMETER :: M7N1RAze = 1918 + INTEGER(IntKi), PARAMETER :: M7N2RAze = 1919 + INTEGER(IntKi), PARAMETER :: M7N3RAze = 1920 + INTEGER(IntKi), PARAMETER :: M7N4RAze = 1921 + INTEGER(IntKi), PARAMETER :: M7N5RAze = 1922 + INTEGER(IntKi), PARAMETER :: M7N6RAze = 1923 + INTEGER(IntKi), PARAMETER :: M7N7RAze = 1924 + INTEGER(IntKi), PARAMETER :: M7N8RAze = 1925 + INTEGER(IntKi), PARAMETER :: M7N9RAze = 1926 + INTEGER(IntKi), PARAMETER :: M8N1RAze = 1927 + INTEGER(IntKi), PARAMETER :: M8N2RAze = 1928 + INTEGER(IntKi), PARAMETER :: M8N3RAze = 1929 + INTEGER(IntKi), PARAMETER :: M8N4RAze = 1930 + INTEGER(IntKi), PARAMETER :: M8N5RAze = 1931 + INTEGER(IntKi), PARAMETER :: M8N6RAze = 1932 + INTEGER(IntKi), PARAMETER :: M8N7RAze = 1933 + INTEGER(IntKi), PARAMETER :: M8N8RAze = 1934 + INTEGER(IntKi), PARAMETER :: M8N9RAze = 1935 + INTEGER(IntKi), PARAMETER :: M9N1RAze = 1936 + INTEGER(IntKi), PARAMETER :: M9N2RAze = 1937 + INTEGER(IntKi), PARAMETER :: M9N3RAze = 1938 + INTEGER(IntKi), PARAMETER :: M9N4RAze = 1939 + INTEGER(IntKi), PARAMETER :: M9N5RAze = 1940 + INTEGER(IntKi), PARAMETER :: M9N6RAze = 1941 + INTEGER(IntKi), PARAMETER :: M9N7RAze = 1942 + INTEGER(IntKi), PARAMETER :: M9N8RAze = 1943 + INTEGER(IntKi), PARAMETER :: M9N9RAze = 1944 + + + ! Reactions: + + INTEGER(IntKi), PARAMETER :: ReactFXss = 1945 + INTEGER(IntKi), PARAMETER :: ReactFYss = 1946 + INTEGER(IntKi), PARAMETER :: ReactFZss = 1947 + INTEGER(IntKi), PARAMETER :: ReactMXss = 1948 + INTEGER(IntKi), PARAMETER :: ReactMYss = 1949 + INTEGER(IntKi), PARAMETER :: ReactMZss = 1950 + INTEGER(IntKi), PARAMETER :: IntfFXss = 1951 + INTEGER(IntKi), PARAMETER :: IntfFYss = 1952 + INTEGER(IntKi), PARAMETER :: IntfFZss = 1953 + INTEGER(IntKi), PARAMETER :: IntfMXss = 1954 + INTEGER(IntKi), PARAMETER :: IntfMYss = 1955 + INTEGER(IntKi), PARAMETER :: IntfMZss = 1956 + + + ! Interface Deflections: + + INTEGER(IntKi), PARAMETER :: IntfTDXss = 1957 + INTEGER(IntKi), PARAMETER :: IntfTDYss = 1958 + INTEGER(IntKi), PARAMETER :: IntfTDZss = 1959 + INTEGER(IntKi), PARAMETER :: IntfRDXss = 1960 + INTEGER(IntKi), PARAMETER :: IntfRDYss = 1961 + INTEGER(IntKi), PARAMETER :: IntfRDZss = 1962 + + + ! Interface Accelerations: + + INTEGER(IntKi), PARAMETER :: IntfTAXss = 1963 + INTEGER(IntKi), PARAMETER :: IntfTAYss = 1964 + INTEGER(IntKi), PARAMETER :: IntfTAZss = 1965 + INTEGER(IntKi), PARAMETER :: IntfRAXss = 1966 + INTEGER(IntKi), PARAMETER :: IntfRAYss = 1967 + INTEGER(IntKi), PARAMETER :: IntfRAZss = 1968 + + + ! Modal Parameters: + + INTEGER(IntKi), PARAMETER :: SSqm01 = 1969 + INTEGER(IntKi), PARAMETER :: SSqm02 = 1970 + INTEGER(IntKi), PARAMETER :: SSqm03 = 1971 + INTEGER(IntKi), PARAMETER :: SSqm04 = 1972 + INTEGER(IntKi), PARAMETER :: SSqm05 = 1973 + INTEGER(IntKi), PARAMETER :: SSqm06 = 1974 + INTEGER(IntKi), PARAMETER :: SSqm07 = 1975 + INTEGER(IntKi), PARAMETER :: SSqm08 = 1976 + INTEGER(IntKi), PARAMETER :: SSqm09 = 1977 + INTEGER(IntKi), PARAMETER :: SSqm10 = 1978 + INTEGER(IntKi), PARAMETER :: SSqm11 = 1979 + INTEGER(IntKi), PARAMETER :: SSqm12 = 1980 + INTEGER(IntKi), PARAMETER :: SSqm13 = 1981 + INTEGER(IntKi), PARAMETER :: SSqm14 = 1982 + INTEGER(IntKi), PARAMETER :: SSqm15 = 1983 + INTEGER(IntKi), PARAMETER :: SSqm16 = 1984 + INTEGER(IntKi), PARAMETER :: SSqm17 = 1985 + INTEGER(IntKi), PARAMETER :: SSqm18 = 1986 + INTEGER(IntKi), PARAMETER :: SSqm19 = 1987 + INTEGER(IntKi), PARAMETER :: SSqm20 = 1988 + INTEGER(IntKi), PARAMETER :: SSqm21 = 1989 + INTEGER(IntKi), PARAMETER :: SSqm22 = 1990 + INTEGER(IntKi), PARAMETER :: SSqm23 = 1991 + INTEGER(IntKi), PARAMETER :: SSqm24 = 1992 + INTEGER(IntKi), PARAMETER :: SSqm25 = 1993 + INTEGER(IntKi), PARAMETER :: SSqm26 = 1994 + INTEGER(IntKi), PARAMETER :: SSqm27 = 1995 + INTEGER(IntKi), PARAMETER :: SSqm28 = 1996 + INTEGER(IntKi), PARAMETER :: SSqm29 = 1997 + INTEGER(IntKi), PARAMETER :: SSqm30 = 1998 + INTEGER(IntKi), PARAMETER :: SSqm31 = 1999 + INTEGER(IntKi), PARAMETER :: SSqm32 = 2000 + INTEGER(IntKi), PARAMETER :: SSqm33 = 2001 + INTEGER(IntKi), PARAMETER :: SSqm34 = 2002 + INTEGER(IntKi), PARAMETER :: SSqm35 = 2003 + INTEGER(IntKi), PARAMETER :: SSqm36 = 2004 + INTEGER(IntKi), PARAMETER :: SSqm37 = 2005 + INTEGER(IntKi), PARAMETER :: SSqm38 = 2006 + INTEGER(IntKi), PARAMETER :: SSqm39 = 2007 + INTEGER(IntKi), PARAMETER :: SSqm40 = 2008 + INTEGER(IntKi), PARAMETER :: SSqm41 = 2009 + INTEGER(IntKi), PARAMETER :: SSqm42 = 2010 + INTEGER(IntKi), PARAMETER :: SSqm43 = 2011 + INTEGER(IntKi), PARAMETER :: SSqm44 = 2012 + INTEGER(IntKi), PARAMETER :: SSqm45 = 2013 + INTEGER(IntKi), PARAMETER :: SSqm46 = 2014 + INTEGER(IntKi), PARAMETER :: SSqm47 = 2015 + INTEGER(IntKi), PARAMETER :: SSqm48 = 2016 + INTEGER(IntKi), PARAMETER :: SSqm49 = 2017 + INTEGER(IntKi), PARAMETER :: SSqm50 = 2018 + INTEGER(IntKi), PARAMETER :: SSqm51 = 2019 + INTEGER(IntKi), PARAMETER :: SSqm52 = 2020 + INTEGER(IntKi), PARAMETER :: SSqm53 = 2021 + INTEGER(IntKi), PARAMETER :: SSqm54 = 2022 + INTEGER(IntKi), PARAMETER :: SSqm55 = 2023 + INTEGER(IntKi), PARAMETER :: SSqm56 = 2024 + INTEGER(IntKi), PARAMETER :: SSqm57 = 2025 + INTEGER(IntKi), PARAMETER :: SSqm58 = 2026 + INTEGER(IntKi), PARAMETER :: SSqm59 = 2027 + INTEGER(IntKi), PARAMETER :: SSqm60 = 2028 + INTEGER(IntKi), PARAMETER :: SSqm61 = 2029 + INTEGER(IntKi), PARAMETER :: SSqm62 = 2030 + INTEGER(IntKi), PARAMETER :: SSqm63 = 2031 + INTEGER(IntKi), PARAMETER :: SSqm64 = 2032 + INTEGER(IntKi), PARAMETER :: SSqm65 = 2033 + INTEGER(IntKi), PARAMETER :: SSqm66 = 2034 + INTEGER(IntKi), PARAMETER :: SSqm67 = 2035 + INTEGER(IntKi), PARAMETER :: SSqm68 = 2036 + INTEGER(IntKi), PARAMETER :: SSqm69 = 2037 + INTEGER(IntKi), PARAMETER :: SSqm70 = 2038 + INTEGER(IntKi), PARAMETER :: SSqm71 = 2039 + INTEGER(IntKi), PARAMETER :: SSqm72 = 2040 + INTEGER(IntKi), PARAMETER :: SSqm73 = 2041 + INTEGER(IntKi), PARAMETER :: SSqm74 = 2042 + INTEGER(IntKi), PARAMETER :: SSqm75 = 2043 + INTEGER(IntKi), PARAMETER :: SSqm76 = 2044 + INTEGER(IntKi), PARAMETER :: SSqm77 = 2045 + INTEGER(IntKi), PARAMETER :: SSqm78 = 2046 + INTEGER(IntKi), PARAMETER :: SSqm79 = 2047 + INTEGER(IntKi), PARAMETER :: SSqm80 = 2048 + INTEGER(IntKi), PARAMETER :: SSqm81 = 2049 + INTEGER(IntKi), PARAMETER :: SSqm82 = 2050 + INTEGER(IntKi), PARAMETER :: SSqm83 = 2051 + INTEGER(IntKi), PARAMETER :: SSqm84 = 2052 + INTEGER(IntKi), PARAMETER :: SSqm85 = 2053 + INTEGER(IntKi), PARAMETER :: SSqm86 = 2054 + INTEGER(IntKi), PARAMETER :: SSqm87 = 2055 + INTEGER(IntKi), PARAMETER :: SSqm88 = 2056 + INTEGER(IntKi), PARAMETER :: SSqm89 = 2057 + INTEGER(IntKi), PARAMETER :: SSqm90 = 2058 + INTEGER(IntKi), PARAMETER :: SSqm91 = 2059 + INTEGER(IntKi), PARAMETER :: SSqm92 = 2060 + INTEGER(IntKi), PARAMETER :: SSqm93 = 2061 + INTEGER(IntKi), PARAMETER :: SSqm94 = 2062 + INTEGER(IntKi), PARAMETER :: SSqm95 = 2063 + INTEGER(IntKi), PARAMETER :: SSqm96 = 2064 + INTEGER(IntKi), PARAMETER :: SSqm97 = 2065 + INTEGER(IntKi), PARAMETER :: SSqm98 = 2066 + INTEGER(IntKi), PARAMETER :: SSqm99 = 2067 + INTEGER(IntKi), PARAMETER :: SSqmd01 = 2068 + INTEGER(IntKi), PARAMETER :: SSqmd02 = 2069 + INTEGER(IntKi), PARAMETER :: SSqmd03 = 2070 + INTEGER(IntKi), PARAMETER :: SSqmd04 = 2071 + INTEGER(IntKi), PARAMETER :: SSqmd05 = 2072 + INTEGER(IntKi), PARAMETER :: SSqmd06 = 2073 + INTEGER(IntKi), PARAMETER :: SSqmd07 = 2074 + INTEGER(IntKi), PARAMETER :: SSqmd08 = 2075 + INTEGER(IntKi), PARAMETER :: SSqmd09 = 2076 + INTEGER(IntKi), PARAMETER :: SSqmd10 = 2077 + INTEGER(IntKi), PARAMETER :: SSqmd11 = 2078 + INTEGER(IntKi), PARAMETER :: SSqmd12 = 2079 + INTEGER(IntKi), PARAMETER :: SSqmd13 = 2080 + INTEGER(IntKi), PARAMETER :: SSqmd14 = 2081 + INTEGER(IntKi), PARAMETER :: SSqmd15 = 2082 + INTEGER(IntKi), PARAMETER :: SSqmd16 = 2083 + INTEGER(IntKi), PARAMETER :: SSqmd17 = 2084 + INTEGER(IntKi), PARAMETER :: SSqmd18 = 2085 + INTEGER(IntKi), PARAMETER :: SSqmd19 = 2086 + INTEGER(IntKi), PARAMETER :: SSqmd20 = 2087 + INTEGER(IntKi), PARAMETER :: SSqmd21 = 2088 + INTEGER(IntKi), PARAMETER :: SSqmd22 = 2089 + INTEGER(IntKi), PARAMETER :: SSqmd23 = 2090 + INTEGER(IntKi), PARAMETER :: SSqmd24 = 2091 + INTEGER(IntKi), PARAMETER :: SSqmd25 = 2092 + INTEGER(IntKi), PARAMETER :: SSqmd26 = 2093 + INTEGER(IntKi), PARAMETER :: SSqmd27 = 2094 + INTEGER(IntKi), PARAMETER :: SSqmd28 = 2095 + INTEGER(IntKi), PARAMETER :: SSqmd29 = 2096 + INTEGER(IntKi), PARAMETER :: SSqmd30 = 2097 + INTEGER(IntKi), PARAMETER :: SSqmd31 = 2098 + INTEGER(IntKi), PARAMETER :: SSqmd32 = 2099 + INTEGER(IntKi), PARAMETER :: SSqmd33 = 2100 + INTEGER(IntKi), PARAMETER :: SSqmd34 = 2101 + INTEGER(IntKi), PARAMETER :: SSqmd35 = 2102 + INTEGER(IntKi), PARAMETER :: SSqmd36 = 2103 + INTEGER(IntKi), PARAMETER :: SSqmd37 = 2104 + INTEGER(IntKi), PARAMETER :: SSqmd38 = 2105 + INTEGER(IntKi), PARAMETER :: SSqmd39 = 2106 + INTEGER(IntKi), PARAMETER :: SSqmd40 = 2107 + INTEGER(IntKi), PARAMETER :: SSqmd41 = 2108 + INTEGER(IntKi), PARAMETER :: SSqmd42 = 2109 + INTEGER(IntKi), PARAMETER :: SSqmd43 = 2110 + INTEGER(IntKi), PARAMETER :: SSqmd44 = 2111 + INTEGER(IntKi), PARAMETER :: SSqmd45 = 2112 + INTEGER(IntKi), PARAMETER :: SSqmd46 = 2113 + INTEGER(IntKi), PARAMETER :: SSqmd47 = 2114 + INTEGER(IntKi), PARAMETER :: SSqmd48 = 2115 + INTEGER(IntKi), PARAMETER :: SSqmd49 = 2116 + INTEGER(IntKi), PARAMETER :: SSqmd50 = 2117 + INTEGER(IntKi), PARAMETER :: SSqmd51 = 2118 + INTEGER(IntKi), PARAMETER :: SSqmd52 = 2119 + INTEGER(IntKi), PARAMETER :: SSqmd53 = 2120 + INTEGER(IntKi), PARAMETER :: SSqmd54 = 2121 + INTEGER(IntKi), PARAMETER :: SSqmd55 = 2122 + INTEGER(IntKi), PARAMETER :: SSqmd56 = 2123 + INTEGER(IntKi), PARAMETER :: SSqmd57 = 2124 + INTEGER(IntKi), PARAMETER :: SSqmd58 = 2125 + INTEGER(IntKi), PARAMETER :: SSqmd59 = 2126 + INTEGER(IntKi), PARAMETER :: SSqmd60 = 2127 + INTEGER(IntKi), PARAMETER :: SSqmd61 = 2128 + INTEGER(IntKi), PARAMETER :: SSqmd62 = 2129 + INTEGER(IntKi), PARAMETER :: SSqmd63 = 2130 + INTEGER(IntKi), PARAMETER :: SSqmd64 = 2131 + INTEGER(IntKi), PARAMETER :: SSqmd65 = 2132 + INTEGER(IntKi), PARAMETER :: SSqmd66 = 2133 + INTEGER(IntKi), PARAMETER :: SSqmd67 = 2134 + INTEGER(IntKi), PARAMETER :: SSqmd68 = 2135 + INTEGER(IntKi), PARAMETER :: SSqmd69 = 2136 + INTEGER(IntKi), PARAMETER :: SSqmd70 = 2137 + INTEGER(IntKi), PARAMETER :: SSqmd71 = 2138 + INTEGER(IntKi), PARAMETER :: SSqmd72 = 2139 + INTEGER(IntKi), PARAMETER :: SSqmd73 = 2140 + INTEGER(IntKi), PARAMETER :: SSqmd74 = 2141 + INTEGER(IntKi), PARAMETER :: SSqmd75 = 2142 + INTEGER(IntKi), PARAMETER :: SSqmd76 = 2143 + INTEGER(IntKi), PARAMETER :: SSqmd77 = 2144 + INTEGER(IntKi), PARAMETER :: SSqmd78 = 2145 + INTEGER(IntKi), PARAMETER :: SSqmd79 = 2146 + INTEGER(IntKi), PARAMETER :: SSqmd80 = 2147 + INTEGER(IntKi), PARAMETER :: SSqmd81 = 2148 + INTEGER(IntKi), PARAMETER :: SSqmd82 = 2149 + INTEGER(IntKi), PARAMETER :: SSqmd83 = 2150 + INTEGER(IntKi), PARAMETER :: SSqmd84 = 2151 + INTEGER(IntKi), PARAMETER :: SSqmd85 = 2152 + INTEGER(IntKi), PARAMETER :: SSqmd86 = 2153 + INTEGER(IntKi), PARAMETER :: SSqmd87 = 2154 + INTEGER(IntKi), PARAMETER :: SSqmd88 = 2155 + INTEGER(IntKi), PARAMETER :: SSqmd89 = 2156 + INTEGER(IntKi), PARAMETER :: SSqmd90 = 2157 + INTEGER(IntKi), PARAMETER :: SSqmd91 = 2158 + INTEGER(IntKi), PARAMETER :: SSqmd92 = 2159 + INTEGER(IntKi), PARAMETER :: SSqmd93 = 2160 + INTEGER(IntKi), PARAMETER :: SSqmd94 = 2161 + INTEGER(IntKi), PARAMETER :: SSqmd95 = 2162 + INTEGER(IntKi), PARAMETER :: SSqmd96 = 2163 + INTEGER(IntKi), PARAMETER :: SSqmd97 = 2164 + INTEGER(IntKi), PARAMETER :: SSqmd98 = 2165 + INTEGER(IntKi), PARAMETER :: SSqmd99 = 2166 + INTEGER(IntKi), PARAMETER :: SSqmdd01 = 2167 + INTEGER(IntKi), PARAMETER :: SSqmdd02 = 2168 + INTEGER(IntKi), PARAMETER :: SSqmdd03 = 2169 + INTEGER(IntKi), PARAMETER :: SSqmdd04 = 2170 + INTEGER(IntKi), PARAMETER :: SSqmdd05 = 2171 + INTEGER(IntKi), PARAMETER :: SSqmdd06 = 2172 + INTEGER(IntKi), PARAMETER :: SSqmdd07 = 2173 + INTEGER(IntKi), PARAMETER :: SSqmdd08 = 2174 + INTEGER(IntKi), PARAMETER :: SSqmdd09 = 2175 + INTEGER(IntKi), PARAMETER :: SSqmdd10 = 2176 + INTEGER(IntKi), PARAMETER :: SSqmdd11 = 2177 + INTEGER(IntKi), PARAMETER :: SSqmdd12 = 2178 + INTEGER(IntKi), PARAMETER :: SSqmdd13 = 2179 + INTEGER(IntKi), PARAMETER :: SSqmdd14 = 2180 + INTEGER(IntKi), PARAMETER :: SSqmdd15 = 2181 + INTEGER(IntKi), PARAMETER :: SSqmdd16 = 2182 + INTEGER(IntKi), PARAMETER :: SSqmdd17 = 2183 + INTEGER(IntKi), PARAMETER :: SSqmdd18 = 2184 + INTEGER(IntKi), PARAMETER :: SSqmdd19 = 2185 + INTEGER(IntKi), PARAMETER :: SSqmdd20 = 2186 + INTEGER(IntKi), PARAMETER :: SSqmdd21 = 2187 + INTEGER(IntKi), PARAMETER :: SSqmdd22 = 2188 + INTEGER(IntKi), PARAMETER :: SSqmdd23 = 2189 + INTEGER(IntKi), PARAMETER :: SSqmdd24 = 2190 + INTEGER(IntKi), PARAMETER :: SSqmdd25 = 2191 + INTEGER(IntKi), PARAMETER :: SSqmdd26 = 2192 + INTEGER(IntKi), PARAMETER :: SSqmdd27 = 2193 + INTEGER(IntKi), PARAMETER :: SSqmdd28 = 2194 + INTEGER(IntKi), PARAMETER :: SSqmdd29 = 2195 + INTEGER(IntKi), PARAMETER :: SSqmdd30 = 2196 + INTEGER(IntKi), PARAMETER :: SSqmdd31 = 2197 + INTEGER(IntKi), PARAMETER :: SSqmdd32 = 2198 + INTEGER(IntKi), PARAMETER :: SSqmdd33 = 2199 + INTEGER(IntKi), PARAMETER :: SSqmdd34 = 2200 + INTEGER(IntKi), PARAMETER :: SSqmdd35 = 2201 + INTEGER(IntKi), PARAMETER :: SSqmdd36 = 2202 + INTEGER(IntKi), PARAMETER :: SSqmdd37 = 2203 + INTEGER(IntKi), PARAMETER :: SSqmdd38 = 2204 + INTEGER(IntKi), PARAMETER :: SSqmdd39 = 2205 + INTEGER(IntKi), PARAMETER :: SSqmdd40 = 2206 + INTEGER(IntKi), PARAMETER :: SSqmdd41 = 2207 + INTEGER(IntKi), PARAMETER :: SSqmdd42 = 2208 + INTEGER(IntKi), PARAMETER :: SSqmdd43 = 2209 + INTEGER(IntKi), PARAMETER :: SSqmdd44 = 2210 + INTEGER(IntKi), PARAMETER :: SSqmdd45 = 2211 + INTEGER(IntKi), PARAMETER :: SSqmdd46 = 2212 + INTEGER(IntKi), PARAMETER :: SSqmdd47 = 2213 + INTEGER(IntKi), PARAMETER :: SSqmdd48 = 2214 + INTEGER(IntKi), PARAMETER :: SSqmdd49 = 2215 + INTEGER(IntKi), PARAMETER :: SSqmdd50 = 2216 + INTEGER(IntKi), PARAMETER :: SSqmdd51 = 2217 + INTEGER(IntKi), PARAMETER :: SSqmdd52 = 2218 + INTEGER(IntKi), PARAMETER :: SSqmdd53 = 2219 + INTEGER(IntKi), PARAMETER :: SSqmdd54 = 2220 + INTEGER(IntKi), PARAMETER :: SSqmdd55 = 2221 + INTEGER(IntKi), PARAMETER :: SSqmdd56 = 2222 + INTEGER(IntKi), PARAMETER :: SSqmdd57 = 2223 + INTEGER(IntKi), PARAMETER :: SSqmdd58 = 2224 + INTEGER(IntKi), PARAMETER :: SSqmdd59 = 2225 + INTEGER(IntKi), PARAMETER :: SSqmdd60 = 2226 + INTEGER(IntKi), PARAMETER :: SSqmdd61 = 2227 + INTEGER(IntKi), PARAMETER :: SSqmdd62 = 2228 + INTEGER(IntKi), PARAMETER :: SSqmdd63 = 2229 + INTEGER(IntKi), PARAMETER :: SSqmdd64 = 2230 + INTEGER(IntKi), PARAMETER :: SSqmdd65 = 2231 + INTEGER(IntKi), PARAMETER :: SSqmdd66 = 2232 + INTEGER(IntKi), PARAMETER :: SSqmdd67 = 2233 + INTEGER(IntKi), PARAMETER :: SSqmdd68 = 2234 + INTEGER(IntKi), PARAMETER :: SSqmdd69 = 2235 + INTEGER(IntKi), PARAMETER :: SSqmdd70 = 2236 + INTEGER(IntKi), PARAMETER :: SSqmdd71 = 2237 + INTEGER(IntKi), PARAMETER :: SSqmdd72 = 2238 + INTEGER(IntKi), PARAMETER :: SSqmdd73 = 2239 + INTEGER(IntKi), PARAMETER :: SSqmdd74 = 2240 + INTEGER(IntKi), PARAMETER :: SSqmdd75 = 2241 + INTEGER(IntKi), PARAMETER :: SSqmdd76 = 2242 + INTEGER(IntKi), PARAMETER :: SSqmdd77 = 2243 + INTEGER(IntKi), PARAMETER :: SSqmdd78 = 2244 + INTEGER(IntKi), PARAMETER :: SSqmdd79 = 2245 + INTEGER(IntKi), PARAMETER :: SSqmdd80 = 2246 + INTEGER(IntKi), PARAMETER :: SSqmdd81 = 2247 + INTEGER(IntKi), PARAMETER :: SSqmdd82 = 2248 + INTEGER(IntKi), PARAMETER :: SSqmdd83 = 2249 + INTEGER(IntKi), PARAMETER :: SSqmdd84 = 2250 + INTEGER(IntKi), PARAMETER :: SSqmdd85 = 2251 + INTEGER(IntKi), PARAMETER :: SSqmdd86 = 2252 + INTEGER(IntKi), PARAMETER :: SSqmdd87 = 2253 + INTEGER(IntKi), PARAMETER :: SSqmdd88 = 2254 + INTEGER(IntKi), PARAMETER :: SSqmdd89 = 2255 + INTEGER(IntKi), PARAMETER :: SSqmdd90 = 2256 + INTEGER(IntKi), PARAMETER :: SSqmdd91 = 2257 + INTEGER(IntKi), PARAMETER :: SSqmdd92 = 2258 + INTEGER(IntKi), PARAMETER :: SSqmdd93 = 2259 + INTEGER(IntKi), PARAMETER :: SSqmdd94 = 2260 + INTEGER(IntKi), PARAMETER :: SSqmdd95 = 2261 + INTEGER(IntKi), PARAMETER :: SSqmdd96 = 2262 + INTEGER(IntKi), PARAMETER :: SSqmdd97 = 2263 + INTEGER(IntKi), PARAMETER :: SSqmdd98 = 2264 + INTEGER(IntKi), PARAMETER :: SSqmdd99 = 2265 + + + ! The maximum number of output channels which can be output by the code. + !INTEGER(IntKi), PARAMETER :: MaxOutPts = 2265 + +!End of code generated by Matlab script + + INTEGER, PARAMETER :: MNfmKe(6,9,9) = reshape((/ M1N1FKxe,M1N1FKye,M1N1FKze,M1N1MKxe,M1N1MKye,M1N1MKze, & + M1N2FKxe,M1N2FKye,M1N2FKze,M1N2MKxe,M1N2MKye,M1N2MKze, & + M1N3FKxe,M1N3FKye,M1N3FKze,M1N3MKxe,M1N3MKye,M1N3MKze, & + M1N4FKxe,M1N4FKye,M1N4FKze,M1N4MKxe,M1N4MKye,M1N4MKze, & + M1N5FKxe,M1N5FKye,M1N5FKze,M1N5MKxe,M1N5MKye,M1N5MKze, & + M1N6FKxe,M1N6FKye,M1N6FKze,M1N6MKxe,M1N6MKye,M1N6MKze, & + M1N7FKxe,M1N7FKye,M1N7FKze,M1N7MKxe,M1N7MKye,M1N7MKze, & + M1N8FKxe,M1N8FKye,M1N8FKze,M1N8MKxe,M1N8MKye,M1N8MKze, & + M1N9FKxe,M1N9FKye,M1N9FKze,M1N9MKxe,M1N9MKye,M1N9MKze, & + M2N1FKxe,M2N1FKye,M2N1FKze,M2N1MKxe,M2N1MKye,M2N1MKze, & + M2N2FKxe,M2N2FKye,M2N2FKze,M2N2MKxe,M2N2MKye,M2N2MKze, & + M2N3FKxe,M2N3FKye,M2N3FKze,M2N3MKxe,M2N3MKye,M2N3MKze, & + M2N4FKxe,M2N4FKye,M2N4FKze,M2N4MKxe,M2N4MKye,M2N4MKze, & + M2N5FKxe,M2N5FKye,M2N5FKze,M2N5MKxe,M2N5MKye,M2N5MKze, & + M2N6FKxe,M2N6FKye,M2N6FKze,M2N6MKxe,M2N6MKye,M2N6MKze, & + M2N7FKxe,M2N7FKye,M2N7FKze,M2N7MKxe,M2N7MKye,M2N7MKze, & + M2N8FKxe,M2N8FKye,M2N8FKze,M2N8MKxe,M2N8MKye,M2N8MKze, & + M2N9FKxe,M2N9FKye,M2N9FKze,M2N9MKxe,M2N9MKye,M2N9MKze, & + M3N1FKxe,M3N1FKye,M3N1FKze,M3N1MKxe,M3N1MKye,M3N1MKze, & + M3N2FKxe,M3N2FKye,M3N2FKze,M3N2MKxe,M3N2MKye,M3N2MKze, & + M3N3FKxe,M3N3FKye,M3N3FKze,M3N3MKxe,M3N3MKye,M3N3MKze, & + M3N4FKxe,M3N4FKye,M3N4FKze,M3N4MKxe,M3N4MKye,M3N4MKze, & + M3N5FKxe,M3N5FKye,M3N5FKze,M3N5MKxe,M3N5MKye,M3N5MKze, & + M3N6FKxe,M3N6FKye,M3N6FKze,M3N6MKxe,M3N6MKye,M3N6MKze, & + M3N7FKxe,M3N7FKye,M3N7FKze,M3N7MKxe,M3N7MKye,M3N7MKze, & + M3N8FKxe,M3N8FKye,M3N8FKze,M3N8MKxe,M3N8MKye,M3N8MKze, & + M3N9FKxe,M3N9FKye,M3N9FKze,M3N9MKxe,M3N9MKye,M3N9MKze, & + M4N1FKxe,M4N1FKye,M4N1FKze,M4N1MKxe,M4N1MKye,M4N1MKze, & + M4N2FKxe,M4N2FKye,M4N2FKze,M4N2MKxe,M4N2MKye,M4N2MKze, & + M4N3FKxe,M4N3FKye,M4N3FKze,M4N3MKxe,M4N3MKye,M4N3MKze, & + M4N4FKxe,M4N4FKye,M4N4FKze,M4N4MKxe,M4N4MKye,M4N4MKze, & + M4N5FKxe,M4N5FKye,M4N5FKze,M4N5MKxe,M4N5MKye,M4N5MKze, & + M4N6FKxe,M4N6FKye,M4N6FKze,M4N6MKxe,M4N6MKye,M4N6MKze, & + M4N7FKxe,M4N7FKye,M4N7FKze,M4N7MKxe,M4N7MKye,M4N7MKze, & + M4N8FKxe,M4N8FKye,M4N8FKze,M4N8MKxe,M4N8MKye,M4N8MKze, & + M4N9FKxe,M4N9FKye,M4N9FKze,M4N9MKxe,M4N9MKye,M4N9MKze, & + M5N1FKxe,M5N1FKye,M5N1FKze,M5N1MKxe,M5N1MKye,M5N1MKze, & + M5N2FKxe,M5N2FKye,M5N2FKze,M5N2MKxe,M5N2MKye,M5N2MKze, & + M5N3FKxe,M5N3FKye,M5N3FKze,M5N3MKxe,M5N3MKye,M5N3MKze, & + M5N4FKxe,M5N4FKye,M5N4FKze,M5N4MKxe,M5N4MKye,M5N4MKze, & + M5N5FKxe,M5N5FKye,M5N5FKze,M5N5MKxe,M5N5MKye,M5N5MKze, & + M5N6FKxe,M5N6FKye,M5N6FKze,M5N6MKxe,M5N6MKye,M5N6MKze, & + M5N7FKxe,M5N7FKye,M5N7FKze,M5N7MKxe,M5N7MKye,M5N7MKze, & + M5N8FKxe,M5N8FKye,M5N8FKze,M5N8MKxe,M5N8MKye,M5N8MKze, & + M5N9FKxe,M5N9FKye,M5N9FKze,M5N9MKxe,M5N9MKye,M5N9MKze, & + M6N1FKxe,M6N1FKye,M6N1FKze,M6N1MKxe,M6N1MKye,M6N1MKze, & + M6N2FKxe,M6N2FKye,M6N2FKze,M6N2MKxe,M6N2MKye,M6N2MKze, & + M6N3FKxe,M6N3FKye,M6N3FKze,M6N3MKxe,M6N3MKye,M6N3MKze, & + M6N4FKxe,M6N4FKye,M6N4FKze,M6N4MKxe,M6N4MKye,M6N4MKze, & + M6N5FKxe,M6N5FKye,M6N5FKze,M6N5MKxe,M6N5MKye,M6N5MKze, & + M6N6FKxe,M6N6FKye,M6N6FKze,M6N6MKxe,M6N6MKye,M6N6MKze, & + M6N7FKxe,M6N7FKye,M6N7FKze,M6N7MKxe,M6N7MKye,M6N7MKze, & + M6N8FKxe,M6N8FKye,M6N8FKze,M6N8MKxe,M6N8MKye,M6N8MKze, & + M6N9FKxe,M6N9FKye,M6N9FKze,M6N9MKxe,M6N9MKye,M6N9MKze, & + M7N1FKxe,M7N1FKye,M7N1FKze,M7N1MKxe,M7N1MKye,M7N1MKze, & + M7N2FKxe,M7N2FKye,M7N2FKze,M7N2MKxe,M7N2MKye,M7N2MKze, & + M7N3FKxe,M7N3FKye,M7N3FKze,M7N3MKxe,M7N3MKye,M7N3MKze, & + M7N4FKxe,M7N4FKye,M7N4FKze,M7N4MKxe,M7N4MKye,M7N4MKze, & + M7N5FKxe,M7N5FKye,M7N5FKze,M7N5MKxe,M7N5MKye,M7N5MKze, & + M7N6FKxe,M7N6FKye,M7N6FKze,M7N6MKxe,M7N6MKye,M7N6MKze, & + M7N7FKxe,M7N7FKye,M7N7FKze,M7N7MKxe,M7N7MKye,M7N7MKze, & + M7N8FKxe,M7N8FKye,M7N8FKze,M7N8MKxe,M7N8MKye,M7N8MKze, & + M7N9FKxe,M7N9FKye,M7N9FKze,M7N9MKxe,M7N9MKye,M7N9MKze, & + M8N1FKxe,M8N1FKye,M8N1FKze,M8N1MKxe,M8N1MKye,M8N1MKze, & + M8N2FKxe,M8N2FKye,M8N2FKze,M8N2MKxe,M8N2MKye,M8N2MKze, & + M8N3FKxe,M8N3FKye,M8N3FKze,M8N3MKxe,M8N3MKye,M8N3MKze, & + M8N4FKxe,M8N4FKye,M8N4FKze,M8N4MKxe,M8N4MKye,M8N4MKze, & + M8N5FKxe,M8N5FKye,M8N5FKze,M8N5MKxe,M8N5MKye,M8N5MKze, & + M8N6FKxe,M8N6FKye,M8N6FKze,M8N6MKxe,M8N6MKye,M8N6MKze, & + M8N7FKxe,M8N7FKye,M8N7FKze,M8N7MKxe,M8N7MKye,M8N7MKze, & + M8N8FKxe,M8N8FKye,M8N8FKze,M8N8MKxe,M8N8MKye,M8N8MKze, & + M8N9FKxe,M8N9FKye,M8N9FKze,M8N9MKxe,M8N9MKye,M8N9MKze, & + M9N1FKxe,M9N1FKye,M9N1FKze,M9N1MKxe,M9N1MKye,M9N1MKze, & + M9N2FKxe,M9N2FKye,M9N2FKze,M9N2MKxe,M9N2MKye,M9N2MKze, & + M9N3FKxe,M9N3FKye,M9N3FKze,M9N3MKxe,M9N3MKye,M9N3MKze, & + M9N4FKxe,M9N4FKye,M9N4FKze,M9N4MKxe,M9N4MKye,M9N4MKze, & + M9N5FKxe,M9N5FKye,M9N5FKze,M9N5MKxe,M9N5MKye,M9N5MKze, & + M9N6FKxe,M9N6FKye,M9N6FKze,M9N6MKxe,M9N6MKye,M9N6MKze, & + M9N7FKxe,M9N7FKye,M9N7FKze,M9N7MKxe,M9N7MKye,M9N7MKze, & + M9N8FKxe,M9N8FKye,M9N8FKze,M9N8MKxe,M9N8MKye,M9N8MKze, & + M9N9FKxe,M9N9FKye,M9N9FKze,M9N9MKxe,M9N9MKye,M9N9MKze /),(/6,9,9/)) + + + + INTEGER, PARAMETER :: MNfmMe(6,9,9) = reshape((/ M1N1FMxe,M1N1FMye,M1N1FMze,M1N1MMxe,M1N1MMye,M1N1MMze, & + M1N2FMxe,M1N2FMye,M1N2FMze,M1N2MMxe,M1N2MMye,M1N2MMze, & + M1N3FMxe,M1N3FMye,M1N3FMze,M1N3MMxe,M1N3MMye,M1N3MMze, & + M1N4FMxe,M1N4FMye,M1N4FMze,M1N4MMxe,M1N4MMye,M1N4MMze, & + M1N5FMxe,M1N5FMye,M1N5FMze,M1N5MMxe,M1N5MMye,M1N5MMze, & + M1N6FMxe,M1N6FMye,M1N6FMze,M1N6MMxe,M1N6MMye,M1N6MMze, & + M1N7FMxe,M1N7FMye,M1N7FMze,M1N7MMxe,M1N7MMye,M1N7MMze, & + M1N8FMxe,M1N8FMye,M1N8FMze,M1N8MMxe,M1N8MMye,M1N8MMze, & + M1N9FMxe,M1N9FMye,M1N9FMze,M1N9MMxe,M1N9MMye,M1N9MMze, & + M2N1FMxe,M2N1FMye,M2N1FMze,M2N1MMxe,M2N1MMye,M2N1MMze, & + M2N2FMxe,M2N2FMye,M2N2FMze,M2N2MMxe,M2N2MMye,M2N2MMze, & + M2N3FMxe,M2N3FMye,M2N3FMze,M2N3MMxe,M2N3MMye,M2N3MMze, & + M2N4FMxe,M2N4FMye,M2N4FMze,M2N4MMxe,M2N4MMye,M2N4MMze, & + M2N5FMxe,M2N5FMye,M2N5FMze,M2N5MMxe,M2N5MMye,M2N5MMze, & + M2N6FMxe,M2N6FMye,M2N6FMze,M2N6MMxe,M2N6MMye,M2N6MMze, & + M2N7FMxe,M2N7FMye,M2N7FMze,M2N7MMxe,M2N7MMye,M2N7MMze, & + M2N8FMxe,M2N8FMye,M2N8FMze,M2N8MMxe,M2N8MMye,M2N8MMze, & + M2N9FMxe,M2N9FMye,M2N9FMze,M2N9MMxe,M2N9MMye,M2N9MMze, & + M3N1FMxe,M3N1FMye,M3N1FMze,M3N1MMxe,M3N1MMye,M3N1MMze, & + M3N2FMxe,M3N2FMye,M3N2FMze,M3N2MMxe,M3N2MMye,M3N2MMze, & + M3N3FMxe,M3N3FMye,M3N3FMze,M3N3MMxe,M3N3MMye,M3N3MMze, & + M3N4FMxe,M3N4FMye,M3N4FMze,M3N4MMxe,M3N4MMye,M3N4MMze, & + M3N5FMxe,M3N5FMye,M3N5FMze,M3N5MMxe,M3N5MMye,M3N5MMze, & + M3N6FMxe,M3N6FMye,M3N6FMze,M3N6MMxe,M3N6MMye,M3N6MMze, & + M3N7FMxe,M3N7FMye,M3N7FMze,M3N7MMxe,M3N7MMye,M3N7MMze, & + M3N8FMxe,M3N8FMye,M3N8FMze,M3N8MMxe,M3N8MMye,M3N8MMze, & + M3N9FMxe,M3N9FMye,M3N9FMze,M3N9MMxe,M3N9MMye,M3N9MMze, & + M4N1FMxe,M4N1FMye,M4N1FMze,M4N1MMxe,M4N1MMye,M4N1MMze, & + M4N2FMxe,M4N2FMye,M4N2FMze,M4N2MMxe,M4N2MMye,M4N2MMze, & + M4N3FMxe,M4N3FMye,M4N3FMze,M4N3MMxe,M4N3MMye,M4N3MMze, & + M4N4FMxe,M4N4FMye,M4N4FMze,M4N4MMxe,M4N4MMye,M4N4MMze, & + M4N5FMxe,M4N5FMye,M4N5FMze,M4N5MMxe,M4N5MMye,M4N5MMze, & + M4N6FMxe,M4N6FMye,M4N6FMze,M4N6MMxe,M4N6MMye,M4N6MMze, & + M4N7FMxe,M4N7FMye,M4N7FMze,M4N7MMxe,M4N7MMye,M4N7MMze, & + M4N8FMxe,M4N8FMye,M4N8FMze,M4N8MMxe,M4N8MMye,M4N8MMze, & + M4N9FMxe,M4N9FMye,M4N9FMze,M4N9MMxe,M4N9MMye,M4N9MMze, & + M5N1FMxe,M5N1FMye,M5N1FMze,M5N1MMxe,M5N1MMye,M5N1MMze, & + M5N2FMxe,M5N2FMye,M5N2FMze,M5N2MMxe,M5N2MMye,M5N2MMze, & + M5N3FMxe,M5N3FMye,M5N3FMze,M5N3MMxe,M5N3MMye,M5N3MMze, & + M5N4FMxe,M5N4FMye,M5N4FMze,M5N4MMxe,M5N4MMye,M5N4MMze, & + M5N5FMxe,M5N5FMye,M5N5FMze,M5N5MMxe,M5N5MMye,M5N5MMze, & + M5N6FMxe,M5N6FMye,M5N6FMze,M5N6MMxe,M5N6MMye,M5N6MMze, & + M5N7FMxe,M5N7FMye,M5N7FMze,M5N7MMxe,M5N7MMye,M5N7MMze, & + M5N8FMxe,M5N8FMye,M5N8FMze,M5N8MMxe,M5N8MMye,M5N8MMze, & + M5N9FMxe,M5N9FMye,M5N9FMze,M5N9MMxe,M5N9MMye,M5N9MMze, & + M6N1FMxe,M6N1FMye,M6N1FMze,M6N1MMxe,M6N1MMye,M6N1MMze, & + M6N2FMxe,M6N2FMye,M6N2FMze,M6N2MMxe,M6N2MMye,M6N2MMze, & + M6N3FMxe,M6N3FMye,M6N3FMze,M6N3MMxe,M6N3MMye,M6N3MMze, & + M6N4FMxe,M6N4FMye,M6N4FMze,M6N4MMxe,M6N4MMye,M6N4MMze, & + M6N5FMxe,M6N5FMye,M6N5FMze,M6N5MMxe,M6N5MMye,M6N5MMze, & + M6N6FMxe,M6N6FMye,M6N6FMze,M6N6MMxe,M6N6MMye,M6N6MMze, & + M6N7FMxe,M6N7FMye,M6N7FMze,M6N7MMxe,M6N7MMye,M6N7MMze, & + M6N8FMxe,M6N8FMye,M6N8FMze,M6N8MMxe,M6N8MMye,M6N8MMze, & + M6N9FMxe,M6N9FMye,M6N9FMze,M6N9MMxe,M6N9MMye,M6N9MMze, & + M7N1FMxe,M7N1FMye,M7N1FMze,M7N1MMxe,M7N1MMye,M7N1MMze, & + M7N2FMxe,M7N2FMye,M7N2FMze,M7N2MMxe,M7N2MMye,M7N2MMze, & + M7N3FMxe,M7N3FMye,M7N3FMze,M7N3MMxe,M7N3MMye,M7N3MMze, & + M7N4FMxe,M7N4FMye,M7N4FMze,M7N4MMxe,M7N4MMye,M7N4MMze, & + M7N5FMxe,M7N5FMye,M7N5FMze,M7N5MMxe,M7N5MMye,M7N5MMze, & + M7N6FMxe,M7N6FMye,M7N6FMze,M7N6MMxe,M7N6MMye,M7N6MMze, & + M7N7FMxe,M7N7FMye,M7N7FMze,M7N7MMxe,M7N7MMye,M7N7MMze, & + M7N8FMxe,M7N8FMye,M7N8FMze,M7N8MMxe,M7N8MMye,M7N8MMze, & + M7N9FMxe,M7N9FMye,M7N9FMze,M7N9MMxe,M7N9MMye,M7N9MMze, & + M8N1FMxe,M8N1FMye,M8N1FMze,M8N1MMxe,M8N1MMye,M8N1MMze, & + M8N2FMxe,M8N2FMye,M8N2FMze,M8N2MMxe,M8N2MMye,M8N2MMze, & + M8N3FMxe,M8N3FMye,M8N3FMze,M8N3MMxe,M8N3MMye,M8N3MMze, & + M8N4FMxe,M8N4FMye,M8N4FMze,M8N4MMxe,M8N4MMye,M8N4MMze, & + M8N5FMxe,M8N5FMye,M8N5FMze,M8N5MMxe,M8N5MMye,M8N5MMze, & + M8N6FMxe,M8N6FMye,M8N6FMze,M8N6MMxe,M8N6MMye,M8N6MMze, & + M8N7FMxe,M8N7FMye,M8N7FMze,M8N7MMxe,M8N7MMye,M8N7MMze, & + M8N8FMxe,M8N8FMye,M8N8FMze,M8N8MMxe,M8N8MMye,M8N8MMze, & + M8N9FMxe,M8N9FMye,M8N9FMze,M8N9MMxe,M8N9MMye,M8N9MMze, & + M9N1FMxe,M9N1FMye,M9N1FMze,M9N1MMxe,M9N1MMye,M9N1MMze, & + M9N2FMxe,M9N2FMye,M9N2FMze,M9N2MMxe,M9N2MMye,M9N2MMze, & + M9N3FMxe,M9N3FMye,M9N3FMze,M9N3MMxe,M9N3MMye,M9N3MMze, & + M9N4FMxe,M9N4FMye,M9N4FMze,M9N4MMxe,M9N4MMye,M9N4MMze, & + M9N5FMxe,M9N5FMye,M9N5FMze,M9N5MMxe,M9N5MMye,M9N5MMze, & + M9N6FMxe,M9N6FMye,M9N6FMze,M9N6MMxe,M9N6MMye,M9N6MMze, & + M9N7FMxe,M9N7FMye,M9N7FMze,M9N7MMxe,M9N7MMye,M9N7MMze, & + M9N8FMxe,M9N8FMye,M9N8FMze,M9N8MMxe,M9N8MMye,M9N8MMze, & + M9N9FMxe,M9N9FMye,M9N9FMze,M9N9MMxe,M9N9MMye,M9N9MMze /),(/6,9,9/)) + + INTEGER, PARAMETER :: MNTDss(3,9,9) = reshape((/M1N1TDxss,M1N1TDyss,M1N1TDzss, & + M1N2TDxss,M1N2TDyss,M1N2TDzss, & + M1N3TDxss,M1N3TDyss,M1N3TDzss, & + M1N4TDxss,M1N4TDyss,M1N4TDzss, & + M1N5TDxss,M1N5TDyss,M1N5TDzss, & + M1N6TDxss,M1N6TDyss,M1N6TDzss, & + M1N7TDxss,M1N7TDyss,M1N7TDzss, & + M1N8TDxss,M1N8TDyss,M1N8TDzss, & + M1N9TDxss,M1N9TDyss,M1N9TDzss, & + M2N1TDxss,M2N1TDyss,M2N1TDzss, & + M2N2TDxss,M2N2TDyss,M2N2TDzss, & + M2N3TDxss,M2N3TDyss,M2N3TDzss, & + M2N4TDxss,M2N4TDyss,M2N4TDzss, & + M2N5TDxss,M2N5TDyss,M2N5TDzss, & + M2N6TDxss,M2N6TDyss,M2N6TDzss, & + M2N7TDxss,M2N7TDyss,M2N7TDzss, & + M2N8TDxss,M2N8TDyss,M2N8TDzss, & + M2N9TDxss,M2N9TDyss,M2N9TDzss, & + M3N1TDxss,M3N1TDyss,M3N1TDzss, & + M3N2TDxss,M3N2TDyss,M3N2TDzss, & + M3N3TDxss,M3N3TDyss,M3N3TDzss, & + M3N4TDxss,M3N4TDyss,M3N4TDzss, & + M3N5TDxss,M3N5TDyss,M3N5TDzss, & + M3N6TDxss,M3N6TDyss,M3N6TDzss, & + M3N7TDxss,M3N7TDyss,M3N7TDzss, & + M3N8TDxss,M3N8TDyss,M3N8TDzss, & + M3N9TDxss,M3N9TDyss,M3N9TDzss, & + M4N1TDxss,M4N1TDyss,M4N1TDzss, & + M4N2TDxss,M4N2TDyss,M4N2TDzss, & + M4N3TDxss,M4N3TDyss,M4N3TDzss, & + M4N4TDxss,M4N4TDyss,M4N4TDzss, & + M4N5TDxss,M4N5TDyss,M4N5TDzss, & + M4N6TDxss,M4N6TDyss,M4N6TDzss, & + M4N7TDxss,M4N7TDyss,M4N7TDzss, & + M4N8TDxss,M4N8TDyss,M4N8TDzss, & + M4N9TDxss,M4N9TDyss,M4N9TDzss, & + M5N1TDxss,M5N1TDyss,M5N1TDzss, & + M5N2TDxss,M5N2TDyss,M5N2TDzss, & + M5N3TDxss,M5N3TDyss,M5N3TDzss, & + M5N4TDxss,M5N4TDyss,M5N4TDzss, & + M5N5TDxss,M5N5TDyss,M5N5TDzss, & + M5N6TDxss,M5N6TDyss,M5N6TDzss, & + M5N7TDxss,M5N7TDyss,M5N7TDzss, & + M5N8TDxss,M5N8TDyss,M5N8TDzss, & + M5N9TDxss,M5N9TDyss,M5N9TDzss, & + M6N1TDxss,M6N1TDyss,M6N1TDzss, & + M6N2TDxss,M6N2TDyss,M6N2TDzss, & + M6N3TDxss,M6N3TDyss,M6N3TDzss, & + M6N4TDxss,M6N4TDyss,M6N4TDzss, & + M6N5TDxss,M6N5TDyss,M6N5TDzss, & + M6N6TDxss,M6N6TDyss,M6N6TDzss, & + M6N7TDxss,M6N7TDyss,M6N7TDzss, & + M6N8TDxss,M6N8TDyss,M6N8TDzss, & + M6N9TDxss,M6N9TDyss,M6N9TDzss, & + M7N1TDxss,M7N1TDyss,M7N1TDzss, & + M7N2TDxss,M7N2TDyss,M7N2TDzss, & + M7N3TDxss,M7N3TDyss,M7N3TDzss, & + M7N4TDxss,M7N4TDyss,M7N4TDzss, & + M7N5TDxss,M7N5TDyss,M7N5TDzss, & + M7N6TDxss,M7N6TDyss,M7N6TDzss, & + M7N7TDxss,M7N7TDyss,M7N7TDzss, & + M7N8TDxss,M7N8TDyss,M7N8TDzss, & + M7N9TDxss,M7N9TDyss,M7N9TDzss, & + M8N1TDxss,M8N1TDyss,M8N1TDzss, & + M8N2TDxss,M8N2TDyss,M8N2TDzss, & + M8N3TDxss,M8N3TDyss,M8N3TDzss, & + M8N4TDxss,M8N4TDyss,M8N4TDzss, & + M8N5TDxss,M8N5TDyss,M8N5TDzss, & + M8N6TDxss,M8N6TDyss,M8N6TDzss, & + M8N7TDxss,M8N7TDyss,M8N7TDzss, & + M8N8TDxss,M8N8TDyss,M8N8TDzss, & + M8N9TDxss,M8N9TDyss,M8N9TDzss, & + M9N1TDxss,M9N1TDyss,M9N1TDzss, & + M9N2TDxss,M9N2TDyss,M9N2TDzss, & + M9N3TDxss,M9N3TDyss,M9N3TDzss, & + M9N4TDxss,M9N4TDyss,M9N4TDzss, & + M9N5TDxss,M9N5TDyss,M9N5TDzss, & + M9N6TDxss,M9N6TDyss,M9N6TDzss, & + M9N7TDxss,M9N7TDyss,M9N7TDzss, & + M9N8TDxss,M9N8TDyss,M9N8TDzss, & + M9N9TDxss,M9N9TDyss,M9N9TDzss/), (/3,9,9/)) + +INTEGER, PARAMETER :: MNRDe (3,9,9) = reshape((/M1N1RDxe,M1N1RDye,M1N1RDze, & + M1N2RDxe,M1N2RDye,M1N2RDze, & + M1N3RDxe,M1N3RDye,M1N3RDze, & + M1N4RDxe,M1N4RDye,M1N4RDze, & + M1N5RDxe,M1N5RDye,M1N5RDze, & + M1N6RDxe,M1N6RDye,M1N6RDze, & + M1N7RDxe,M1N7RDye,M1N7RDze, & + M1N8RDxe,M1N8RDye,M1N8RDze, & + M1N9RDxe,M1N9RDye,M1N9RDze, & + M2N1RDxe,M2N1RDye,M2N1RDze, & + M2N2RDxe,M2N2RDye,M2N2RDze, & + M2N3RDxe,M2N3RDye,M2N3RDze, & + M2N4RDxe,M2N4RDye,M2N4RDze, & + M2N5RDxe,M2N5RDye,M2N5RDze, & + M2N6RDxe,M2N6RDye,M2N6RDze, & + M2N7RDxe,M2N7RDye,M2N7RDze, & + M2N8RDxe,M2N8RDye,M2N8RDze, & + M2N9RDxe,M2N9RDye,M2N9RDze, & + M3N1RDxe,M3N1RDye,M3N1RDze, & + M3N2RDxe,M3N2RDye,M3N2RDze, & + M3N3RDxe,M3N3RDye,M3N3RDze, & + M3N4RDxe,M3N4RDye,M3N4RDze, & + M3N5RDxe,M3N5RDye,M3N5RDze, & + M3N6RDxe,M3N6RDye,M3N6RDze, & + M3N7RDxe,M3N7RDye,M3N7RDze, & + M3N8RDxe,M3N8RDye,M3N8RDze, & + M3N9RDxe,M3N9RDye,M3N9RDze, & + M4N1RDxe,M4N1RDye,M4N1RDze, & + M4N2RDxe,M4N2RDye,M4N2RDze, & + M4N3RDxe,M4N3RDye,M4N3RDze, & + M4N4RDxe,M4N4RDye,M4N4RDze, & + M4N5RDxe,M4N5RDye,M4N5RDze, & + M4N6RDxe,M4N6RDye,M4N6RDze, & + M4N7RDxe,M4N7RDye,M4N7RDze, & + M4N8RDxe,M4N8RDye,M4N8RDze, & + M4N9RDxe,M4N9RDye,M4N9RDze, & + M5N1RDxe,M5N1RDye,M5N1RDze, & + M5N2RDxe,M5N2RDye,M5N2RDze, & + M5N3RDxe,M5N3RDye,M5N3RDze, & + M5N4RDxe,M5N4RDye,M5N4RDze, & + M5N5RDxe,M5N5RDye,M5N5RDze, & + M5N6RDxe,M5N6RDye,M5N6RDze, & + M5N7RDxe,M5N7RDye,M5N7RDze, & + M5N8RDxe,M5N8RDye,M5N8RDze, & + M5N9RDxe,M5N9RDye,M5N9RDze, & + M6N1RDxe,M6N1RDye,M6N1RDze, & + M6N2RDxe,M6N2RDye,M6N2RDze, & + M6N3RDxe,M6N3RDye,M6N3RDze, & + M6N4RDxe,M6N4RDye,M6N4RDze, & + M6N5RDxe,M6N5RDye,M6N5RDze, & + M6N6RDxe,M6N6RDye,M6N6RDze, & + M6N7RDxe,M6N7RDye,M6N7RDze, & + M6N8RDxe,M6N8RDye,M6N8RDze, & + M6N9RDxe,M6N9RDye,M6N9RDze, & + M7N1RDxe,M7N1RDye,M7N1RDze, & + M7N2RDxe,M7N2RDye,M7N2RDze, & + M7N3RDxe,M7N3RDye,M7N3RDze, & + M7N4RDxe,M7N4RDye,M7N4RDze, & + M7N5RDxe,M7N5RDye,M7N5RDze, & + M7N6RDxe,M7N6RDye,M7N6RDze, & + M7N7RDxe,M7N7RDye,M7N7RDze, & + M7N8RDxe,M7N8RDye,M7N8RDze, & + M7N9RDxe,M7N9RDye,M7N9RDze, & + M8N1RDxe,M8N1RDye,M8N1RDze, & + M8N2RDxe,M8N2RDye,M8N2RDze, & + M8N3RDxe,M8N3RDye,M8N3RDze, & + M8N4RDxe,M8N4RDye,M8N4RDze, & + M8N5RDxe,M8N5RDye,M8N5RDze, & + M8N6RDxe,M8N6RDye,M8N6RDze, & + M8N7RDxe,M8N7RDye,M8N7RDze, & + M8N8RDxe,M8N8RDye,M8N8RDze, & + M8N9RDxe,M8N9RDye,M8N9RDze, & + M9N1RDxe,M9N1RDye,M9N1RDze, & + M9N2RDxe,M9N2RDye,M9N2RDze, & + M9N3RDxe,M9N3RDye,M9N3RDze, & + M9N4RDxe,M9N4RDye,M9N4RDze, & + M9N5RDxe,M9N5RDye,M9N5RDze, & + M9N6RDxe,M9N6RDye,M9N6RDze, & + M9N7RDxe,M9N7RDye,M9N7RDze, & + M9N8RDxe,M9N8RDye,M9N8RDze, & + M9N9RDxe,M9N9RDye,M9N9RDze/), (/3,9,9/)) + + + INTEGER, PARAMETER :: MNTRAe(6,9,9) = reshape( (/M1N1TAxe,M1N1TAye,M1N1TAze,M1N1RAxe,M1N1RAye,M1N1RAze, & + M1N2TAxe,M1N2TAye,M1N2TAze,M1N2RAxe,M1N2RAye,M1N2RAze, & + M1N3TAxe,M1N3TAye,M1N3TAze,M1N3RAxe,M1N3RAye,M1N3RAze, & + M1N4TAxe,M1N4TAye,M1N4TAze,M1N4RAxe,M1N4RAye,M1N4RAze, & + M1N5TAxe,M1N5TAye,M1N5TAze,M1N5RAxe,M1N5RAye,M1N5RAze, & + M1N6TAxe,M1N6TAye,M1N6TAze,M1N6RAxe,M1N6RAye,M1N6RAze, & + M1N7TAxe,M1N7TAye,M1N7TAze,M1N7RAxe,M1N7RAye,M1N7RAze, & + M1N8TAxe,M1N8TAye,M1N8TAze,M1N8RAxe,M1N8RAye,M1N8RAze, & + M1N9TAxe,M1N9TAye,M1N9TAze,M1N9RAxe,M1N9RAye,M1N9RAze, & + M2N1TAxe,M2N1TAye,M2N1TAze,M2N1RAxe,M2N1RAye,M2N1RAze, & + M2N2TAxe,M2N2TAye,M2N2TAze,M2N2RAxe,M2N2RAye,M2N2RAze, & + M2N3TAxe,M2N3TAye,M2N3TAze,M2N3RAxe,M2N3RAye,M2N3RAze, & + M2N4TAxe,M2N4TAye,M2N4TAze,M2N4RAxe,M2N4RAye,M2N4RAze, & + M2N5TAxe,M2N5TAye,M2N5TAze,M2N5RAxe,M2N5RAye,M2N5RAze, & + M2N6TAxe,M2N6TAye,M2N6TAze,M2N6RAxe,M2N6RAye,M2N6RAze, & + M2N7TAxe,M2N7TAye,M2N7TAze,M2N7RAxe,M2N7RAye,M2N7RAze, & + M2N8TAxe,M2N8TAye,M2N8TAze,M2N8RAxe,M2N8RAye,M2N8RAze, & + M2N9TAxe,M2N9TAye,M2N9TAze,M2N9RAxe,M2N9RAye,M2N9RAze, & + M3N1TAxe,M3N1TAye,M3N1TAze,M3N1RAxe,M3N1RAye,M3N1RAze, & + M3N2TAxe,M3N2TAye,M3N2TAze,M3N2RAxe,M3N2RAye,M3N2RAze, & + M3N3TAxe,M3N3TAye,M3N3TAze,M3N3RAxe,M3N3RAye,M3N3RAze, & + M3N4TAxe,M3N4TAye,M3N4TAze,M3N4RAxe,M3N4RAye,M3N4RAze, & + M3N5TAxe,M3N5TAye,M3N5TAze,M3N5RAxe,M3N5RAye,M3N5RAze, & + M3N6TAxe,M3N6TAye,M3N6TAze,M3N6RAxe,M3N6RAye,M3N6RAze, & + M3N7TAxe,M3N7TAye,M3N7TAze,M3N7RAxe,M3N7RAye,M3N7RAze, & + M3N8TAxe,M3N8TAye,M3N8TAze,M3N8RAxe,M3N8RAye,M3N8RAze, & + M3N9TAxe,M3N9TAye,M3N9TAze,M3N9RAxe,M3N9RAye,M3N9RAze, & + M4N1TAxe,M4N1TAye,M4N1TAze,M4N1RAxe,M4N1RAye,M4N1RAze, & + M4N2TAxe,M4N2TAye,M4N2TAze,M4N2RAxe,M4N2RAye,M4N2RAze, & + M4N3TAxe,M4N3TAye,M4N3TAze,M4N3RAxe,M4N3RAye,M4N3RAze, & + M4N4TAxe,M4N4TAye,M4N4TAze,M4N4RAxe,M4N4RAye,M4N4RAze, & + M4N5TAxe,M4N5TAye,M4N5TAze,M4N5RAxe,M4N5RAye,M4N5RAze, & + M4N6TAxe,M4N6TAye,M4N6TAze,M4N6RAxe,M4N6RAye,M4N6RAze, & + M4N7TAxe,M4N7TAye,M4N7TAze,M4N7RAxe,M4N7RAye,M4N7RAze, & + M4N8TAxe,M4N8TAye,M4N8TAze,M4N8RAxe,M4N8RAye,M4N8RAze, & + M4N9TAxe,M4N9TAye,M4N9TAze,M4N9RAxe,M4N9RAye,M4N9RAze, & + M5N1TAxe,M5N1TAye,M5N1TAze,M5N1RAxe,M5N1RAye,M5N1RAze, & + M5N2TAxe,M5N2TAye,M5N2TAze,M5N2RAxe,M5N2RAye,M5N2RAze, & + M5N3TAxe,M5N3TAye,M5N3TAze,M5N3RAxe,M5N3RAye,M5N3RAze, & + M5N4TAxe,M5N4TAye,M5N4TAze,M5N4RAxe,M5N4RAye,M5N4RAze, & + M5N5TAxe,M5N5TAye,M5N5TAze,M5N5RAxe,M5N5RAye,M5N5RAze, & + M5N6TAxe,M5N6TAye,M5N6TAze,M5N6RAxe,M5N6RAye,M5N6RAze, & + M5N7TAxe,M5N7TAye,M5N7TAze,M5N7RAxe,M5N7RAye,M5N7RAze, & + M5N8TAxe,M5N8TAye,M5N8TAze,M5N8RAxe,M5N8RAye,M5N8RAze, & + M5N9TAxe,M5N9TAye,M5N9TAze,M5N9RAxe,M5N9RAye,M5N9RAze, & + M6N1TAxe,M6N1TAye,M6N1TAze,M6N1RAxe,M6N1RAye,M6N1RAze, & + M6N2TAxe,M6N2TAye,M6N2TAze,M6N2RAxe,M6N2RAye,M6N2RAze, & + M6N3TAxe,M6N3TAye,M6N3TAze,M6N3RAxe,M6N3RAye,M6N3RAze, & + M6N4TAxe,M6N4TAye,M6N4TAze,M6N4RAxe,M6N4RAye,M6N4RAze, & + M6N5TAxe,M6N5TAye,M6N5TAze,M6N5RAxe,M6N5RAye,M6N5RAze, & + M6N6TAxe,M6N6TAye,M6N6TAze,M6N6RAxe,M6N6RAye,M6N6RAze, & + M6N7TAxe,M6N7TAye,M6N7TAze,M6N7RAxe,M6N7RAye,M6N7RAze, & + M6N8TAxe,M6N8TAye,M6N8TAze,M6N8RAxe,M6N8RAye,M6N8RAze, & + M6N9TAxe,M6N9TAye,M6N9TAze,M6N9RAxe,M6N9RAye,M6N9RAze, & + M7N1TAxe,M7N1TAye,M7N1TAze,M7N1RAxe,M7N1RAye,M7N1RAze, & + M7N2TAxe,M7N2TAye,M7N2TAze,M7N2RAxe,M7N2RAye,M7N2RAze, & + M7N3TAxe,M7N3TAye,M7N3TAze,M7N3RAxe,M7N3RAye,M7N3RAze, & + M7N4TAxe,M7N4TAye,M7N4TAze,M7N4RAxe,M7N4RAye,M7N4RAze, & + M7N5TAxe,M7N5TAye,M7N5TAze,M7N5RAxe,M7N5RAye,M7N5RAze, & + M7N6TAxe,M7N6TAye,M7N6TAze,M7N6RAxe,M7N6RAye,M7N6RAze, & + M7N7TAxe,M7N7TAye,M7N7TAze,M7N7RAxe,M7N7RAye,M7N7RAze, & + M7N8TAxe,M7N8TAye,M7N8TAze,M7N8RAxe,M7N8RAye,M7N8RAze, & + M7N9TAxe,M7N9TAye,M7N9TAze,M7N9RAxe,M7N9RAye,M7N9RAze, & + M8N1TAxe,M8N1TAye,M8N1TAze,M8N1RAxe,M8N1RAye,M8N1RAze, & + M8N2TAxe,M8N2TAye,M8N2TAze,M8N2RAxe,M8N2RAye,M8N2RAze, & + M8N3TAxe,M8N3TAye,M8N3TAze,M8N3RAxe,M8N3RAye,M8N3RAze, & + M8N4TAxe,M8N4TAye,M8N4TAze,M8N4RAxe,M8N4RAye,M8N4RAze, & + M8N5TAxe,M8N5TAye,M8N5TAze,M8N5RAxe,M8N5RAye,M8N5RAze, & + M8N6TAxe,M8N6TAye,M8N6TAze,M8N6RAxe,M8N6RAye,M8N6RAze, & + M8N7TAxe,M8N7TAye,M8N7TAze,M8N7RAxe,M8N7RAye,M8N7RAze, & + M8N8TAxe,M8N8TAye,M8N8TAze,M8N8RAxe,M8N8RAye,M8N8RAze, & + M8N9TAxe,M8N9TAye,M8N9TAze,M8N9RAxe,M8N9RAye,M8N9RAze, & + M9N1TAxe,M9N1TAye,M9N1TAze,M9N1RAxe,M9N1RAye,M9N1RAze, & + M9N2TAxe,M9N2TAye,M9N2TAze,M9N2RAxe,M9N2RAye,M9N2RAze, & + M9N3TAxe,M9N3TAye,M9N3TAze,M9N3RAxe,M9N3RAye,M9N3RAze, & + M9N4TAxe,M9N4TAye,M9N4TAze,M9N4RAxe,M9N4RAye,M9N4RAze, & + M9N5TAxe,M9N5TAye,M9N5TAze,M9N5RAxe,M9N5RAye,M9N5RAze, & + M9N6TAxe,M9N6TAye,M9N6TAze,M9N6RAxe,M9N6RAye,M9N6RAze, & + M9N7TAxe,M9N7TAye,M9N7TAze,M9N7RAxe,M9N7RAye,M9N7RAze, & + M9N8TAxe,M9N8TAye,M9N8TAze,M9N8RAxe,M9N8RAye,M9N8RAze, & + M9N9TAxe,M9N9TAye,M9N9TAze,M9N9RAxe,M9N9RAye,M9N9RAze/), (/6,9,9/)) + + INTEGER, PARAMETER :: ReactSS(6) = (/ReactFXss, ReactFYss, ReactFZss , & + ReactMXss, ReactMYss, ReactMZss/) + + INTEGER, PARAMETER :: IntfSS(6) = (/IntfFXss, IntfFYss, IntfFZss , & + IntfMXss, IntfMYss, IntfMZss/) + + + INTEGER, PARAMETER :: IntfTRss(6) = (/IntfTDXss, IntfTDYss, IntfTDZss , & + IntfRDXss, IntfRDYss, IntfRDZss/) + + INTEGER, PARAMETER :: IntfTRAss(6) = (/IntfTAXss, IntfTAYss, IntfTAZss , & + IntfRAXss, IntfRAYss, IntfRAZss/) + + + + + + + + CHARACTER(10), PARAMETER :: ValidParamAry(2265) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "INTFFXSS ","INTFFYSS ","INTFFZSS ","INTFMXSS ","INTFMYSS ","INTFMZSS ","INTFRAXSS", & + "INTFRAYSS","INTFRAZSS","INTFRDXSS","INTFRDYSS","INTFRDZSS","INTFTAXSS","INTFTAYSS", & + "INTFTAZSS","INTFTDXSS","INTFTDYSS","INTFTDZSS","M1N1FKXE ","M1N1FKYE ","M1N1FKZE ", & + "M1N1FMXE ","M1N1FMYE ","M1N1FMZE ","M1N1MKXE ","M1N1MKYE ","M1N1MKZE ","M1N1MMXE ", & + "M1N1MMYE ","M1N1MMZE ","M1N1RAXE ","M1N1RAYE ","M1N1RAZE ","M1N1RDXE ","M1N1RDYE ", & + "M1N1RDZE ","M1N1TAXE ","M1N1TAYE ","M1N1TAZE ","M1N1TDXSS","M1N1TDYSS","M1N1TDZSS", & + "M1N2FKXE ","M1N2FKYE ","M1N2FKZE ","M1N2FMXE ","M1N2FMYE ","M1N2FMZE ","M1N2MKXE ", & + "M1N2MKYE ","M1N2MKZE ","M1N2MMXE ","M1N2MMYE ","M1N2MMZE ","M1N2RAXE ","M1N2RAYE ", & + "M1N2RAZE ","M1N2RDXE ","M1N2RDYE ","M1N2RDZE ","M1N2TAXE ","M1N2TAYE ","M1N2TAZE ", & + "M1N2TDXSS","M1N2TDYSS","M1N2TDZSS","M1N3FKXE ","M1N3FKYE ","M1N3FKZE ","M1N3FMXE ", & + "M1N3FMYE ","M1N3FMZE ","M1N3MKXE ","M1N3MKYE ","M1N3MKZE ","M1N3MMXE ","M1N3MMYE ", & + "M1N3MMZE ","M1N3RAXE ","M1N3RAYE ","M1N3RAZE ","M1N3RDXE ","M1N3RDYE ","M1N3RDZE ", & + "M1N3TAXE ","M1N3TAYE ","M1N3TAZE ","M1N3TDXSS","M1N3TDYSS","M1N3TDZSS","M1N4FKXE ", & + "M1N4FKYE ","M1N4FKZE ","M1N4FMXE ","M1N4FMYE ","M1N4FMZE ","M1N4MKXE ","M1N4MKYE ", & + "M1N4MKZE ","M1N4MMXE ","M1N4MMYE ","M1N4MMZE ","M1N4RAXE ","M1N4RAYE ","M1N4RAZE ", & + "M1N4RDXE ","M1N4RDYE ","M1N4RDZE ","M1N4TAXE ","M1N4TAYE ","M1N4TAZE ","M1N4TDXSS", & + "M1N4TDYSS","M1N4TDZSS","M1N5FKXE ","M1N5FKYE ","M1N5FKZE ","M1N5FMXE ","M1N5FMYE ", & + "M1N5FMZE ","M1N5MKXE ","M1N5MKYE ","M1N5MKZE ","M1N5MMXE ","M1N5MMYE ","M1N5MMZE ", & + "M1N5RAXE ","M1N5RAYE ","M1N5RAZE ","M1N5RDXE ","M1N5RDYE ","M1N5RDZE ","M1N5TAXE ", & + "M1N5TAYE ","M1N5TAZE ","M1N5TDXSS","M1N5TDYSS","M1N5TDZSS","M1N6FKXE ","M1N6FKYE ", & + "M1N6FKZE ","M1N6FMXE ","M1N6FMYE ","M1N6FMZE ","M1N6MKXE ","M1N6MKYE ","M1N6MKZE ", & + "M1N6MMXE ","M1N6MMYE ","M1N6MMZE ","M1N6RAXE ","M1N6RAYE ","M1N6RAZE ","M1N6RDXE ", & + "M1N6RDYE ","M1N6RDZE ","M1N6TAXE ","M1N6TAYE ","M1N6TAZE ","M1N6TDXSS","M1N6TDYSS", & + "M1N6TDZSS","M1N7FKXE ","M1N7FKYE ","M1N7FKZE ","M1N7FMXE ","M1N7FMYE ","M1N7FMZE ", & + "M1N7MKXE ","M1N7MKYE ","M1N7MKZE ","M1N7MMXE ","M1N7MMYE ","M1N7MMZE ","M1N7RAXE ", & + "M1N7RAYE ","M1N7RAZE ","M1N7RDXE ","M1N7RDYE ","M1N7RDZE ","M1N7TAXE ","M1N7TAYE ", & + "M1N7TAZE ","M1N7TDXSS","M1N7TDYSS","M1N7TDZSS","M1N8FKXE ","M1N8FKYE ","M1N8FKZE ", & + "M1N8FMXE ","M1N8FMYE ","M1N8FMZE ","M1N8MKXE ","M1N8MKYE ","M1N8MKZE ","M1N8MMXE ", & + "M1N8MMYE ","M1N8MMZE ","M1N8RAXE ","M1N8RAYE ","M1N8RAZE ","M1N8RDXE ","M1N8RDYE ", & + "M1N8RDZE ","M1N8TAXE ","M1N8TAYE ","M1N8TAZE ","M1N8TDXSS","M1N8TDYSS","M1N8TDZSS", & + "M1N9FKXE ","M1N9FKYE ","M1N9FKZE ","M1N9FMXE ","M1N9FMYE ","M1N9FMZE ","M1N9MKXE ", & + "M1N9MKYE ","M1N9MKZE ","M1N9MMXE ","M1N9MMYE ","M1N9MMZE ","M1N9RAXE ","M1N9RAYE ", & + "M1N9RAZE ","M1N9RDXE ","M1N9RDYE ","M1N9RDZE ","M1N9TAXE ","M1N9TAYE ","M1N9TAZE ", & + "M1N9TDXSS","M1N9TDYSS","M1N9TDZSS","M2N1FKXE ","M2N1FKYE ","M2N1FKZE ","M2N1FMXE ", & + "M2N1FMYE ","M2N1FMZE ","M2N1MKXE ","M2N1MKYE ","M2N1MKZE ","M2N1MMXE ","M2N1MMYE ", & + "M2N1MMZE ","M2N1RAXE ","M2N1RAYE ","M2N1RAZE ","M2N1RDXE ","M2N1RDYE ","M2N1RDZE ", & + "M2N1TAXE ","M2N1TAYE ","M2N1TAZE ","M2N1TDXSS","M2N1TDYSS","M2N1TDZSS","M2N2FKXE ", & + "M2N2FKYE ","M2N2FKZE ","M2N2FMXE ","M2N2FMYE ","M2N2FMZE ","M2N2MKXE ","M2N2MKYE ", & + "M2N2MKZE ","M2N2MMXE ","M2N2MMYE ","M2N2MMZE ","M2N2RAXE ","M2N2RAYE ","M2N2RAZE ", & + "M2N2RDXE ","M2N2RDYE ","M2N2RDZE ","M2N2TAXE ","M2N2TAYE ","M2N2TAZE ","M2N2TDXSS", & + "M2N2TDYSS","M2N2TDZSS","M2N3FKXE ","M2N3FKYE ","M2N3FKZE ","M2N3FMXE ","M2N3FMYE ", & + "M2N3FMZE ","M2N3MKXE ","M2N3MKYE ","M2N3MKZE ","M2N3MMXE ","M2N3MMYE ","M2N3MMZE ", & + "M2N3RAXE ","M2N3RAYE ","M2N3RAZE ","M2N3RDXE ","M2N3RDYE ","M2N3RDZE ","M2N3TAXE ", & + "M2N3TAYE ","M2N3TAZE ","M2N3TDXSS","M2N3TDYSS","M2N3TDZSS","M2N4FKXE ","M2N4FKYE ", & + "M2N4FKZE ","M2N4FMXE ","M2N4FMYE ","M2N4FMZE ","M2N4MKXE ","M2N4MKYE ","M2N4MKZE ", & + "M2N4MMXE ","M2N4MMYE ","M2N4MMZE ","M2N4RAXE ","M2N4RAYE ","M2N4RAZE ","M2N4RDXE ", & + "M2N4RDYE ","M2N4RDZE ","M2N4TAXE ","M2N4TAYE ","M2N4TAZE ","M2N4TDXSS","M2N4TDYSS", & + "M2N4TDZSS","M2N5FKXE ","M2N5FKYE ","M2N5FKZE ","M2N5FMXE ","M2N5FMYE ","M2N5FMZE ", & + "M2N5MKXE ","M2N5MKYE ","M2N5MKZE ","M2N5MMXE ","M2N5MMYE ","M2N5MMZE ","M2N5RAXE ", & + "M2N5RAYE ","M2N5RAZE ","M2N5RDXE ","M2N5RDYE ","M2N5RDZE ","M2N5TAXE ","M2N5TAYE ", & + "M2N5TAZE ","M2N5TDXSS","M2N5TDYSS","M2N5TDZSS","M2N6FKXE ","M2N6FKYE ","M2N6FKZE ", & + "M2N6FMXE ","M2N6FMYE ","M2N6FMZE ","M2N6MKXE ","M2N6MKYE ","M2N6MKZE ","M2N6MMXE ", & + "M2N6MMYE ","M2N6MMZE ","M2N6RAXE ","M2N6RAYE ","M2N6RAZE ","M2N6RDXE ","M2N6RDYE ", & + "M2N6RDZE ","M2N6TAXE ","M2N6TAYE ","M2N6TAZE ","M2N6TDXSS","M2N6TDYSS","M2N6TDZSS", & + "M2N7FKXE ","M2N7FKYE ","M2N7FKZE ","M2N7FMXE ","M2N7FMYE ","M2N7FMZE ","M2N7MKXE ", & + "M2N7MKYE ","M2N7MKZE ","M2N7MMXE ","M2N7MMYE ","M2N7MMZE ","M2N7RAXE ","M2N7RAYE ", & + "M2N7RAZE ","M2N7RDXE ","M2N7RDYE ","M2N7RDZE ","M2N7TAXE ","M2N7TAYE ","M2N7TAZE ", & + "M2N7TDXSS","M2N7TDYSS","M2N7TDZSS","M2N8FKXE ","M2N8FKYE ","M2N8FKZE ","M2N8FMXE ", & + "M2N8FMYE ","M2N8FMZE ","M2N8MKXE ","M2N8MKYE ","M2N8MKZE ","M2N8MMXE ","M2N8MMYE ", & + "M2N8MMZE ","M2N8RAXE ","M2N8RAYE ","M2N8RAZE ","M2N8RDXE ","M2N8RDYE ","M2N8RDZE ", & + "M2N8TAXE ","M2N8TAYE ","M2N8TAZE ","M2N8TDXSS","M2N8TDYSS","M2N8TDZSS","M2N9FKXE ", & + "M2N9FKYE ","M2N9FKZE ","M2N9FMXE ","M2N9FMYE ","M2N9FMZE ","M2N9MKXE ","M2N9MKYE ", & + "M2N9MKZE ","M2N9MMXE ","M2N9MMYE ","M2N9MMZE ","M2N9RAXE ","M2N9RAYE ","M2N9RAZE ", & + "M2N9RDXE ","M2N9RDYE ","M2N9RDZE ","M2N9TAXE ","M2N9TAYE ","M2N9TAZE ","M2N9TDXSS", & + "M2N9TDYSS","M2N9TDZSS","M3N1FKXE ","M3N1FKYE ","M3N1FKZE ","M3N1FMXE ","M3N1FMYE ", & + "M3N1FMZE ","M3N1MKXE ","M3N1MKYE ","M3N1MKZE ","M3N1MMXE ","M3N1MMYE ","M3N1MMZE ", & + "M3N1RAXE ","M3N1RAYE ","M3N1RAZE ","M3N1RDXE ","M3N1RDYE ","M3N1RDZE ","M3N1TAXE ", & + "M3N1TAYE ","M3N1TAZE ","M3N1TDXSS","M3N1TDYSS","M3N1TDZSS","M3N2FKXE ","M3N2FKYE ", & + "M3N2FKZE ","M3N2FMXE ","M3N2FMYE ","M3N2FMZE ","M3N2MKXE ","M3N2MKYE ","M3N2MKZE ", & + "M3N2MMXE ","M3N2MMYE ","M3N2MMZE ","M3N2RAXE ","M3N2RAYE ","M3N2RAZE ","M3N2RDXE ", & + "M3N2RDYE ","M3N2RDZE ","M3N2TAXE ","M3N2TAYE ","M3N2TAZE ","M3N2TDXSS","M3N2TDYSS", & + "M3N2TDZSS","M3N3FKXE ","M3N3FKYE ","M3N3FKZE ","M3N3FMXE ","M3N3FMYE ","M3N3FMZE ", & + "M3N3MKXE ","M3N3MKYE ","M3N3MKZE ","M3N3MMXE ","M3N3MMYE ","M3N3MMZE ","M3N3RAXE ", & + "M3N3RAYE ","M3N3RAZE ","M3N3RDXE ","M3N3RDYE ","M3N3RDZE ","M3N3TAXE ","M3N3TAYE ", & + "M3N3TAZE ","M3N3TDXSS","M3N3TDYSS","M3N3TDZSS","M3N4FKXE ","M3N4FKYE ","M3N4FKZE ", & + "M3N4FMXE ","M3N4FMYE ","M3N4FMZE ","M3N4MKXE ","M3N4MKYE ","M3N4MKZE ","M3N4MMXE ", & + "M3N4MMYE ","M3N4MMZE ","M3N4RAXE ","M3N4RAYE ","M3N4RAZE ","M3N4RDXE ","M3N4RDYE ", & + "M3N4RDZE ","M3N4TAXE ","M3N4TAYE ","M3N4TAZE ","M3N4TDXSS","M3N4TDYSS","M3N4TDZSS", & + "M3N5FKXE ","M3N5FKYE ","M3N5FKZE ","M3N5FMXE ","M3N5FMYE ","M3N5FMZE ","M3N5MKXE ", & + "M3N5MKYE ","M3N5MKZE ","M3N5MMXE ","M3N5MMYE ","M3N5MMZE ","M3N5RAXE ","M3N5RAYE ", & + "M3N5RAZE ","M3N5RDXE ","M3N5RDYE ","M3N5RDZE ","M3N5TAXE ","M3N5TAYE ","M3N5TAZE ", & + "M3N5TDXSS","M3N5TDYSS","M3N5TDZSS","M3N6FKXE ","M3N6FKYE ","M3N6FKZE ","M3N6FMXE ", & + "M3N6FMYE ","M3N6FMZE ","M3N6MKXE ","M3N6MKYE ","M3N6MKZE ","M3N6MMXE ","M3N6MMYE ", & + "M3N6MMZE ","M3N6RAXE ","M3N6RAYE ","M3N6RAZE ","M3N6RDXE ","M3N6RDYE ","M3N6RDZE ", & + "M3N6TAXE ","M3N6TAYE ","M3N6TAZE ","M3N6TDXSS","M3N6TDYSS","M3N6TDZSS","M3N7FKXE ", & + "M3N7FKYE ","M3N7FKZE ","M3N7FMXE ","M3N7FMYE ","M3N7FMZE ","M3N7MKXE ","M3N7MKYE ", & + "M3N7MKZE ","M3N7MMXE ","M3N7MMYE ","M3N7MMZE ","M3N7RAXE ","M3N7RAYE ","M3N7RAZE ", & + "M3N7RDXE ","M3N7RDYE ","M3N7RDZE ","M3N7TAXE ","M3N7TAYE ","M3N7TAZE ","M3N7TDXSS", & + "M3N7TDYSS","M3N7TDZSS","M3N8FKXE ","M3N8FKYE ","M3N8FKZE ","M3N8FMXE ","M3N8FMYE ", & + "M3N8FMZE ","M3N8MKXE ","M3N8MKYE ","M3N8MKZE ","M3N8MMXE ","M3N8MMYE ","M3N8MMZE ", & + "M3N8RAXE ","M3N8RAYE ","M3N8RAZE ","M3N8RDXE ","M3N8RDYE ","M3N8RDZE ","M3N8TAXE ", & + "M3N8TAYE ","M3N8TAZE ","M3N8TDXSS","M3N8TDYSS","M3N8TDZSS","M3N9FKXE ","M3N9FKYE ", & + "M3N9FKZE ","M3N9FMXE ","M3N9FMYE ","M3N9FMZE ","M3N9MKXE ","M3N9MKYE ","M3N9MKZE ", & + "M3N9MMXE ","M3N9MMYE ","M3N9MMZE ","M3N9RAXE ","M3N9RAYE ","M3N9RAZE ","M3N9RDXE ", & + "M3N9RDYE ","M3N9RDZE ","M3N9TAXE ","M3N9TAYE ","M3N9TAZE ","M3N9TDXSS","M3N9TDYSS", & + "M3N9TDZSS","M4N1FKXE ","M4N1FKYE ","M4N1FKZE ","M4N1FMXE ","M4N1FMYE ","M4N1FMZE ", & + "M4N1MKXE ","M4N1MKYE ","M4N1MKZE ","M4N1MMXE ","M4N1MMYE ","M4N1MMZE ","M4N1RAXE ", & + "M4N1RAYE ","M4N1RAZE ","M4N1RDXE ","M4N1RDYE ","M4N1RDZE ","M4N1TAXE ","M4N1TAYE ", & + "M4N1TAZE ","M4N1TDXSS","M4N1TDYSS","M4N1TDZSS","M4N2FKXE ","M4N2FKYE ","M4N2FKZE ", & + "M4N2FMXE ","M4N2FMYE ","M4N2FMZE ","M4N2MKXE ","M4N2MKYE ","M4N2MKZE ","M4N2MMXE ", & + "M4N2MMYE ","M4N2MMZE ","M4N2RAXE ","M4N2RAYE ","M4N2RAZE ","M4N2RDXE ","M4N2RDYE ", & + "M4N2RDZE ","M4N2TAXE ","M4N2TAYE ","M4N2TAZE ","M4N2TDXSS","M4N2TDYSS","M4N2TDZSS", & + "M4N3FKXE ","M4N3FKYE ","M4N3FKZE ","M4N3FMXE ","M4N3FMYE ","M4N3FMZE ","M4N3MKXE ", & + "M4N3MKYE ","M4N3MKZE ","M4N3MMXE ","M4N3MMYE ","M4N3MMZE ","M4N3RAXE ","M4N3RAYE ", & + "M4N3RAZE ","M4N3RDXE ","M4N3RDYE ","M4N3RDZE ","M4N3TAXE ","M4N3TAYE ","M4N3TAZE ", & + "M4N3TDXSS","M4N3TDYSS","M4N3TDZSS","M4N4FKXE ","M4N4FKYE ","M4N4FKZE ","M4N4FMXE ", & + "M4N4FMYE ","M4N4FMZE ","M4N4MKXE ","M4N4MKYE ","M4N4MKZE ","M4N4MMXE ","M4N4MMYE ", & + "M4N4MMZE ","M4N4RAXE ","M4N4RAYE ","M4N4RAZE ","M4N4RDXE ","M4N4RDYE ","M4N4RDZE ", & + "M4N4TAXE ","M4N4TAYE ","M4N4TAZE ","M4N4TDXSS","M4N4TDYSS","M4N4TDZSS","M4N5FKXE ", & + "M4N5FKYE ","M4N5FKZE ","M4N5FMXE ","M4N5FMYE ","M4N5FMZE ","M4N5MKXE ","M4N5MKYE ", & + "M4N5MKZE ","M4N5MMXE ","M4N5MMYE ","M4N5MMZE ","M4N5RAXE ","M4N5RAYE ","M4N5RAZE ", & + "M4N5RDXE ","M4N5RDYE ","M4N5RDZE ","M4N5TAXE ","M4N5TAYE ","M4N5TAZE ","M4N5TDXSS", & + "M4N5TDYSS","M4N5TDZSS","M4N6FKXE ","M4N6FKYE ","M4N6FKZE ","M4N6FMXE ","M4N6FMYE ", & + "M4N6FMZE ","M4N6MKXE ","M4N6MKYE ","M4N6MKZE ","M4N6MMXE ","M4N6MMYE ","M4N6MMZE ", & + "M4N6RAXE ","M4N6RAYE ","M4N6RAZE ","M4N6RDXE ","M4N6RDYE ","M4N6RDZE ","M4N6TAXE ", & + "M4N6TAYE ","M4N6TAZE ","M4N6TDXSS","M4N6TDYSS","M4N6TDZSS","M4N7FKXE ","M4N7FKYE ", & + "M4N7FKZE ","M4N7FMXE ","M4N7FMYE ","M4N7FMZE ","M4N7MKXE ","M4N7MKYE ","M4N7MKZE ", & + "M4N7MMXE ","M4N7MMYE ","M4N7MMZE ","M4N7RAXE ","M4N7RAYE ","M4N7RAZE ","M4N7RDXE ", & + "M4N7RDYE ","M4N7RDZE ","M4N7TAXE ","M4N7TAYE ","M4N7TAZE ","M4N7TDXSS","M4N7TDYSS", & + "M4N7TDZSS","M4N8FKXE ","M4N8FKYE ","M4N8FKZE ","M4N8FMXE ","M4N8FMYE ","M4N8FMZE ", & + "M4N8MKXE ","M4N8MKYE ","M4N8MKZE ","M4N8MMXE ","M4N8MMYE ","M4N8MMZE ","M4N8RAXE ", & + "M4N8RAYE ","M4N8RAZE ","M4N8RDXE ","M4N8RDYE ","M4N8RDZE ","M4N8TAXE ","M4N8TAYE ", & + "M4N8TAZE ","M4N8TDXSS","M4N8TDYSS","M4N8TDZSS","M4N9FKXE ","M4N9FKYE ","M4N9FKZE ", & + "M4N9FMXE ","M4N9FMYE ","M4N9FMZE ","M4N9MKXE ","M4N9MKYE ","M4N9MKZE ","M4N9MMXE ", & + "M4N9MMYE ","M4N9MMZE ","M4N9RAXE ","M4N9RAYE ","M4N9RAZE ","M4N9RDXE ","M4N9RDYE ", & + "M4N9RDZE ","M4N9TAXE ","M4N9TAYE ","M4N9TAZE ","M4N9TDXSS","M4N9TDYSS","M4N9TDZSS", & + "M5N1FKXE ","M5N1FKYE ","M5N1FKZE ","M5N1FMXE ","M5N1FMYE ","M5N1FMZE ","M5N1MKXE ", & + "M5N1MKYE ","M5N1MKZE ","M5N1MMXE ","M5N1MMYE ","M5N1MMZE ","M5N1RAXE ","M5N1RAYE ", & + "M5N1RAZE ","M5N1RDXE ","M5N1RDYE ","M5N1RDZE ","M5N1TAXE ","M5N1TAYE ","M5N1TAZE ", & + "M5N1TDXSS","M5N1TDYSS","M5N1TDZSS","M5N2FKXE ","M5N2FKYE ","M5N2FKZE ","M5N2FMXE ", & + "M5N2FMYE ","M5N2FMZE ","M5N2MKXE ","M5N2MKYE ","M5N2MKZE ","M5N2MMXE ","M5N2MMYE ", & + "M5N2MMZE ","M5N2RAXE ","M5N2RAYE ","M5N2RAZE ","M5N2RDXE ","M5N2RDYE ","M5N2RDZE ", & + "M5N2TAXE ","M5N2TAYE ","M5N2TAZE ","M5N2TDXSS","M5N2TDYSS","M5N2TDZSS","M5N3FKXE ", & + "M5N3FKYE ","M5N3FKZE ","M5N3FMXE ","M5N3FMYE ","M5N3FMZE ","M5N3MKXE ","M5N3MKYE ", & + "M5N3MKZE ","M5N3MMXE ","M5N3MMYE ","M5N3MMZE ","M5N3RAXE ","M5N3RAYE ","M5N3RAZE ", & + "M5N3RDXE ","M5N3RDYE ","M5N3RDZE ","M5N3TAXE ","M5N3TAYE ","M5N3TAZE ","M5N3TDXSS", & + "M5N3TDYSS","M5N3TDZSS","M5N4FKXE ","M5N4FKYE ","M5N4FKZE ","M5N4FMXE ","M5N4FMYE ", & + "M5N4FMZE ","M5N4MKXE ","M5N4MKYE ","M5N4MKZE ","M5N4MMXE ","M5N4MMYE ","M5N4MMZE ", & + "M5N4RAXE ","M5N4RAYE ","M5N4RAZE ","M5N4RDXE ","M5N4RDYE ","M5N4RDZE ","M5N4TAXE ", & + "M5N4TAYE ","M5N4TAZE ","M5N4TDXSS","M5N4TDYSS","M5N4TDZSS","M5N5FKXE ","M5N5FKYE ", & + "M5N5FKZE ","M5N5FMXE ","M5N5FMYE ","M5N5FMZE ","M5N5MKXE ","M5N5MKYE ","M5N5MKZE ", & + "M5N5MMXE ","M5N5MMYE ","M5N5MMZE ","M5N5RAXE ","M5N5RAYE ","M5N5RAZE ","M5N5RDXE ", & + "M5N5RDYE ","M5N5RDZE ","M5N5TAXE ","M5N5TAYE ","M5N5TAZE ","M5N5TDXSS","M5N5TDYSS", & + "M5N5TDZSS","M5N6FKXE ","M5N6FKYE ","M5N6FKZE ","M5N6FMXE ","M5N6FMYE ","M5N6FMZE ", & + "M5N6MKXE ","M5N6MKYE ","M5N6MKZE ","M5N6MMXE ","M5N6MMYE ","M5N6MMZE ","M5N6RAXE ", & + "M5N6RAYE ","M5N6RAZE ","M5N6RDXE ","M5N6RDYE ","M5N6RDZE ","M5N6TAXE ","M5N6TAYE ", & + "M5N6TAZE ","M5N6TDXSS","M5N6TDYSS","M5N6TDZSS","M5N7FKXE ","M5N7FKYE ","M5N7FKZE ", & + "M5N7FMXE ","M5N7FMYE ","M5N7FMZE ","M5N7MKXE ","M5N7MKYE ","M5N7MKZE ","M5N7MMXE ", & + "M5N7MMYE ","M5N7MMZE ","M5N7RAXE ","M5N7RAYE ","M5N7RAZE ","M5N7RDXE ","M5N7RDYE ", & + "M5N7RDZE ","M5N7TAXE ","M5N7TAYE ","M5N7TAZE ","M5N7TDXSS","M5N7TDYSS","M5N7TDZSS", & + "M5N8FKXE ","M5N8FKYE ","M5N8FKZE ","M5N8FMXE ","M5N8FMYE ","M5N8FMZE ","M5N8MKXE ", & + "M5N8MKYE ","M5N8MKZE ","M5N8MMXE ","M5N8MMYE ","M5N8MMZE ","M5N8RAXE ","M5N8RAYE ", & + "M5N8RAZE ","M5N8RDXE ","M5N8RDYE ","M5N8RDZE ","M5N8TAXE ","M5N8TAYE ","M5N8TAZE ", & + "M5N8TDXSS","M5N8TDYSS","M5N8TDZSS","M5N9FKXE ","M5N9FKYE ","M5N9FKZE ","M5N9FMXE ", & + "M5N9FMYE ","M5N9FMZE ","M5N9MKXE ","M5N9MKYE ","M5N9MKZE ","M5N9MMXE ","M5N9MMYE ", & + "M5N9MMZE ","M5N9RAXE ","M5N9RAYE ","M5N9RAZE ","M5N9RDXE ","M5N9RDYE ","M5N9RDZE ", & + "M5N9TAXE ","M5N9TAYE ","M5N9TAZE ","M5N9TDXSS","M5N9TDYSS","M5N9TDZSS","M6N1FKXE ", & + "M6N1FKYE ","M6N1FKZE ","M6N1FMXE ","M6N1FMYE ","M6N1FMZE ","M6N1MKXE ","M6N1MKYE ", & + "M6N1MKZE ","M6N1MMXE ","M6N1MMYE ","M6N1MMZE ","M6N1RAXE ","M6N1RAYE ","M6N1RAZE ", & + "M6N1RDXE ","M6N1RDYE ","M6N1RDZE ","M6N1TAXE ","M6N1TAYE ","M6N1TAZE ","M6N1TDXSS", & + "M6N1TDYSS","M6N1TDZSS","M6N2FKXE ","M6N2FKYE ","M6N2FKZE ","M6N2FMXE ","M6N2FMYE ", & + "M6N2FMZE ","M6N2MKXE ","M6N2MKYE ","M6N2MKZE ","M6N2MMXE ","M6N2MMYE ","M6N2MMZE ", & + "M6N2RAXE ","M6N2RAYE ","M6N2RAZE ","M6N2RDXE ","M6N2RDYE ","M6N2RDZE ","M6N2TAXE ", & + "M6N2TAYE ","M6N2TAZE ","M6N2TDXSS","M6N2TDYSS","M6N2TDZSS","M6N3FKXE ","M6N3FKYE ", & + "M6N3FKZE ","M6N3FMXE ","M6N3FMYE ","M6N3FMZE ","M6N3MKXE ","M6N3MKYE ","M6N3MKZE ", & + "M6N3MMXE ","M6N3MMYE ","M6N3MMZE ","M6N3RAXE ","M6N3RAYE ","M6N3RAZE ","M6N3RDXE ", & + "M6N3RDYE ","M6N3RDZE ","M6N3TAXE ","M6N3TAYE ","M6N3TAZE ","M6N3TDXSS","M6N3TDYSS", & + "M6N3TDZSS","M6N4FKXE ","M6N4FKYE ","M6N4FKZE ","M6N4FMXE ","M6N4FMYE ","M6N4FMZE ", & + "M6N4MKXE ","M6N4MKYE ","M6N4MKZE ","M6N4MMXE ","M6N4MMYE ","M6N4MMZE ","M6N4RAXE ", & + "M6N4RAYE ","M6N4RAZE ","M6N4RDXE ","M6N4RDYE ","M6N4RDZE ","M6N4TAXE ","M6N4TAYE ", & + "M6N4TAZE ","M6N4TDXSS","M6N4TDYSS","M6N4TDZSS","M6N5FKXE ","M6N5FKYE ","M6N5FKZE ", & + "M6N5FMXE ","M6N5FMYE ","M6N5FMZE ","M6N5MKXE ","M6N5MKYE ","M6N5MKZE ","M6N5MMXE ", & + "M6N5MMYE ","M6N5MMZE ","M6N5RAXE ","M6N5RAYE ","M6N5RAZE ","M6N5RDXE ","M6N5RDYE ", & + "M6N5RDZE ","M6N5TAXE ","M6N5TAYE ","M6N5TAZE ","M6N5TDXSS","M6N5TDYSS","M6N5TDZSS", & + "M6N6FKXE ","M6N6FKYE ","M6N6FKZE ","M6N6FMXE ","M6N6FMYE ","M6N6FMZE ","M6N6MKXE ", & + "M6N6MKYE ","M6N6MKZE ","M6N6MMXE ","M6N6MMYE ","M6N6MMZE ","M6N6RAXE ","M6N6RAYE ", & + "M6N6RAZE ","M6N6RDXE ","M6N6RDYE ","M6N6RDZE ","M6N6TAXE ","M6N6TAYE ","M6N6TAZE ", & + "M6N6TDXSS","M6N6TDYSS","M6N6TDZSS","M6N7FKXE ","M6N7FKYE ","M6N7FKZE ","M6N7FMXE ", & + "M6N7FMYE ","M6N7FMZE ","M6N7MKXE ","M6N7MKYE ","M6N7MKZE ","M6N7MMXE ","M6N7MMYE ", & + "M6N7MMZE ","M6N7RAXE ","M6N7RAYE ","M6N7RAZE ","M6N7RDXE ","M6N7RDYE ","M6N7RDZE ", & + "M6N7TAXE ","M6N7TAYE ","M6N7TAZE ","M6N7TDXSS","M6N7TDYSS","M6N7TDZSS","M6N8FKXE ", & + "M6N8FKYE ","M6N8FKZE ","M6N8FMXE ","M6N8FMYE ","M6N8FMZE ","M6N8MKXE ","M6N8MKYE ", & + "M6N8MKZE ","M6N8MMXE ","M6N8MMYE ","M6N8MMZE ","M6N8RAXE ","M6N8RAYE ","M6N8RAZE ", & + "M6N8RDXE ","M6N8RDYE ","M6N8RDZE ","M6N8TAXE ","M6N8TAYE ","M6N8TAZE ","M6N8TDXSS", & + "M6N8TDYSS","M6N8TDZSS","M6N9FKXE ","M6N9FKYE ","M6N9FKZE ","M6N9FMXE ","M6N9FMYE ", & + "M6N9FMZE ","M6N9MKXE ","M6N9MKYE ","M6N9MKZE ","M6N9MMXE ","M6N9MMYE ","M6N9MMZE ", & + "M6N9RAXE ","M6N9RAYE ","M6N9RAZE ","M6N9RDXE ","M6N9RDYE ","M6N9RDZE ","M6N9TAXE ", & + "M6N9TAYE ","M6N9TAZE ","M6N9TDXSS","M6N9TDYSS","M6N9TDZSS","M7N1FKXE ","M7N1FKYE ", & + "M7N1FKZE ","M7N1FMXE ","M7N1FMYE ","M7N1FMZE ","M7N1MKXE ","M7N1MKYE ","M7N1MKZE ", & + "M7N1MMXE ","M7N1MMYE ","M7N1MMZE ","M7N1RAXE ","M7N1RAYE ","M7N1RAZE ","M7N1RDXE ", & + "M7N1RDYE ","M7N1RDZE ","M7N1TAXE ","M7N1TAYE ","M7N1TAZE ","M7N1TDXSS","M7N1TDYSS", & + "M7N1TDZSS","M7N2FKXE ","M7N2FKYE ","M7N2FKZE ","M7N2FMXE ","M7N2FMYE ","M7N2FMZE ", & + "M7N2MKXE ","M7N2MKYE ","M7N2MKZE ","M7N2MMXE ","M7N2MMYE ","M7N2MMZE ","M7N2RAXE ", & + "M7N2RAYE ","M7N2RAZE ","M7N2RDXE ","M7N2RDYE ","M7N2RDZE ","M7N2TAXE ","M7N2TAYE ", & + "M7N2TAZE ","M7N2TDXSS","M7N2TDYSS","M7N2TDZSS","M7N3FKXE ","M7N3FKYE ","M7N3FKZE ", & + "M7N3FMXE ","M7N3FMYE ","M7N3FMZE ","M7N3MKXE ","M7N3MKYE ","M7N3MKZE ","M7N3MMXE ", & + "M7N3MMYE ","M7N3MMZE ","M7N3RAXE ","M7N3RAYE ","M7N3RAZE ","M7N3RDXE ","M7N3RDYE ", & + "M7N3RDZE ","M7N3TAXE ","M7N3TAYE ","M7N3TAZE ","M7N3TDXSS","M7N3TDYSS","M7N3TDZSS", & + "M7N4FKXE ","M7N4FKYE ","M7N4FKZE ","M7N4FMXE ","M7N4FMYE ","M7N4FMZE ","M7N4MKXE ", & + "M7N4MKYE ","M7N4MKZE ","M7N4MMXE ","M7N4MMYE ","M7N4MMZE ","M7N4RAXE ","M7N4RAYE ", & + "M7N4RAZE ","M7N4RDXE ","M7N4RDYE ","M7N4RDZE ","M7N4TAXE ","M7N4TAYE ","M7N4TAZE ", & + "M7N4TDXSS","M7N4TDYSS","M7N4TDZSS","M7N5FKXE ","M7N5FKYE ","M7N5FKZE ","M7N5FMXE ", & + "M7N5FMYE ","M7N5FMZE ","M7N5MKXE ","M7N5MKYE ","M7N5MKZE ","M7N5MMXE ","M7N5MMYE ", & + "M7N5MMZE ","M7N5RAXE ","M7N5RAYE ","M7N5RAZE ","M7N5RDXE ","M7N5RDYE ","M7N5RDZE ", & + "M7N5TAXE ","M7N5TAYE ","M7N5TAZE ","M7N5TDXSS","M7N5TDYSS","M7N5TDZSS","M7N6FKXE ", & + "M7N6FKYE ","M7N6FKZE ","M7N6FMXE ","M7N6FMYE ","M7N6FMZE ","M7N6MKXE ","M7N6MKYE ", & + "M7N6MKZE ","M7N6MMXE ","M7N6MMYE ","M7N6MMZE ","M7N6RAXE ","M7N6RAYE ","M7N6RAZE ", & + "M7N6RDXE ","M7N6RDYE ","M7N6RDZE ","M7N6TAXE ","M7N6TAYE ","M7N6TAZE ","M7N6TDXSS", & + "M7N6TDYSS","M7N6TDZSS","M7N7FKXE ","M7N7FKYE ","M7N7FKZE ","M7N7FMXE ","M7N7FMYE ", & + "M7N7FMZE ","M7N7MKXE ","M7N7MKYE ","M7N7MKZE ","M7N7MMXE ","M7N7MMYE ","M7N7MMZE ", & + "M7N7RAXE ","M7N7RAYE ","M7N7RAZE ","M7N7RDXE ","M7N7RDYE ","M7N7RDZE ","M7N7TAXE ", & + "M7N7TAYE ","M7N7TAZE ","M7N7TDXSS","M7N7TDYSS","M7N7TDZSS","M7N8FKXE ","M7N8FKYE ", & + "M7N8FKZE ","M7N8FMXE ","M7N8FMYE ","M7N8FMZE ","M7N8MKXE ","M7N8MKYE ","M7N8MKZE ", & + "M7N8MMXE ","M7N8MMYE ","M7N8MMZE ","M7N8RAXE ","M7N8RAYE ","M7N8RAZE ","M7N8RDXE ", & + "M7N8RDYE ","M7N8RDZE ","M7N8TAXE ","M7N8TAYE ","M7N8TAZE ","M7N8TDXSS","M7N8TDYSS", & + "M7N8TDZSS","M7N9FKXE ","M7N9FKYE ","M7N9FKZE ","M7N9FMXE ","M7N9FMYE ","M7N9FMZE ", & + "M7N9MKXE ","M7N9MKYE ","M7N9MKZE ","M7N9MMXE ","M7N9MMYE ","M7N9MMZE ","M7N9RAXE ", & + "M7N9RAYE ","M7N9RAZE ","M7N9RDXE ","M7N9RDYE ","M7N9RDZE ","M7N9TAXE ","M7N9TAYE ", & + "M7N9TAZE ","M7N9TDXSS","M7N9TDYSS","M7N9TDZSS","M8N1FKXE ","M8N1FKYE ","M8N1FKZE ", & + "M8N1FMXE ","M8N1FMYE ","M8N1FMZE ","M8N1MKXE ","M8N1MKYE ","M8N1MKZE ","M8N1MMXE ", & + "M8N1MMYE ","M8N1MMZE ","M8N1RAXE ","M8N1RAYE ","M8N1RAZE ","M8N1RDXE ","M8N1RDYE ", & + "M8N1RDZE ","M8N1TAXE ","M8N1TAYE ","M8N1TAZE ","M8N1TDXSS","M8N1TDYSS","M8N1TDZSS", & + "M8N2FKXE ","M8N2FKYE ","M8N2FKZE ","M8N2FMXE ","M8N2FMYE ","M8N2FMZE ","M8N2MKXE ", & + "M8N2MKYE ","M8N2MKZE ","M8N2MMXE ","M8N2MMYE ","M8N2MMZE ","M8N2RAXE ","M8N2RAYE ", & + "M8N2RAZE ","M8N2RDXE ","M8N2RDYE ","M8N2RDZE ","M8N2TAXE ","M8N2TAYE ","M8N2TAZE ", & + "M8N2TDXSS","M8N2TDYSS","M8N2TDZSS","M8N3FKXE ","M8N3FKYE ","M8N3FKZE ","M8N3FMXE ", & + "M8N3FMYE ","M8N3FMZE ","M8N3MKXE ","M8N3MKYE ","M8N3MKZE ","M8N3MMXE ","M8N3MMYE ", & + "M8N3MMZE ","M8N3RAXE ","M8N3RAYE ","M8N3RAZE ","M8N3RDXE ","M8N3RDYE ","M8N3RDZE ", & + "M8N3TAXE ","M8N3TAYE ","M8N3TAZE ","M8N3TDXSS","M8N3TDYSS","M8N3TDZSS","M8N4FKXE ", & + "M8N4FKYE ","M8N4FKZE ","M8N4FMXE ","M8N4FMYE ","M8N4FMZE ","M8N4MKXE ","M8N4MKYE ", & + "M8N4MKZE ","M8N4MMXE ","M8N4MMYE ","M8N4MMZE ","M8N4RAXE ","M8N4RAYE ","M8N4RAZE ", & + "M8N4RDXE ","M8N4RDYE ","M8N4RDZE ","M8N4TAXE ","M8N4TAYE ","M8N4TAZE ","M8N4TDXSS", & + "M8N4TDYSS","M8N4TDZSS","M8N5FKXE ","M8N5FKYE ","M8N5FKZE ","M8N5FMXE ","M8N5FMYE ", & + "M8N5FMZE ","M8N5MKXE ","M8N5MKYE ","M8N5MKZE ","M8N5MMXE ","M8N5MMYE ","M8N5MMZE ", & + "M8N5RAXE ","M8N5RAYE ","M8N5RAZE ","M8N5RDXE ","M8N5RDYE ","M8N5RDZE ","M8N5TAXE ", & + "M8N5TAYE ","M8N5TAZE ","M8N5TDXSS","M8N5TDYSS","M8N5TDZSS","M8N6FKXE ","M8N6FKYE ", & + "M8N6FKZE ","M8N6FMXE ","M8N6FMYE ","M8N6FMZE ","M8N6MKXE ","M8N6MKYE ","M8N6MKZE ", & + "M8N6MMXE ","M8N6MMYE ","M8N6MMZE ","M8N6RAXE ","M8N6RAYE ","M8N6RAZE ","M8N6RDXE ", & + "M8N6RDYE ","M8N6RDZE ","M8N6TAXE ","M8N6TAYE ","M8N6TAZE ","M8N6TDXSS","M8N6TDYSS", & + "M8N6TDZSS","M8N7FKXE ","M8N7FKYE ","M8N7FKZE ","M8N7FMXE ","M8N7FMYE ","M8N7FMZE ", & + "M8N7MKXE ","M8N7MKYE ","M8N7MKZE ","M8N7MMXE ","M8N7MMYE ","M8N7MMZE ","M8N7RAXE ", & + "M8N7RAYE ","M8N7RAZE ","M8N7RDXE ","M8N7RDYE ","M8N7RDZE ","M8N7TAXE ","M8N7TAYE ", & + "M8N7TAZE ","M8N7TDXSS","M8N7TDYSS","M8N7TDZSS","M8N8FKXE ","M8N8FKYE ","M8N8FKZE ", & + "M8N8FMXE ","M8N8FMYE ","M8N8FMZE ","M8N8MKXE ","M8N8MKYE ","M8N8MKZE ","M8N8MMXE ", & + "M8N8MMYE ","M8N8MMZE ","M8N8RAXE ","M8N8RAYE ","M8N8RAZE ","M8N8RDXE ","M8N8RDYE ", & + "M8N8RDZE ","M8N8TAXE ","M8N8TAYE ","M8N8TAZE ","M8N8TDXSS","M8N8TDYSS","M8N8TDZSS", & + "M8N9FKXE ","M8N9FKYE ","M8N9FKZE ","M8N9FMXE ","M8N9FMYE ","M8N9FMZE ","M8N9MKXE ", & + "M8N9MKYE ","M8N9MKZE ","M8N9MMXE ","M8N9MMYE ","M8N9MMZE ","M8N9RAXE ","M8N9RAYE ", & + "M8N9RAZE ","M8N9RDXE ","M8N9RDYE ","M8N9RDZE ","M8N9TAXE ","M8N9TAYE ","M8N9TAZE ", & + "M8N9TDXSS","M8N9TDYSS","M8N9TDZSS","M9N1FKXE ","M9N1FKYE ","M9N1FKZE ","M9N1FMXE ", & + "M9N1FMYE ","M9N1FMZE ","M9N1MKXE ","M9N1MKYE ","M9N1MKZE ","M9N1MMXE ","M9N1MMYE ", & + "M9N1MMZE ","M9N1RAXE ","M9N1RAYE ","M9N1RAZE ","M9N1RDXE ","M9N1RDYE ","M9N1RDZE ", & + "M9N1TAXE ","M9N1TAYE ","M9N1TAZE ","M9N1TDXSS","M9N1TDYSS","M9N1TDZSS","M9N2FKXE ", & + "M9N2FKYE ","M9N2FKZE ","M9N2FMXE ","M9N2FMYE ","M9N2FMZE ","M9N2MKXE ","M9N2MKYE ", & + "M9N2MKZE ","M9N2MMXE ","M9N2MMYE ","M9N2MMZE ","M9N2RAXE ","M9N2RAYE ","M9N2RAZE ", & + "M9N2RDXE ","M9N2RDYE ","M9N2RDZE ","M9N2TAXE ","M9N2TAYE ","M9N2TAZE ","M9N2TDXSS", & + "M9N2TDYSS","M9N2TDZSS","M9N3FKXE ","M9N3FKYE ","M9N3FKZE ","M9N3FMXE ","M9N3FMYE ", & + "M9N3FMZE ","M9N3MKXE ","M9N3MKYE ","M9N3MKZE ","M9N3MMXE ","M9N3MMYE ","M9N3MMZE ", & + "M9N3RAXE ","M9N3RAYE ","M9N3RAZE ","M9N3RDXE ","M9N3RDYE ","M9N3RDZE ","M9N3TAXE ", & + "M9N3TAYE ","M9N3TAZE ","M9N3TDXSS","M9N3TDYSS","M9N3TDZSS","M9N4FKXE ","M9N4FKYE ", & + "M9N4FKZE ","M9N4FMXE ","M9N4FMYE ","M9N4FMZE ","M9N4MKXE ","M9N4MKYE ","M9N4MKZE ", & + "M9N4MMXE ","M9N4MMYE ","M9N4MMZE ","M9N4RAXE ","M9N4RAYE ","M9N4RAZE ","M9N4RDXE ", & + "M9N4RDYE ","M9N4RDZE ","M9N4TAXE ","M9N4TAYE ","M9N4TAZE ","M9N4TDXSS","M9N4TDYSS", & + "M9N4TDZSS","M9N5FKXE ","M9N5FKYE ","M9N5FKZE ","M9N5FMXE ","M9N5FMYE ","M9N5FMZE ", & + "M9N5MKXE ","M9N5MKYE ","M9N5MKZE ","M9N5MMXE ","M9N5MMYE ","M9N5MMZE ","M9N5RAXE ", & + "M9N5RAYE ","M9N5RAZE ","M9N5RDXE ","M9N5RDYE ","M9N5RDZE ","M9N5TAXE ","M9N5TAYE ", & + "M9N5TAZE ","M9N5TDXSS","M9N5TDYSS","M9N5TDZSS","M9N6FKXE ","M9N6FKYE ","M9N6FKZE ", & + "M9N6FMXE ","M9N6FMYE ","M9N6FMZE ","M9N6MKXE ","M9N6MKYE ","M9N6MKZE ","M9N6MMXE ", & + "M9N6MMYE ","M9N6MMZE ","M9N6RAXE ","M9N6RAYE ","M9N6RAZE ","M9N6RDXE ","M9N6RDYE ", & + "M9N6RDZE ","M9N6TAXE ","M9N6TAYE ","M9N6TAZE ","M9N6TDXSS","M9N6TDYSS","M9N6TDZSS", & + "M9N7FKXE ","M9N7FKYE ","M9N7FKZE ","M9N7FMXE ","M9N7FMYE ","M9N7FMZE ","M9N7MKXE ", & + "M9N7MKYE ","M9N7MKZE ","M9N7MMXE ","M9N7MMYE ","M9N7MMZE ","M9N7RAXE ","M9N7RAYE ", & + "M9N7RAZE ","M9N7RDXE ","M9N7RDYE ","M9N7RDZE ","M9N7TAXE ","M9N7TAYE ","M9N7TAZE ", & + "M9N7TDXSS","M9N7TDYSS","M9N7TDZSS","M9N8FKXE ","M9N8FKYE ","M9N8FKZE ","M9N8FMXE ", & + "M9N8FMYE ","M9N8FMZE ","M9N8MKXE ","M9N8MKYE ","M9N8MKZE ","M9N8MMXE ","M9N8MMYE ", & + "M9N8MMZE ","M9N8RAXE ","M9N8RAYE ","M9N8RAZE ","M9N8RDXE ","M9N8RDYE ","M9N8RDZE ", & + "M9N8TAXE ","M9N8TAYE ","M9N8TAZE ","M9N8TDXSS","M9N8TDYSS","M9N8TDZSS","M9N9FKXE ", & + "M9N9FKYE ","M9N9FKZE ","M9N9FMXE ","M9N9FMYE ","M9N9FMZE ","M9N9MKXE ","M9N9MKYE ", & + "M9N9MKZE ","M9N9MMXE ","M9N9MMYE ","M9N9MMZE ","M9N9RAXE ","M9N9RAYE ","M9N9RAZE ", & + "M9N9RDXE ","M9N9RDYE ","M9N9RDZE ","M9N9TAXE ","M9N9TAYE ","M9N9TAZE ","M9N9TDXSS", & + "M9N9TDYSS","M9N9TDZSS","REACTFXSS","REACTFYSS","REACTFZSS","REACTMXSS","REACTMYSS", & + "REACTMZSS","SSQM01 ","SSQM02 ","SSQM03 ","SSQM04 ","SSQM05 ","SSQM06 ", & + "SSQM07 ","SSQM08 ","SSQM09 ","SSQM10 ","SSQM11 ","SSQM12 ","SSQM13 ", & + "SSQM14 ","SSQM15 ","SSQM16 ","SSQM17 ","SSQM18 ","SSQM19 ","SSQM20 ", & + "SSQM21 ","SSQM22 ","SSQM23 ","SSQM24 ","SSQM25 ","SSQM26 ","SSQM27 ", & + "SSQM28 ","SSQM29 ","SSQM30 ","SSQM31 ","SSQM32 ","SSQM33 ","SSQM34 ", & + "SSQM35 ","SSQM36 ","SSQM37 ","SSQM38 ","SSQM39 ","SSQM40 ","SSQM41 ", & + "SSQM42 ","SSQM43 ","SSQM44 ","SSQM45 ","SSQM46 ","SSQM47 ","SSQM48 ", & + "SSQM49 ","SSQM50 ","SSQM51 ","SSQM52 ","SSQM53 ","SSQM54 ","SSQM55 ", & + "SSQM56 ","SSQM57 ","SSQM58 ","SSQM59 ","SSQM60 ","SSQM61 ","SSQM62 ", & + "SSQM63 ","SSQM64 ","SSQM65 ","SSQM66 ","SSQM67 ","SSQM68 ","SSQM69 ", & + "SSQM70 ","SSQM71 ","SSQM72 ","SSQM73 ","SSQM74 ","SSQM75 ","SSQM76 ", & + "SSQM77 ","SSQM78 ","SSQM79 ","SSQM80 ","SSQM81 ","SSQM82 ","SSQM83 ", & + "SSQM84 ","SSQM85 ","SSQM86 ","SSQM87 ","SSQM88 ","SSQM89 ","SSQM90 ", & + "SSQM91 ","SSQM92 ","SSQM93 ","SSQM94 ","SSQM95 ","SSQM96 ","SSQM97 ", & + "SSQM98 ","SSQM99 ","SSQMD01 ","SSQMD02 ","SSQMD03 ","SSQMD04 ","SSQMD05 ", & + "SSQMD06 ","SSQMD07 ","SSQMD08 ","SSQMD09 ","SSQMD10 ","SSQMD11 ","SSQMD12 ", & + "SSQMD13 ","SSQMD14 ","SSQMD15 ","SSQMD16 ","SSQMD17 ","SSQMD18 ","SSQMD19 ", & + "SSQMD20 ","SSQMD21 ","SSQMD22 ","SSQMD23 ","SSQMD24 ","SSQMD25 ","SSQMD26 ", & + "SSQMD27 ","SSQMD28 ","SSQMD29 ","SSQMD30 ","SSQMD31 ","SSQMD32 ","SSQMD33 ", & + "SSQMD34 ","SSQMD35 ","SSQMD36 ","SSQMD37 ","SSQMD38 ","SSQMD39 ","SSQMD40 ", & + "SSQMD41 ","SSQMD42 ","SSQMD43 ","SSQMD44 ","SSQMD45 ","SSQMD46 ","SSQMD47 ", & + "SSQMD48 ","SSQMD49 ","SSQMD50 ","SSQMD51 ","SSQMD52 ","SSQMD53 ","SSQMD54 ", & + "SSQMD55 ","SSQMD56 ","SSQMD57 ","SSQMD58 ","SSQMD59 ","SSQMD60 ","SSQMD61 ", & + "SSQMD62 ","SSQMD63 ","SSQMD64 ","SSQMD65 ","SSQMD66 ","SSQMD67 ","SSQMD68 ", & + "SSQMD69 ","SSQMD70 ","SSQMD71 ","SSQMD72 ","SSQMD73 ","SSQMD74 ","SSQMD75 ", & + "SSQMD76 ","SSQMD77 ","SSQMD78 ","SSQMD79 ","SSQMD80 ","SSQMD81 ","SSQMD82 ", & + "SSQMD83 ","SSQMD84 ","SSQMD85 ","SSQMD86 ","SSQMD87 ","SSQMD88 ","SSQMD89 ", & + "SSQMD90 ","SSQMD91 ","SSQMD92 ","SSQMD93 ","SSQMD94 ","SSQMD95 ","SSQMD96 ", & + "SSQMD97 ","SSQMD98 ","SSQMD99 ","SSQMDD01 ","SSQMDD02 ","SSQMDD03 ","SSQMDD04 ", & + "SSQMDD05 ","SSQMDD06 ","SSQMDD07 ","SSQMDD08 ","SSQMDD09 ","SSQMDD10 ","SSQMDD11 ", & + "SSQMDD12 ","SSQMDD13 ","SSQMDD14 ","SSQMDD15 ","SSQMDD16 ","SSQMDD17 ","SSQMDD18 ", & + "SSQMDD19 ","SSQMDD20 ","SSQMDD21 ","SSQMDD22 ","SSQMDD23 ","SSQMDD24 ","SSQMDD25 ", & + "SSQMDD26 ","SSQMDD27 ","SSQMDD28 ","SSQMDD29 ","SSQMDD30 ","SSQMDD31 ","SSQMDD32 ", & + "SSQMDD33 ","SSQMDD34 ","SSQMDD35 ","SSQMDD36 ","SSQMDD37 ","SSQMDD38 ","SSQMDD39 ", & + "SSQMDD40 ","SSQMDD41 ","SSQMDD42 ","SSQMDD43 ","SSQMDD44 ","SSQMDD45 ","SSQMDD46 ", & + "SSQMDD47 ","SSQMDD48 ","SSQMDD49 ","SSQMDD50 ","SSQMDD51 ","SSQMDD52 ","SSQMDD53 ", & + "SSQMDD54 ","SSQMDD55 ","SSQMDD56 ","SSQMDD57 ","SSQMDD58 ","SSQMDD59 ","SSQMDD60 ", & + "SSQMDD61 ","SSQMDD62 ","SSQMDD63 ","SSQMDD64 ","SSQMDD65 ","SSQMDD66 ","SSQMDD67 ", & + "SSQMDD68 ","SSQMDD69 ","SSQMDD70 ","SSQMDD71 ","SSQMDD72 ","SSQMDD73 ","SSQMDD74 ", & + "SSQMDD75 ","SSQMDD76 ","SSQMDD77 ","SSQMDD78 ","SSQMDD79 ","SSQMDD80 ","SSQMDD81 ", & + "SSQMDD82 ","SSQMDD83 ","SSQMDD84 ","SSQMDD85 ","SSQMDD86 ","SSQMDD87 ","SSQMDD88 ", & + "SSQMDD89 ","SSQMDD90 ","SSQMDD91 ","SSQMDD92 ","SSQMDD93 ","SSQMDD94 ","SSQMDD95 ", & + "SSQMDD96 ","SSQMDD97 ","SSQMDD98 ","SSQMDD99 "/) + INTEGER(IntKi), PARAMETER :: ParamIndxAry(2265) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + IntfFXss , IntfFYss , IntfFZss , IntfMXss , IntfMYss , IntfMZss , IntfRAXss , & + IntfRAYss , IntfRAZss , IntfRDXss , IntfRDYss , IntfRDZss , IntfTAXss , IntfTAYss , & + IntfTAZss , IntfTDXss , IntfTDYss , IntfTDZss , M1N1FKxe , M1N1FKye , M1N1FKze , & + M1N1FMxe , M1N1FMye , M1N1FMze , M1N1MKxe , M1N1MKye , M1N1MKze , M1N1MMxe , & + M1N1MMye , M1N1MMze , M1N1RAxe , M1N1RAye , M1N1RAze , M1N1RDxe , M1N1RDye , & + M1N1RDze , M1N1TAxe , M1N1TAye , M1N1TAze , M1N1TDxss , M1N1TDyss , M1N1TDzss , & + M1N2FKxe , M1N2FKye , M1N2FKze , M1N2FMxe , M1N2FMye , M1N2FMze , M1N2MKxe , & + M1N2MKye , M1N2MKze , M1N2MMxe , M1N2MMye , M1N2MMze , M1N2RAxe , M1N2RAye , & + M1N2RAze , M1N2RDxe , M1N2RDye , M1N2RDze , M1N2TAxe , M1N2TAye , M1N2TAze , & + M1N2TDxss , M1N2TDyss , M1N2TDzss , M1N3FKxe , M1N3FKye , M1N3FKze , M1N3FMxe , & + M1N3FMye , M1N3FMze , M1N3MKxe , M1N3MKye , M1N3MKze , M1N3MMxe , M1N3MMye , & + M1N3MMze , M1N3RAxe , M1N3RAye , M1N3RAze , M1N3RDxe , M1N3RDye , M1N3RDze , & + M1N3TAxe , M1N3TAye , M1N3TAze , M1N3TDxss , M1N3TDyss , M1N3TDzss , M1N4FKxe , & + M1N4FKye , M1N4FKze , M1N4FMxe , M1N4FMye , M1N4FMze , M1N4MKxe , M1N4MKye , & + M1N4MKze , M1N4MMxe , M1N4MMye , M1N4MMze , M1N4RAxe , M1N4RAye , M1N4RAze , & + M1N4RDxe , M1N4RDye , M1N4RDze , M1N4TAxe , M1N4TAye , M1N4TAze , M1N4TDxss , & + M1N4TDyss , M1N4TDzss , M1N5FKxe , M1N5FKye , M1N5FKze , M1N5FMxe , M1N5FMye , & + M1N5FMze , M1N5MKxe , M1N5MKye , M1N5MKze , M1N5MMxe , M1N5MMye , M1N5MMze , & + M1N5RAxe , M1N5RAye , M1N5RAze , M1N5RDxe , M1N5RDye , M1N5RDze , M1N5TAxe , & + M1N5TAye , M1N5TAze , M1N5TDxss , M1N5TDyss , M1N5TDzss , M1N6FKxe , M1N6FKye , & + M1N6FKze , M1N6FMxe , M1N6FMye , M1N6FMze , M1N6MKxe , M1N6MKye , M1N6MKze , & + M1N6MMxe , M1N6MMye , M1N6MMze , M1N6RAxe , M1N6RAye , M1N6RAze , M1N6RDxe , & + M1N6RDye , M1N6RDze , M1N6TAxe , M1N6TAye , M1N6TAze , M1N6TDxss , M1N6TDyss , & + M1N6TDzss , M1N7FKxe , M1N7FKye , M1N7FKze , M1N7FMxe , M1N7FMye , M1N7FMze , & + M1N7MKxe , M1N7MKye , M1N7MKze , M1N7MMxe , M1N7MMye , M1N7MMze , M1N7RAxe , & + M1N7RAye , M1N7RAze , M1N7RDxe , M1N7RDye , M1N7RDze , M1N7TAxe , M1N7TAye , & + M1N7TAze , M1N7TDxss , M1N7TDyss , M1N7TDzss , M1N8FKxe , M1N8FKye , M1N8FKze , & + M1N8FMxe , M1N8FMye , M1N8FMze , M1N8MKxe , M1N8MKye , M1N8MKze , M1N8MMxe , & + M1N8MMye , M1N8MMze , M1N8RAxe , M1N8RAye , M1N8RAze , M1N8RDxe , M1N8RDye , & + M1N8RDze , M1N8TAxe , M1N8TAye , M1N8TAze , M1N8TDxss , M1N8TDyss , M1N8TDzss , & + M1N9FKxe , M1N9FKye , M1N9FKze , M1N9FMxe , M1N9FMye , M1N9FMze , M1N9MKxe , & + M1N9MKye , M1N9MKze , M1N9MMxe , M1N9MMye , M1N9MMze , M1N9RAxe , M1N9RAye , & + M1N9RAze , M1N9RDxe , M1N9RDye , M1N9RDze , M1N9TAxe , M1N9TAye , M1N9TAze , & + M1N9TDxss , M1N9TDyss , M1N9TDzss , M2N1FKxe , M2N1FKye , M2N1FKze , M2N1FMxe , & + M2N1FMye , M2N1FMze , M2N1MKxe , M2N1MKye , M2N1MKze , M2N1MMxe , M2N1MMye , & + M2N1MMze , M2N1RAxe , M2N1RAye , M2N1RAze , M2N1RDxe , M2N1RDye , M2N1RDze , & + M2N1TAxe , M2N1TAye , M2N1TAze , M2N1TDxss , M2N1TDyss , M2N1TDzss , M2N2FKxe , & + M2N2FKye , M2N2FKze , M2N2FMxe , M2N2FMye , M2N2FMze , M2N2MKxe , M2N2MKye , & + M2N2MKze , M2N2MMxe , M2N2MMye , M2N2MMze , M2N2RAxe , M2N2RAye , M2N2RAze , & + M2N2RDxe , M2N2RDye , M2N2RDze , M2N2TAxe , M2N2TAye , M2N2TAze , M2N2TDxss , & + M2N2TDyss , M2N2TDzss , M2N3FKxe , M2N3FKye , M2N3FKze , M2N3FMxe , M2N3FMye , & + M2N3FMze , M2N3MKxe , M2N3MKye , M2N3MKze , M2N3MMxe , M2N3MMye , M2N3MMze , & + M2N3RAxe , M2N3RAye , M2N3RAze , M2N3RDxe , M2N3RDye , M2N3RDze , M2N3TAxe , & + M2N3TAye , M2N3TAze , M2N3TDxss , M2N3TDyss , M2N3TDzss , M2N4FKxe , M2N4FKye , & + M2N4FKze , M2N4FMxe , M2N4FMye , M2N4FMze , M2N4MKxe , M2N4MKye , M2N4MKze , & + M2N4MMxe , M2N4MMye , M2N4MMze , M2N4RAxe , M2N4RAye , M2N4RAze , M2N4RDxe , & + M2N4RDye , M2N4RDze , M2N4TAxe , M2N4TAye , M2N4TAze , M2N4TDxss , M2N4TDyss , & + M2N4TDzss , M2N5FKxe , M2N5FKye , M2N5FKze , M2N5FMxe , M2N5FMye , M2N5FMze , & + M2N5MKxe , M2N5MKye , M2N5MKze , M2N5MMxe , M2N5MMye , M2N5MMze , M2N5RAxe , & + M2N5RAye , M2N5RAze , M2N5RDxe , M2N5RDye , M2N5RDze , M2N5TAxe , M2N5TAye , & + M2N5TAze , M2N5TDxss , M2N5TDyss , M2N5TDzss , M2N6FKxe , M2N6FKye , M2N6FKze , & + M2N6FMxe , M2N6FMye , M2N6FMze , M2N6MKxe , M2N6MKye , M2N6MKze , M2N6MMxe , & + M2N6MMye , M2N6MMze , M2N6RAxe , M2N6RAye , M2N6RAze , M2N6RDxe , M2N6RDye , & + M2N6RDze , M2N6TAxe , M2N6TAye , M2N6TAze , M2N6TDxss , M2N6TDyss , M2N6TDzss , & + M2N7FKxe , M2N7FKye , M2N7FKze , M2N7FMxe , M2N7FMye , M2N7FMze , M2N7MKxe , & + M2N7MKye , M2N7MKze , M2N7MMxe , M2N7MMye , M2N7MMze , M2N7RAxe , M2N7RAye , & + M2N7RAze , M2N7RDxe , M2N7RDye , M2N7RDze , M2N7TAxe , M2N7TAye , M2N7TAze , & + M2N7TDxss , M2N7TDyss , M2N7TDzss , M2N8FKxe , M2N8FKye , M2N8FKze , M2N8FMxe , & + M2N8FMye , M2N8FMze , M2N8MKxe , M2N8MKye , M2N8MKze , M2N8MMxe , M2N8MMye , & + M2N8MMze , M2N8RAxe , M2N8RAye , M2N8RAze , M2N8RDxe , M2N8RDye , M2N8RDze , & + M2N8TAxe , M2N8TAye , M2N8TAze , M2N8TDxss , M2N8TDyss , M2N8TDzss , M2N9FKxe , & + M2N9FKye , M2N9FKze , M2N9FMxe , M2N9FMye , M2N9FMze , M2N9MKxe , M2N9MKye , & + M2N9MKze , M2N9MMxe , M2N9MMye , M2N9MMze , M2N9RAxe , M2N9RAye , M2N9RAze , & + M2N9RDxe , M2N9RDye , M2N9RDze , M2N9TAxe , M2N9TAye , M2N9TAze , M2N9TDxss , & + M2N9TDyss , M2N9TDzss , M3N1FKxe , M3N1FKye , M3N1FKze , M3N1FMxe , M3N1FMye , & + M3N1FMze , M3N1MKxe , M3N1MKye , M3N1MKze , M3N1MMxe , M3N1MMye , M3N1MMze , & + M3N1RAxe , M3N1RAye , M3N1RAze , M3N1RDxe , M3N1RDye , M3N1RDze , M3N1TAxe , & + M3N1TAye , M3N1TAze , M3N1TDxss , M3N1TDyss , M3N1TDzss , M3N2FKxe , M3N2FKye , & + M3N2FKze , M3N2FMxe , M3N2FMye , M3N2FMze , M3N2MKxe , M3N2MKye , M3N2MKze , & + M3N2MMxe , M3N2MMye , M3N2MMze , M3N2RAxe , M3N2RAye , M3N2RAze , M3N2RDxe , & + M3N2RDye , M3N2RDze , M3N2TAxe , M3N2TAye , M3N2TAze , M3N2TDxss , M3N2TDyss , & + M3N2TDzss , M3N3FKxe , M3N3FKye , M3N3FKze , M3N3FMxe , M3N3FMye , M3N3FMze , & + M3N3MKxe , M3N3MKye , M3N3MKze , M3N3MMxe , M3N3MMye , M3N3MMze , M3N3RAxe , & + M3N3RAye , M3N3RAze , M3N3RDxe , M3N3RDye , M3N3RDze , M3N3TAxe , M3N3TAye , & + M3N3TAze , M3N3TDxss , M3N3TDyss , M3N3TDzss , M3N4FKxe , M3N4FKye , M3N4FKze , & + M3N4FMxe , M3N4FMye , M3N4FMze , M3N4MKxe , M3N4MKye , M3N4MKze , M3N4MMxe , & + M3N4MMye , M3N4MMze , M3N4RAxe , M3N4RAye , M3N4RAze , M3N4RDxe , M3N4RDye , & + M3N4RDze , M3N4TAxe , M3N4TAye , M3N4TAze , M3N4TDxss , M3N4TDyss , M3N4TDzss , & + M3N5FKxe , M3N5FKye , M3N5FKze , M3N5FMxe , M3N5FMye , M3N5FMze , M3N5MKxe , & + M3N5MKye , M3N5MKze , M3N5MMxe , M3N5MMye , M3N5MMze , M3N5RAxe , M3N5RAye , & + M3N5RAze , M3N5RDxe , M3N5RDye , M3N5RDze , M3N5TAxe , M3N5TAye , M3N5TAze , & + M3N5TDxss , M3N5TDyss , M3N5TDzss , M3N6FKxe , M3N6FKye , M3N6FKze , M3N6FMxe , & + M3N6FMye , M3N6FMze , M3N6MKxe , M3N6MKye , M3N6MKze , M3N6MMxe , M3N6MMye , & + M3N6MMze , M3N6RAxe , M3N6RAye , M3N6RAze , M3N6RDxe , M3N6RDye , M3N6RDze , & + M3N6TAxe , M3N6TAye , M3N6TAze , M3N6TDxss , M3N6TDyss , M3N6TDzss , M3N7FKxe , & + M3N7FKye , M3N7FKze , M3N7FMxe , M3N7FMye , M3N7FMze , M3N7MKxe , M3N7MKye , & + M3N7MKze , M3N7MMxe , M3N7MMye , M3N7MMze , M3N7RAxe , M3N7RAye , M3N7RAze , & + M3N7RDxe , M3N7RDye , M3N7RDze , M3N7TAxe , M3N7TAye , M3N7TAze , M3N7TDxss , & + M3N7TDyss , M3N7TDzss , M3N8FKxe , M3N8FKye , M3N8FKze , M3N8FMxe , M3N8FMye , & + M3N8FMze , M3N8MKxe , M3N8MKye , M3N8MKze , M3N8MMxe , M3N8MMye , M3N8MMze , & + M3N8RAxe , M3N8RAye , M3N8RAze , M3N8RDxe , M3N8RDye , M3N8RDze , M3N8TAxe , & + M3N8TAye , M3N8TAze , M3N8TDxss , M3N8TDyss , M3N8TDzss , M3N9FKxe , M3N9FKye , & + M3N9FKze , M3N9FMxe , M3N9FMye , M3N9FMze , M3N9MKxe , M3N9MKye , M3N9MKze , & + M3N9MMxe , M3N9MMye , M3N9MMze , M3N9RAxe , M3N9RAye , M3N9RAze , M3N9RDxe , & + M3N9RDye , M3N9RDze , M3N9TAxe , M3N9TAye , M3N9TAze , M3N9TDxss , M3N9TDyss , & + M3N9TDzss , M4N1FKxe , M4N1FKye , M4N1FKze , M4N1FMxe , M4N1FMye , M4N1FMze , & + M4N1MKxe , M4N1MKye , M4N1MKze , M4N1MMxe , M4N1MMye , M4N1MMze , M4N1RAxe , & + M4N1RAye , M4N1RAze , M4N1RDxe , M4N1RDye , M4N1RDze , M4N1TAxe , M4N1TAye , & + M4N1TAze , M4N1TDxss , M4N1TDyss , M4N1TDzss , M4N2FKxe , M4N2FKye , M4N2FKze , & + M4N2FMxe , M4N2FMye , M4N2FMze , M4N2MKxe , M4N2MKye , M4N2MKze , M4N2MMxe , & + M4N2MMye , M4N2MMze , M4N2RAxe , M4N2RAye , M4N2RAze , M4N2RDxe , M4N2RDye , & + M4N2RDze , M4N2TAxe , M4N2TAye , M4N2TAze , M4N2TDxss , M4N2TDyss , M4N2TDzss , & + M4N3FKxe , M4N3FKye , M4N3FKze , M4N3FMxe , M4N3FMye , M4N3FMze , M4N3MKxe , & + M4N3MKye , M4N3MKze , M4N3MMxe , M4N3MMye , M4N3MMze , M4N3RAxe , M4N3RAye , & + M4N3RAze , M4N3RDxe , M4N3RDye , M4N3RDze , M4N3TAxe , M4N3TAye , M4N3TAze , & + M4N3TDxss , M4N3TDyss , M4N3TDzss , M4N4FKxe , M4N4FKye , M4N4FKze , M4N4FMxe , & + M4N4FMye , M4N4FMze , M4N4MKxe , M4N4MKye , M4N4MKze , M4N4MMxe , M4N4MMye , & + M4N4MMze , M4N4RAxe , M4N4RAye , M4N4RAze , M4N4RDxe , M4N4RDye , M4N4RDze , & + M4N4TAxe , M4N4TAye , M4N4TAze , M4N4TDxss , M4N4TDyss , M4N4TDzss , M4N5FKxe , & + M4N5FKye , M4N5FKze , M4N5FMxe , M4N5FMye , M4N5FMze , M4N5MKxe , M4N5MKye , & + M4N5MKze , M4N5MMxe , M4N5MMye , M4N5MMze , M4N5RAxe , M4N5RAye , M4N5RAze , & + M4N5RDxe , M4N5RDye , M4N5RDze , M4N5TAxe , M4N5TAye , M4N5TAze , M4N5TDxss , & + M4N5TDyss , M4N5TDzss , M4N6FKxe , M4N6FKye , M4N6FKze , M4N6FMxe , M4N6FMye , & + M4N6FMze , M4N6MKxe , M4N6MKye , M4N6MKze , M4N6MMxe , M4N6MMye , M4N6MMze , & + M4N6RAxe , M4N6RAye , M4N6RAze , M4N6RDxe , M4N6RDye , M4N6RDze , M4N6TAxe , & + M4N6TAye , M4N6TAze , M4N6TDxss , M4N6TDyss , M4N6TDzss , M4N7FKxe , M4N7FKye , & + M4N7FKze , M4N7FMxe , M4N7FMye , M4N7FMze , M4N7MKxe , M4N7MKye , M4N7MKze , & + M4N7MMxe , M4N7MMye , M4N7MMze , M4N7RAxe , M4N7RAye , M4N7RAze , M4N7RDxe , & + M4N7RDye , M4N7RDze , M4N7TAxe , M4N7TAye , M4N7TAze , M4N7TDxss , M4N7TDyss , & + M4N7TDzss , M4N8FKxe , M4N8FKye , M4N8FKze , M4N8FMxe , M4N8FMye , M4N8FMze , & + M4N8MKxe , M4N8MKye , M4N8MKze , M4N8MMxe , M4N8MMye , M4N8MMze , M4N8RAxe , & + M4N8RAye , M4N8RAze , M4N8RDxe , M4N8RDye , M4N8RDze , M4N8TAxe , M4N8TAye , & + M4N8TAze , M4N8TDxss , M4N8TDyss , M4N8TDzss , M4N9FKxe , M4N9FKye , M4N9FKze , & + M4N9FMxe , M4N9FMye , M4N9FMze , M4N9MKxe , M4N9MKye , M4N9MKze , M4N9MMxe , & + M4N9MMye , M4N9MMze , M4N9RAxe , M4N9RAye , M4N9RAze , M4N9RDxe , M4N9RDye , & + M4N9RDze , M4N9TAxe , M4N9TAye , M4N9TAze , M4N9TDxss , M4N9TDyss , M4N9TDzss , & + M5N1FKxe , M5N1FKye , M5N1FKze , M5N1FMxe , M5N1FMye , M5N1FMze , M5N1MKxe , & + M5N1MKye , M5N1MKze , M5N1MMxe , M5N1MMye , M5N1MMze , M5N1RAxe , M5N1RAye , & + M5N1RAze , M5N1RDxe , M5N1RDye , M5N1RDze , M5N1TAxe , M5N1TAye , M5N1TAze , & + M5N1TDxss , M5N1TDyss , M5N1TDzss , M5N2FKxe , M5N2FKye , M5N2FKze , M5N2FMxe , & + M5N2FMye , M5N2FMze , M5N2MKxe , M5N2MKye , M5N2MKze , M5N2MMxe , M5N2MMye , & + M5N2MMze , M5N2RAxe , M5N2RAye , M5N2RAze , M5N2RDxe , M5N2RDye , M5N2RDze , & + M5N2TAxe , M5N2TAye , M5N2TAze , M5N2TDxss , M5N2TDyss , M5N2TDzss , M5N3FKxe , & + M5N3FKye , M5N3FKze , M5N3FMxe , M5N3FMye , M5N3FMze , M5N3MKxe , M5N3MKye , & + M5N3MKze , M5N3MMxe , M5N3MMye , M5N3MMze , M5N3RAxe , M5N3RAye , M5N3RAze , & + M5N3RDxe , M5N3RDye , M5N3RDze , M5N3TAxe , M5N3TAye , M5N3TAze , M5N3TDxss , & + M5N3TDyss , M5N3TDzss , M5N4FKxe , M5N4FKye , M5N4FKze , M5N4FMxe , M5N4FMye , & + M5N4FMze , M5N4MKxe , M5N4MKye , M5N4MKze , M5N4MMxe , M5N4MMye , M5N4MMze , & + M5N4RAxe , M5N4RAye , M5N4RAze , M5N4RDxe , M5N4RDye , M5N4RDze , M5N4TAxe , & + M5N4TAye , M5N4TAze , M5N4TDxss , M5N4TDyss , M5N4TDzss , M5N5FKxe , M5N5FKye , & + M5N5FKze , M5N5FMxe , M5N5FMye , M5N5FMze , M5N5MKxe , M5N5MKye , M5N5MKze , & + M5N5MMxe , M5N5MMye , M5N5MMze , M5N5RAxe , M5N5RAye , M5N5RAze , M5N5RDxe , & + M5N5RDye , M5N5RDze , M5N5TAxe , M5N5TAye , M5N5TAze , M5N5TDxss , M5N5TDyss , & + M5N5TDzss , M5N6FKxe , M5N6FKye , M5N6FKze , M5N6FMxe , M5N6FMye , M5N6FMze , & + M5N6MKxe , M5N6MKye , M5N6MKze , M5N6MMxe , M5N6MMye , M5N6MMze , M5N6RAxe , & + M5N6RAye , M5N6RAze , M5N6RDxe , M5N6RDye , M5N6RDze , M5N6TAxe , M5N6TAye , & + M5N6TAze , M5N6TDxss , M5N6TDyss , M5N6TDzss , M5N7FKxe , M5N7FKye , M5N7FKze , & + M5N7FMxe , M5N7FMye , M5N7FMze , M5N7MKxe , M5N7MKye , M5N7MKze , M5N7MMxe , & + M5N7MMye , M5N7MMze , M5N7RAxe , M5N7RAye , M5N7RAze , M5N7RDxe , M5N7RDye , & + M5N7RDze , M5N7TAxe , M5N7TAye , M5N7TAze , M5N7TDxss , M5N7TDyss , M5N7TDzss , & + M5N8FKxe , M5N8FKye , M5N8FKze , M5N8FMxe , M5N8FMye , M5N8FMze , M5N8MKxe , & + M5N8MKye , M5N8MKze , M5N8MMxe , M5N8MMye , M5N8MMze , M5N8RAxe , M5N8RAye , & + M5N8RAze , M5N8RDxe , M5N8RDye , M5N8RDze , M5N8TAxe , M5N8TAye , M5N8TAze , & + M5N8TDxss , M5N8TDyss , M5N8TDzss , M5N9FKxe , M5N9FKye , M5N9FKze , M5N9FMxe , & + M5N9FMye , M5N9FMze , M5N9MKxe , M5N9MKye , M5N9MKze , M5N9MMxe , M5N9MMye , & + M5N9MMze , M5N9RAxe , M5N9RAye , M5N9RAze , M5N9RDxe , M5N9RDye , M5N9RDze , & + M5N9TAxe , M5N9TAye , M5N9TAze , M5N9TDxss , M5N9TDyss , M5N9TDzss , M6N1FKxe , & + M6N1FKye , M6N1FKze , M6N1FMxe , M6N1FMye , M6N1FMze , M6N1MKxe , M6N1MKye , & + M6N1MKze , M6N1MMxe , M6N1MMye , M6N1MMze , M6N1RAxe , M6N1RAye , M6N1RAze , & + M6N1RDxe , M6N1RDye , M6N1RDze , M6N1TAxe , M6N1TAye , M6N1TAze , M6N1TDxss , & + M6N1TDyss , M6N1TDzss , M6N2FKxe , M6N2FKye , M6N2FKze , M6N2FMxe , M6N2FMye , & + M6N2FMze , M6N2MKxe , M6N2MKye , M6N2MKze , M6N2MMxe , M6N2MMye , M6N2MMze , & + M6N2RAxe , M6N2RAye , M6N2RAze , M6N2RDxe , M6N2RDye , M6N2RDze , M6N2TAxe , & + M6N2TAye , M6N2TAze , M6N2TDxss , M6N2TDyss , M6N2TDzss , M6N3FKxe , M6N3FKye , & + M6N3FKze , M6N3FMxe , M6N3FMye , M6N3FMze , M6N3MKxe , M6N3MKye , M6N3MKze , & + M6N3MMxe , M6N3MMye , M6N3MMze , M6N3RAxe , M6N3RAye , M6N3RAze , M6N3RDxe , & + M6N3RDye , M6N3RDze , M6N3TAxe , M6N3TAye , M6N3TAze , M6N3TDxss , M6N3TDyss , & + M6N3TDzss , M6N4FKxe , M6N4FKye , M6N4FKze , M6N4FMxe , M6N4FMye , M6N4FMze , & + M6N4MKxe , M6N4MKye , M6N4MKze , M6N4MMxe , M6N4MMye , M6N4MMze , M6N4RAxe , & + M6N4RAye , M6N4RAze , M6N4RDxe , M6N4RDye , M6N4RDze , M6N4TAxe , M6N4TAye , & + M6N4TAze , M6N4TDxss , M6N4TDyss , M6N4TDzss , M6N5FKxe , M6N5FKye , M6N5FKze , & + M6N5FMxe , M6N5FMye , M6N5FMze , M6N5MKxe , M6N5MKye , M6N5MKze , M6N5MMxe , & + M6N5MMye , M6N5MMze , M6N5RAxe , M6N5RAye , M6N5RAze , M6N5RDxe , M6N5RDye , & + M6N5RDze , M6N5TAxe , M6N5TAye , M6N5TAze , M6N5TDxss , M6N5TDyss , M6N5TDzss , & + M6N6FKxe , M6N6FKye , M6N6FKze , M6N6FMxe , M6N6FMye , M6N6FMze , M6N6MKxe , & + M6N6MKye , M6N6MKze , M6N6MMxe , M6N6MMye , M6N6MMze , M6N6RAxe , M6N6RAye , & + M6N6RAze , M6N6RDxe , M6N6RDye , M6N6RDze , M6N6TAxe , M6N6TAye , M6N6TAze , & + M6N6TDxss , M6N6TDyss , M6N6TDzss , M6N7FKxe , M6N7FKye , M6N7FKze , M6N7FMxe , & + M6N7FMye , M6N7FMze , M6N7MKxe , M6N7MKye , M6N7MKze , M6N7MMxe , M6N7MMye , & + M6N7MMze , M6N7RAxe , M6N7RAye , M6N7RAze , M6N7RDxe , M6N7RDye , M6N7RDze , & + M6N7TAxe , M6N7TAye , M6N7TAze , M6N7TDxss , M6N7TDyss , M6N7TDzss , M6N8FKxe , & + M6N8FKye , M6N8FKze , M6N8FMxe , M6N8FMye , M6N8FMze , M6N8MKxe , M6N8MKye , & + M6N8MKze , M6N8MMxe , M6N8MMye , M6N8MMze , M6N8RAxe , M6N8RAye , M6N8RAze , & + M6N8RDxe , M6N8RDye , M6N8RDze , M6N8TAxe , M6N8TAye , M6N8TAze , M6N8TDxss , & + M6N8TDyss , M6N8TDzss , M6N9FKxe , M6N9FKye , M6N9FKze , M6N9FMxe , M6N9FMye , & + M6N9FMze , M6N9MKxe , M6N9MKye , M6N9MKze , M6N9MMxe , M6N9MMye , M6N9MMze , & + M6N9RAxe , M6N9RAye , M6N9RAze , M6N9RDxe , M6N9RDye , M6N9RDze , M6N9TAxe , & + M6N9TAye , M6N9TAze , M6N9TDxss , M6N9TDyss , M6N9TDzss , M7N1FKxe , M7N1FKye , & + M7N1FKze , M7N1FMxe , M7N1FMye , M7N1FMze , M7N1MKxe , M7N1MKye , M7N1MKze , & + M7N1MMxe , M7N1MMye , M7N1MMze , M7N1RAxe , M7N1RAye , M7N1RAze , M7N1RDxe , & + M7N1RDye , M7N1RDze , M7N1TAxe , M7N1TAye , M7N1TAze , M7N1TDxss , M7N1TDyss , & + M7N1TDzss , M7N2FKxe , M7N2FKye , M7N2FKze , M7N2FMxe , M7N2FMye , M7N2FMze , & + M7N2MKxe , M7N2MKye , M7N2MKze , M7N2MMxe , M7N2MMye , M7N2MMze , M7N2RAxe , & + M7N2RAye , M7N2RAze , M7N2RDxe , M7N2RDye , M7N2RDze , M7N2TAxe , M7N2TAye , & + M7N2TAze , M7N2TDxss , M7N2TDyss , M7N2TDzss , M7N3FKxe , M7N3FKye , M7N3FKze , & + M7N3FMxe , M7N3FMye , M7N3FMze , M7N3MKxe , M7N3MKye , M7N3MKze , M7N3MMxe , & + M7N3MMye , M7N3MMze , M7N3RAxe , M7N3RAye , M7N3RAze , M7N3RDxe , M7N3RDye , & + M7N3RDze , M7N3TAxe , M7N3TAye , M7N3TAze , M7N3TDxss , M7N3TDyss , M7N3TDzss , & + M7N4FKxe , M7N4FKye , M7N4FKze , M7N4FMxe , M7N4FMye , M7N4FMze , M7N4MKxe , & + M7N4MKye , M7N4MKze , M7N4MMxe , M7N4MMye , M7N4MMze , M7N4RAxe , M7N4RAye , & + M7N4RAze , M7N4RDxe , M7N4RDye , M7N4RDze , M7N4TAxe , M7N4TAye , M7N4TAze , & + M7N4TDxss , M7N4TDyss , M7N4TDzss , M7N5FKxe , M7N5FKye , M7N5FKze , M7N5FMxe , & + M7N5FMye , M7N5FMze , M7N5MKxe , M7N5MKye , M7N5MKze , M7N5MMxe , M7N5MMye , & + M7N5MMze , M7N5RAxe , M7N5RAye , M7N5RAze , M7N5RDxe , M7N5RDye , M7N5RDze , & + M7N5TAxe , M7N5TAye , M7N5TAze , M7N5TDxss , M7N5TDyss , M7N5TDzss , M7N6FKxe , & + M7N6FKye , M7N6FKze , M7N6FMxe , M7N6FMye , M7N6FMze , M7N6MKxe , M7N6MKye , & + M7N6MKze , M7N6MMxe , M7N6MMye , M7N6MMze , M7N6RAxe , M7N6RAye , M7N6RAze , & + M7N6RDxe , M7N6RDye , M7N6RDze , M7N6TAxe , M7N6TAye , M7N6TAze , M7N6TDxss , & + M7N6TDyss , M7N6TDzss , M7N7FKxe , M7N7FKye , M7N7FKze , M7N7FMxe , M7N7FMye , & + M7N7FMze , M7N7MKxe , M7N7MKye , M7N7MKze , M7N7MMxe , M7N7MMye , M7N7MMze , & + M7N7RAxe , M7N7RAye , M7N7RAze , M7N7RDxe , M7N7RDye , M7N7RDze , M7N7TAxe , & + M7N7TAye , M7N7TAze , M7N7TDxss , M7N7TDyss , M7N7TDzss , M7N8FKxe , M7N8FKye , & + M7N8FKze , M7N8FMxe , M7N8FMye , M7N8FMze , M7N8MKxe , M7N8MKye , M7N8MKze , & + M7N8MMxe , M7N8MMye , M7N8MMze , M7N8RAxe , M7N8RAye , M7N8RAze , M7N8RDxe , & + M7N8RDye , M7N8RDze , M7N8TAxe , M7N8TAye , M7N8TAze , M7N8TDxss , M7N8TDyss , & + M7N8TDzss , M7N9FKxe , M7N9FKye , M7N9FKze , M7N9FMxe , M7N9FMye , M7N9FMze , & + M7N9MKxe , M7N9MKye , M7N9MKze , M7N9MMxe , M7N9MMye , M7N9MMze , M7N9RAxe , & + M7N9RAye , M7N9RAze , M7N9RDxe , M7N9RDye , M7N9RDze , M7N9TAxe , M7N9TAye , & + M7N9TAze , M7N9TDxss , M7N9TDyss , M7N9TDzss , M8N1FKxe , M8N1FKye , M8N1FKze , & + M8N1FMxe , M8N1FMye , M8N1FMze , M8N1MKxe , M8N1MKye , M8N1MKze , M8N1MMxe , & + M8N1MMye , M8N1MMze , M8N1RAxe , M8N1RAye , M8N1RAze , M8N1RDxe , M8N1RDye , & + M8N1RDze , M8N1TAxe , M8N1TAye , M8N1TAze , M8N1TDxss , M8N1TDyss , M8N1TDzss , & + M8N2FKxe , M8N2FKye , M8N2FKze , M8N2FMxe , M8N2FMye , M8N2FMze , M8N2MKxe , & + M8N2MKye , M8N2MKze , M8N2MMxe , M8N2MMye , M8N2MMze , M8N2RAxe , M8N2RAye , & + M8N2RAze , M8N2RDxe , M8N2RDye , M8N2RDze , M8N2TAxe , M8N2TAye , M8N2TAze , & + M8N2TDxss , M8N2TDyss , M8N2TDzss , M8N3FKxe , M8N3FKye , M8N3FKze , M8N3FMxe , & + M8N3FMye , M8N3FMze , M8N3MKxe , M8N3MKye , M8N3MKze , M8N3MMxe , M8N3MMye , & + M8N3MMze , M8N3RAxe , M8N3RAye , M8N3RAze , M8N3RDxe , M8N3RDye , M8N3RDze , & + M8N3TAxe , M8N3TAye , M8N3TAze , M8N3TDxss , M8N3TDyss , M8N3TDzss , M8N4FKxe , & + M8N4FKye , M8N4FKze , M8N4FMxe , M8N4FMye , M8N4FMze , M8N4MKxe , M8N4MKye , & + M8N4MKze , M8N4MMxe , M8N4MMye , M8N4MMze , M8N4RAxe , M8N4RAye , M8N4RAze , & + M8N4RDxe , M8N4RDye , M8N4RDze , M8N4TAxe , M8N4TAye , M8N4TAze , M8N4TDxss , & + M8N4TDyss , M8N4TDzss , M8N5FKxe , M8N5FKye , M8N5FKze , M8N5FMxe , M8N5FMye , & + M8N5FMze , M8N5MKxe , M8N5MKye , M8N5MKze , M8N5MMxe , M8N5MMye , M8N5MMze , & + M8N5RAxe , M8N5RAye , M8N5RAze , M8N5RDxe , M8N5RDye , M8N5RDze , M8N5TAxe , & + M8N5TAye , M8N5TAze , M8N5TDxss , M8N5TDyss , M8N5TDzss , M8N6FKxe , M8N6FKye , & + M8N6FKze , M8N6FMxe , M8N6FMye , M8N6FMze , M8N6MKxe , M8N6MKye , M8N6MKze , & + M8N6MMxe , M8N6MMye , M8N6MMze , M8N6RAxe , M8N6RAye , M8N6RAze , M8N6RDxe , & + M8N6RDye , M8N6RDze , M8N6TAxe , M8N6TAye , M8N6TAze , M8N6TDxss , M8N6TDyss , & + M8N6TDzss , M8N7FKxe , M8N7FKye , M8N7FKze , M8N7FMxe , M8N7FMye , M8N7FMze , & + M8N7MKxe , M8N7MKye , M8N7MKze , M8N7MMxe , M8N7MMye , M8N7MMze , M8N7RAxe , & + M8N7RAye , M8N7RAze , M8N7RDxe , M8N7RDye , M8N7RDze , M8N7TAxe , M8N7TAye , & + M8N7TAze , M8N7TDxss , M8N7TDyss , M8N7TDzss , M8N8FKxe , M8N8FKye , M8N8FKze , & + M8N8FMxe , M8N8FMye , M8N8FMze , M8N8MKxe , M8N8MKye , M8N8MKze , M8N8MMxe , & + M8N8MMye , M8N8MMze , M8N8RAxe , M8N8RAye , M8N8RAze , M8N8RDxe , M8N8RDye , & + M8N8RDze , M8N8TAxe , M8N8TAye , M8N8TAze , M8N8TDxss , M8N8TDyss , M8N8TDzss , & + M8N9FKxe , M8N9FKye , M8N9FKze , M8N9FMxe , M8N9FMye , M8N9FMze , M8N9MKxe , & + M8N9MKye , M8N9MKze , M8N9MMxe , M8N9MMye , M8N9MMze , M8N9RAxe , M8N9RAye , & + M8N9RAze , M8N9RDxe , M8N9RDye , M8N9RDze , M8N9TAxe , M8N9TAye , M8N9TAze , & + M8N9TDxss , M8N9TDyss , M8N9TDzss , M9N1FKxe , M9N1FKye , M9N1FKze , M9N1FMxe , & + M9N1FMye , M9N1FMze , M9N1MKxe , M9N1MKye , M9N1MKze , M9N1MMxe , M9N1MMye , & + M9N1MMze , M9N1RAxe , M9N1RAye , M9N1RAze , M9N1RDxe , M9N1RDye , M9N1RDze , & + M9N1TAxe , M9N1TAye , M9N1TAze , M9N1TDxss , M9N1TDyss , M9N1TDzss , M9N2FKxe , & + M9N2FKye , M9N2FKze , M9N2FMxe , M9N2FMye , M9N2FMze , M9N2MKxe , M9N2MKye , & + M9N2MKze , M9N2MMxe , M9N2MMye , M9N2MMze , M9N2RAxe , M9N2RAye , M9N2RAze , & + M9N2RDxe , M9N2RDye , M9N2RDze , M9N2TAxe , M9N2TAye , M9N2TAze , M9N2TDxss , & + M9N2TDyss , M9N2TDzss , M9N3FKxe , M9N3FKye , M9N3FKze , M9N3FMxe , M9N3FMye , & + M9N3FMze , M9N3MKxe , M9N3MKye , M9N3MKze , M9N3MMxe , M9N3MMye , M9N3MMze , & + M9N3RAxe , M9N3RAye , M9N3RAze , M9N3RDxe , M9N3RDye , M9N3RDze , M9N3TAxe , & + M9N3TAye , M9N3TAze , M9N3TDxss , M9N3TDyss , M9N3TDzss , M9N4FKxe , M9N4FKye , & + M9N4FKze , M9N4FMxe , M9N4FMye , M9N4FMze , M9N4MKxe , M9N4MKye , M9N4MKze , & + M9N4MMxe , M9N4MMye , M9N4MMze , M9N4RAxe , M9N4RAye , M9N4RAze , M9N4RDxe , & + M9N4RDye , M9N4RDze , M9N4TAxe , M9N4TAye , M9N4TAze , M9N4TDxss , M9N4TDyss , & + M9N4TDzss , M9N5FKxe , M9N5FKye , M9N5FKze , M9N5FMxe , M9N5FMye , M9N5FMze , & + M9N5MKxe , M9N5MKye , M9N5MKze , M9N5MMxe , M9N5MMye , M9N5MMze , M9N5RAxe , & + M9N5RAye , M9N5RAze , M9N5RDxe , M9N5RDye , M9N5RDze , M9N5TAxe , M9N5TAye , & + M9N5TAze , M9N5TDxss , M9N5TDyss , M9N5TDzss , M9N6FKxe , M9N6FKye , M9N6FKze , & + M9N6FMxe , M9N6FMye , M9N6FMze , M9N6MKxe , M9N6MKye , M9N6MKze , M9N6MMxe , & + M9N6MMye , M9N6MMze , M9N6RAxe , M9N6RAye , M9N6RAze , M9N6RDxe , M9N6RDye , & + M9N6RDze , M9N6TAxe , M9N6TAye , M9N6TAze , M9N6TDxss , M9N6TDyss , M9N6TDzss , & + M9N7FKxe , M9N7FKye , M9N7FKze , M9N7FMxe , M9N7FMye , M9N7FMze , M9N7MKxe , & + M9N7MKye , M9N7MKze , M9N7MMxe , M9N7MMye , M9N7MMze , M9N7RAxe , M9N7RAye , & + M9N7RAze , M9N7RDxe , M9N7RDye , M9N7RDze , M9N7TAxe , M9N7TAye , M9N7TAze , & + M9N7TDxss , M9N7TDyss , M9N7TDzss , M9N8FKxe , M9N8FKye , M9N8FKze , M9N8FMxe , & + M9N8FMye , M9N8FMze , M9N8MKxe , M9N8MKye , M9N8MKze , M9N8MMxe , M9N8MMye , & + M9N8MMze , M9N8RAxe , M9N8RAye , M9N8RAze , M9N8RDxe , M9N8RDye , M9N8RDze , & + M9N8TAxe , M9N8TAye , M9N8TAze , M9N8TDxss , M9N8TDyss , M9N8TDzss , M9N9FKxe , & + M9N9FKye , M9N9FKze , M9N9FMxe , M9N9FMye , M9N9FMze , M9N9MKxe , M9N9MKye , & + M9N9MKze , M9N9MMxe , M9N9MMye , M9N9MMze , M9N9RAxe , M9N9RAye , M9N9RAze , & + M9N9RDxe , M9N9RDye , M9N9RDze , M9N9TAxe , M9N9TAye , M9N9TAze , M9N9TDxss , & + M9N9TDyss , M9N9TDzss , ReactFXss , ReactFYss , ReactFZss , ReactMXss , ReactMYss , & + ReactMZss , SSqm01 , SSqm02 , SSqm03 , SSqm04 , SSqm05 , SSqm06 , & + SSqm07 , SSqm08 , SSqm09 , SSqm10 , SSqm11 , SSqm12 , SSqm13 , & + SSqm14 , SSqm15 , SSqm16 , SSqm17 , SSqm18 , SSqm19 , SSqm20 , & + SSqm21 , SSqm22 , SSqm23 , SSqm24 , SSqm25 , SSqm26 , SSqm27 , & + SSqm28 , SSqm29 , SSqm30 , SSqm31 , SSqm32 , SSqm33 , SSqm34 , & + SSqm35 , SSqm36 , SSqm37 , SSqm38 , SSqm39 , SSqm40 , SSqm41 , & + SSqm42 , SSqm43 , SSqm44 , SSqm45 , SSqm46 , SSqm47 , SSqm48 , & + SSqm49 , SSqm50 , SSqm51 , SSqm52 , SSqm53 , SSqm54 , SSqm55 , & + SSqm56 , SSqm57 , SSqm58 , SSqm59 , SSqm60 , SSqm61 , SSqm62 , & + SSqm63 , SSqm64 , SSqm65 , SSqm66 , SSqm67 , SSqm68 , SSqm69 , & + SSqm70 , SSqm71 , SSqm72 , SSqm73 , SSqm74 , SSqm75 , SSqm76 , & + SSqm77 , SSqm78 , SSqm79 , SSqm80 , SSqm81 , SSqm82 , SSqm83 , & + SSqm84 , SSqm85 , SSqm86 , SSqm87 , SSqm88 , SSqm89 , SSqm90 , & + SSqm91 , SSqm92 , SSqm93 , SSqm94 , SSqm95 , SSqm96 , SSqm97 , & + SSqm98 , SSqm99 , SSqmd01 , SSqmd02 , SSqmd03 , SSqmd04 , SSqmd05 , & + SSqmd06 , SSqmd07 , SSqmd08 , SSqmd09 , SSqmd10 , SSqmd11 , SSqmd12 , & + SSqmd13 , SSqmd14 , SSqmd15 , SSqmd16 , SSqmd17 , SSqmd18 , SSqmd19 , & + SSqmd20 , SSqmd21 , SSqmd22 , SSqmd23 , SSqmd24 , SSqmd25 , SSqmd26 , & + SSqmd27 , SSqmd28 , SSqmd29 , SSqmd30 , SSqmd31 , SSqmd32 , SSqmd33 , & + SSqmd34 , SSqmd35 , SSqmd36 , SSqmd37 , SSqmd38 , SSqmd39 , SSqmd40 , & + SSqmd41 , SSqmd42 , SSqmd43 , SSqmd44 , SSqmd45 , SSqmd46 , SSqmd47 , & + SSqmd48 , SSqmd49 , SSqmd50 , SSqmd51 , SSqmd52 , SSqmd53 , SSqmd54 , & + SSqmd55 , SSqmd56 , SSqmd57 , SSqmd58 , SSqmd59 , SSqmd60 , SSqmd61 , & + SSqmd62 , SSqmd63 , SSqmd64 , SSqmd65 , SSqmd66 , SSqmd67 , SSqmd68 , & + SSqmd69 , SSqmd70 , SSqmd71 , SSqmd72 , SSqmd73 , SSqmd74 , SSqmd75 , & + SSqmd76 , SSqmd77 , SSqmd78 , SSqmd79 , SSqmd80 , SSqmd81 , SSqmd82 , & + SSqmd83 , SSqmd84 , SSqmd85 , SSqmd86 , SSqmd87 , SSqmd88 , SSqmd89 , & + SSqmd90 , SSqmd91 , SSqmd92 , SSqmd93 , SSqmd94 , SSqmd95 , SSqmd96 , & + SSqmd97 , SSqmd98 , SSqmd99 , SSqmdd01 , SSqmdd02 , SSqmdd03 , SSqmdd04 , & + SSqmdd05 , SSqmdd06 , SSqmdd07 , SSqmdd08 , SSqmdd09 , SSqmdd10 , SSqmdd11 , & + SSqmdd12 , SSqmdd13 , SSqmdd14 , SSqmdd15 , SSqmdd16 , SSqmdd17 , SSqmdd18 , & + SSqmdd19 , SSqmdd20 , SSqmdd21 , SSqmdd22 , SSqmdd23 , SSqmdd24 , SSqmdd25 , & + SSqmdd26 , SSqmdd27 , SSqmdd28 , SSqmdd29 , SSqmdd30 , SSqmdd31 , SSqmdd32 , & + SSqmdd33 , SSqmdd34 , SSqmdd35 , SSqmdd36 , SSqmdd37 , SSqmdd38 , SSqmdd39 , & + SSqmdd40 , SSqmdd41 , SSqmdd42 , SSqmdd43 , SSqmdd44 , SSqmdd45 , SSqmdd46 , & + SSqmdd47 , SSqmdd48 , SSqmdd49 , SSqmdd50 , SSqmdd51 , SSqmdd52 , SSqmdd53 , & + SSqmdd54 , SSqmdd55 , SSqmdd56 , SSqmdd57 , SSqmdd58 , SSqmdd59 , SSqmdd60 , & + SSqmdd61 , SSqmdd62 , SSqmdd63 , SSqmdd64 , SSqmdd65 , SSqmdd66 , SSqmdd67 , & + SSqmdd68 , SSqmdd69 , SSqmdd70 , SSqmdd71 , SSqmdd72 , SSqmdd73 , SSqmdd74 , & + SSqmdd75 , SSqmdd76 , SSqmdd77 , SSqmdd78 , SSqmdd79 , SSqmdd80 , SSqmdd81 , & + SSqmdd82 , SSqmdd83 , SSqmdd84 , SSqmdd85 , SSqmdd86 , SSqmdd87 , SSqmdd88 , & + SSqmdd89 , SSqmdd90 , SSqmdd91 , SSqmdd92 , SSqmdd93 , SSqmdd94 , SSqmdd95 , & + SSqmdd96 , SSqmdd97 , SSqmdd98 , SSqmdd99 /) + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(2265) = (/ & ! This lists the units corresponding to the allowed parameters + "(N) ","(N) ","(N) ","(Nm) ","(Nm) ","(Nm) ","(rad/s^2) ", & + "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & + "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & + "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & + "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & + "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & + "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & + "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & + "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & + "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & + "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & + "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & + "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & + "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & + "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & + "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & + "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & + "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & + "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & + "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & + "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & + "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & + "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & + "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & + "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & + "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & + "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & + "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & + "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & + "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & + "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & + "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & + "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & + "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & + "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & + "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & + "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & + "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & + "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & + "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & + "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & + "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & + "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & + "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & + "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & + "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & + "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & + "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & + "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & + "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & + "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & + "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & + "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & + "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & + "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & + "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & + "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & + "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & + "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & + "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & + "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & + "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & + "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & + "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & + "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & + "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & + "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & + "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & + "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & + "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & + "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & + "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & + "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & + "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & + "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & + "(m) ","(m) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ", & + "(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ", & + "(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ", & + "(m) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ", & + "(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ", & + "(m/s^2) ","(m) ","(m) ","(m) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ", & + "(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ", & + "(rad/s^2) ","(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ", & + "(m) ","(m) ","(m) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ","(N*m) ", & + "(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ","(rad) ","(rad) ","(rad) ", & + "(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ","(m) ","(m) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N*m) ","(N*m) ", & + "(N*m) ","(N*m) ","(N*m) ","(N*m) ","(rad/s^2) ","(rad/s^2) ","(rad/s^2) ", & + "(rad) ","(rad) ","(rad) ","(m/s^2) ","(m/s^2) ","(m/s^2) ","(m) ", & + "(m) ","(m) ","(N) ","(N) ","(N) ","(Nm) ","(Nm) ", & + "(Nm) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & + "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & + "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & + "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & + "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & + "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & + "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & + "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & + "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & + "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & + "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & + "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & + "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & + "(--) ","(--) ","(--) ","(--) ","(--) ","(--) ","(--) ", & + "(--) ","(--) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & + "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & + "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & + "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & + "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & + "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & + "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & + "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & + "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & + "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & + "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & + "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & + "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & + "(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ","(1/s) ", & + "(1/s) ","(1/s) ","(1/s) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & + "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & + "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & + "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & + "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & + "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & + "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & + "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & + "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & + "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & + "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & + "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & + "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & + "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) ", & + "(1/s^2) ","(1/s^2) ","(1/s^2) ","(1/s^2) "/) + + +!End of code generated by Matlab script +end module SubDyn_Output_Params diff --git a/modules/subdyn/src/SubDyn_Registry.txt b/modules/subdyn/src/SubDyn_Registry.txt index 248ce4ba22..d8d458ca59 100644 --- a/modules/subdyn/src/SubDyn_Registry.txt +++ b/modules/subdyn/src/SubDyn_Registry.txt @@ -4,219 +4,279 @@ # Use ^ as a shortcut for the value in the same column from the previous line. ################################################################################################################################### # ...... Include files (definitions from NWTC Library) ............................................................................ -include Registry_NWTC_Library.txt +include Registry_NWTC_Library.txt -# -# Keyword ModuleName/ModName Derived data type Field type Variable name Dimemsion of the variable Initial value not used Description Units +# ============================== Internal data types ============================================================================================================================================ +typedef SubDyn/SD IList INTEGER List {:} - - "List of integers" +# +typedef ^ MeshAuxDataType INTEGER MemberID - - - "Member ID for Output" +typedef ^ MeshAuxDataType INTEGER NOutCnt - - - "Number of Nodes for the output member" +typedef ^ MeshAuxDataType INTEGER NodeCnt {:} - - "Node ordinal numbers for the output member" +typedef ^ MeshAuxDataType INTEGER NodeIDs {:} - - "Node IDs associated with ordinal numbers for the output member" +typedef ^ MeshAuxDataType INTEGER ElmIDs {:}{:} - - "Element IDs connected to each NodeIDs; max 10 elements" +typedef ^ MeshAuxDataType INTEGER ElmNds {:}{:} - - "Flag to indicate 1st or 2nd node of element for each ElmIDs" +typedef ^ MeshAuxDataType R8Ki Me {:}{:}{:}{:} - - "Mass matrix connected to each joint element for outAll output" +typedef ^ MeshAuxDataType R8Ki Ke {:}{:}{:}{:} - - "Mass matrix connected to each joint element for outAll output" +typedef ^ MeshAuxDataType R8Ki Fg {:}{:}{:} - - "Gravity load vector connected to each joint element for requested member output" -# ============================== Define Initialization Inputs (from glue code) here: ============================================================================================================================================ -typedef SubDyn/SD InitInputType CHARACTER(1024) SDInputFile - - - "Name of the input file" -typedef ^ InitInputType CHARACTER(1024) RootName - - - "SubDyn rootname" -typedef ^ InitInputType ReKi g - - - "Gravity acceleration" -typedef ^ InitInputType ReKi WtrDpth - - - "Water Depth (positive valued)" -typedef ^ InitInputType ReKi TP_RefPoint {3} - - "global position of transition piece reference point (could also be defined in SubDyn itself)" -typedef ^ InitInputType ReKi SubRotateZ - - - "Rotation angle in degrees about global Z" +# CB_MatArrays: Matrices and arrays for CB summary +typedef ^ CB_MatArrays R8Ki MBB {:}{:} - - "FULL MBB ( no constraints applied)" +typedef ^ CB_MatArrays R8Ki MBM {:}{:} - - "FULL MBM ( no constraints applied)" +typedef ^ CB_MatArrays R8Ki KBB {:}{:} - - "FULL KBB ( no constraints applied)" +typedef ^ CB_MatArrays R8Ki PhiL {:}{:} - - "Retained CB modes, possibly allPhiL(nDOFL,nDOFL), or PhiL(nDOFL,nDOFM)" +typedef ^ CB_MatArrays R8Ki PhiR {:}{:} - - "FULL PhiR ( no constraints applied)" +typedef ^ CB_MatArrays R8Ki OmegaL {:} - - "Eigenvalues of retained CB modes, possibly all (nDOFL or nDOFM)" +# +typedef ^ ElemPropType IntKi eType - - - "Element Type" +typedef ^ ElemPropType ReKi Length - - - "Length of an element" +typedef ^ ElemPropType ReKi Ixx - - - "Moment of inertia of an element" +typedef ^ ElemPropType ReKi Iyy - - - "Moment of inertia of an element" +typedef ^ ElemPropType ReKi Jzz - - - "Moment of inertia of an element" +typedef ^ ElemPropType LOGICAL Shear - - - "Use timoshenko (true) E-B (false)" +typedef ^ ElemPropType ReKi Kappa - - - "Shear coefficient" +typedef ^ ElemPropType ReKi YoungE - - - "Young's modulus" +typedef ^ ElemPropType ReKi ShearG - - - "Shear modulus" N/m^2 +# Properties common to all element types: +typedef ^ ElemPropType ReKi Area - - - "Area of an element" m^2 +typedef ^ ElemPropType ReKi Rho - - - "Density" kg/m^3 +typedef ^ ElemPropType ReKi T0 - - - "Pretension " N +typedef ^ ElemPropType R8Ki DirCos {3}{3} - - "Element direction cosine matrix" -# ============================== Define Initialization outputs here: ============================================================================================================================================ -typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {:} - - "Names of the output-to-file channels" - -typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputUnt {:} - - "Units of the output-to-file channels" - -typedef ^ InitOutputType ProgDesc Ver - - - "This module's name, version, and date" - +# ============================== Input Initialization (from glue code) ============================================================================================================================================ +typedef ^ InitInputType CHARACTER(1024) SDInputFile - - - "Name of the input file" +typedef ^ InitInputType CHARACTER(1024) RootName - - - "SubDyn rootname" +typedef ^ InitInputType ReKi g - - - "Gravity acceleration" +typedef ^ InitInputType ReKi WtrDpth - - - "Water Depth (positive valued)" +typedef ^ InitInputType ReKi TP_RefPoint {3} - - "global position of transition piece reference point (could also be defined in SubDyn itself)" +typedef ^ InitInputType ReKi SubRotateZ - - - "Rotation angle in degrees about global Z" +typedef ^ InitInputType ReKi SoilStiffness ::: - - "Soil stiffness matrices from SoilDyn" '(N/m, N-m/rad)' +typedef ^ InitInputType MeshType SoilMesh - - - "Mesh for soil stiffness locations" - +typedef ^ InitInputType Logical Linearize - .FALSE. - "Flag that tells this module if the glue code wants to linearize." - -# ============================== Define Internal data types here: ============================================================================================================================================ -typedef SubDyn/SD MeshAuxDataType INTEGER MemberID - - - "Member ID for Output" -typedef ^ MeshAuxDataType INTEGER NOutCnt - - - "Number of Nodes for the output member" -typedef ^ MeshAuxDataType INTEGER NodeCnt {:} - - "Node ordinal numbers for the output member" -typedef ^ MeshAuxDataType INTEGER NodeIDs {:} - - "Node IDs associated with ordinal numbers for the output member" -typedef ^ MeshAuxDataType INTEGER ElmIDs {:}{:} - - "Element IDs connected to each NodeIDs; max 10 elements" -typedef ^ MeshAuxDataType INTEGER ElmNds {:}{:} - - "Flag to indicate 1st or 2nd node of element for each ElmIDs" -typedef ^ MeshAuxDataType INTEGER ElmID2s {2} - - "Element IDs connected to each joint node" -typedef ^ MeshAuxDataType INTEGER ElmNd2s {2} - - Flag to indicate 1st or 2nd node of element which is attached to "member joint (for outAll)" -typedef ^ MeshAuxDataType ReKi Me {:}{:}{:}{:} - - "Mass matrix connected to each joint element for outAll output" -typedef ^ MeshAuxDataType ReKi Ke {:}{:}{:}{:} - - "Mass matrix connected to each joint element for outAll output" -typedef ^ MeshAuxDataType ReKi Fg {:}{:}{:} - - "Gravity load vector connected to each joint element for requested member output" -typedef ^ MeshAuxDataType ReKi Me2 {12}{12}{2} - - "Mass matrix connected to each joint element for outAll output" -typedef ^ MeshAuxDataType ReKi Ke2 {12}{12}{2} - - "Mass matrix connected to each joint element for outAll output" -typedef ^ MeshAuxDataType ReKi Fg2 {12}{2} - - "Gravity load vector connected to each joint element for outAll output" -# CB_MatArrays: Matrices and arrays for CB summary -typedef SubDyn/SD CB_MatArrays INTEGER DOFM - - - "retained degrees of freedom (modes)" -typedef ^ CB_MatArrays ReKi TI2 {:}{:} - - "TI2 matrix to refer to total mass to (0,0,0)" -typedef ^ CB_MatArrays ReKi MBB {:}{:} - - "FULL MBB ( no constraints applied)" -typedef ^ CB_MatArrays ReKi MBM {:}{:} - - "FULL MBM ( no constraints applied)" -typedef ^ CB_MatArrays ReKi KBB {:}{:} - - "FULL KBB ( no constraints applied)" -typedef ^ CB_MatArrays ReKi PhiL {:}{:} - - "Retained CB modes, possibly allPhiL(DOFL,DOFL), or PhiL(DOFL,DOFM)" -typedef ^ CB_MatArrays ReKi PhiR {:}{:} - - "FULL PhiR ( no constraints applied)" -typedef ^ CB_MatArrays ReKi OmegaL {:} - - "Eigenvalues of retained CB modes, possibly all (DOFL or DOFM)" -# FEM_MatArrays: Matrices and arrays for FEM summary -typedef SubDyn/SD FEM_MatArrays ReKi Omega {:} - - "Eigenvalues of full FEM model, we calculate them all" -typedef ^ FEM_MatArrays INTEGER NOmega - - - "Number of full FEM Eigenvalues (for now TDOF-6*Nreact)" -typedef ^ FEM_MatArrays ReKi Modes {:}{:} - - "Eigenmodes of full FEM model, we calculate them all" +# ============================== Initialization outputs ============================================================================================================================================ +typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {:} - - "Names of the output-to-file channels" - +typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputUnt {:} - - "Units of the output-to-file channels" - +typedef ^ InitOutputType ProgDesc Ver - - - "This module's name, version, and date" - +# Linearization +typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_y {:} - - "Names of the outputs used in linearization" - +typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_x {:} - - "Names of the continuous states used in linearization" - +typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_u {:} - - "Names of the inputs used in linearization" - +typedef ^ InitOutputType LOGICAL RotFrame_y {:} - - "Flag that tells FAST/MBC3 if the outputs used in linearization are in the rotating frame" - +typedef ^ InitOutputType LOGICAL RotFrame_x {:} - - "Flag that tells FAST/MBC3 if the continuous states used in linearization are in the rotating frame (not used for glue)" - +typedef ^ InitOutputType LOGICAL RotFrame_u {:} - - "Flag that tells FAST/MBC3 if the inputs used in linearization are in the rotating frame" - +typedef ^ InitOutputType LOGICAL IsLoad_u {:} - - "Flag that tells FAST if the inputs used in linearization are loads (for preconditioning matrix)" - +typedef ^ InitOutputType IntKi DerivOrder_x {:} - - "Integer that tells FAST/MBC3 the maximum derivative order of continuous states used in linearization" - -# -typedef ^ ElemPropType ReKi Area - - - "Area of an element" -typedef ^ ^ ReKi Length - - - "Length of an element" -typedef ^ ^ ReKi Ixx - - - "Moment of inertia of an element" -typedef ^ ^ ReKi Iyy - - - "Moment of inertia of an element" -typedef ^ ^ ReKi Jzz - - - "Moment of inertia of an element" -typedef ^ ^ LOGICAL Shear - - - "Use timoshenko (true) E-B (false)" -typedef ^ ^ ReKi Kappa - - - "Shear coefficient" -typedef ^ ^ ReKi YoungE - - - "Young's modulus" -typedef ^ ^ ReKi ShearG - - - "Shear modulus" -typedef ^ ^ ReKi Rho - - - "Density" -typedef ^ ^ ReKi DirCos {3}{3} - - "Element direction cosine matrix" # ============================== Define initialization data (not from glue code) here: ============================================================================================================================================ -#--------------------------arrays and variables from the input file --------------------------------------------------------------------------------------------------------------------------------- -typedef SubDyn/SD SD_InitType CHARACTER(1024) RootName - - - "SubDyn rootname" -typedef ^ ^ ReKi TP_RefPoint {3} - - "global position of transition piece reference point (could also be defined in SubDyn itself)" -typedef ^ ^ ReKi SubRotateZ - - - "Rotation angle in degrees about global Z" -typedef ^ ^ ReKi g - - - "Gravity acceleration" -typedef ^ ^ DbKi DT - - - "Time step from Glue Code" seconds -typedef ^ ^ INTEGER NJoints - - - "Number of joints of the sub structure" -typedef ^ ^ INTEGER NPropSets - - - "Number of property sets" -typedef ^ ^ INTEGER NXPropSets - - - "Number of extended property sets" -typedef ^ ^ INTEGER NInterf - - - "Number of joints attached to transition piece" -typedef ^ ^ INTEGER NCMass - - - "Number of joints with concentrated mass" -typedef ^ ^ INTEGER NCOSMs - - - "Number of independent cosine matrices" -typedef ^ ^ INTEGER FEMMod - - - "FEM switch: element model in the FEM" -typedef ^ ^ INTEGER NDiv - - - "Number of divisions for each member" -typedef ^ ^ LOGICAL CBMod - - - "Perform C-B flag" -typedef ^ ^ ReKi Joints {:}{:} - - "Joints number and coordinate values" -typedef ^ ^ ReKi PropSets {:}{:} - - "Property sets number and values" -typedef ^ ^ ReKi XPropSets {:}{:} - - "Extended property sets" -typedef ^ ^ ReKi COSMs {:}{:} - - "Independent direction cosine matrices" -typedef ^ ^ ReKi CMass {:}{:} - - "Concentrated mass information" -typedef ^ ^ ReKi JDampings {:} - - "Damping coefficients for internal modes" -typedef ^ ^ INTEGER Members {:}{:} - - "Member joints connection" -typedef ^ ^ INTEGER Interf {:}{:} - - "Interface degree of freedoms" -typedef ^ ^ CHARACTER(ChanLen) SSOutList {:} - - "List of Output Channels" -typedef ^ ^ LOGICAL OutCOSM - - - "Output Cos-matrices Flag" -typedef ^ ^ LOGICAL TabDelim - - - "Generate a tab-delimited output file in OutJckF-Flag" -#-------------------------- arrays and variables used in the module ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -typedef ^ ^ INTEGER NNode - - - "Total number of nodes" -typedef ^ ^ INTEGER NElem - - - "Total number of elements" -typedef ^ ^ INTEGER NProp - - - "Total number of property sets" -typedef ^ ^ INTEGER TDOF - - - "Total degree of freedom" -typedef ^ ^ ReKi Nodes {:}{:} - - "Nodes number and coordinates" -typedef ^ ^ ReKi Props {:}{:} - - "Property sets and values" -typedef ^ ^ ReKi K {:}{:} - - "System stiffness matrix" -typedef ^ ^ ReKi M {:}{:} - - "System mass matrix" -typedef ^ ^ ReKi F {:} - - "System force vector" N -typedef ^ ^ ReKi FG {:} - - "Gravity force vector" N -typedef ^ ^ ReKi ElemProps {:}{:} - - "Element properties(A, L, Ixx, Iyy, Jzz, Shear, Kappa, E, G, Rho, DirCos(1,1), DirCos(2, 1), ....., DirCos(3, 3) )" -typedef ^ ^ INTEGER BCs {:}{:} - - "Boundary constraint degree of freedoms. First column - DOFs(rows in the system matrices), Second column - constrained(1) or not(0)" -typedef ^ ^ INTEGER IntFc {:}{:} - - "Interface constraint degree of freedoms" -typedef ^ ^ INTEGER MemberNodes {:}{:} - - "Member number and nodes in the member" -typedef ^ ^ INTEGER NodesConnN {:}{:} - - "Nodes that connect to a common node" -typedef ^ ^ INTEGER NodesConnE {:}{:} - - "Elements that connect to a common node" -typedef ^ ^ LOGICAL SSSum - - - "SubDyn Summary File Flag" +typedef ^ SD_InitType CHARACTER(1024) RootName - - - "SubDyn rootname" +typedef ^ SD_InitType ReKi TP_RefPoint {3} - - "global position of transition piece reference point (could also be defined in SubDyn itself)" +typedef ^ SD_InitType ReKi SubRotateZ - - - "Rotation angle in degrees about global Z" +typedef ^ SD_InitType ReKi g - - - "Gravity acceleration" +typedef ^ SD_InitType DbKi DT - - - "Time step from Glue Code" seconds +typedef ^ SD_InitType INTEGER NJoints - - - "Number of joints of the sub structure" +typedef ^ SD_InitType INTEGER NPropSetsX - - - "Number of extended property sets" +typedef ^ SD_InitType INTEGER NPropSetsB - - - "Number of property sets for beams" +typedef ^ SD_InitType INTEGER NPropSetsC - - - "Number of property sets for cables" +typedef ^ SD_InitType INTEGER NPropSetsR - - - "Number of property sets for rigid links" +typedef ^ SD_InitType INTEGER NCMass - - - "Number of joints with concentrated mass" +typedef ^ SD_InitType INTEGER NCOSMs - - - "Number of independent cosine matrices" +typedef ^ SD_InitType INTEGER FEMMod - - - "FEM switch element model in the FEM" +typedef ^ SD_InitType INTEGER NDiv - - - "Number of divisions for each member" +typedef ^ SD_InitType LOGICAL CBMod - - - "Perform C-B flag" +typedef ^ SD_InitType ReKi Joints {:}{:} - - "Joints number and coordinate values" +typedef ^ SD_InitType ReKi PropSetsB {:}{:} - - "Property sets number and values" +typedef ^ SD_InitType ReKi PropSetsC {:}{:} - - "Property ID and values for cables" +typedef ^ SD_InitType ReKi PropSetsR {:}{:} - - "Property ID and values for rigid link" +typedef ^ SD_InitType ReKi PropSetsX {:}{:} - - "Extended property sets" +typedef ^ SD_InitType ReKi COSMs {:}{:} - - "Independent direction cosine matrices" +typedef ^ SD_InitType ReKi CMass {:}{:} - - "Concentrated mass information" +typedef ^ SD_InitType ReKi JDampings {:} - - "Damping coefficients for internal modes" +typedef ^ SD_InitType IntKi GuyanDampMod - - - "Guyan damping [0=none, 1=Rayleigh Damping, 2= user specified 6x6 matrix]" +typedef ^ SD_InitType ReKi RayleighDamp {2} - - "Mass and stiffness proportional damping coefficients (Rayleigh Damping) [only if GuyanDampMod=1]" +typedef ^ SD_InitType ReKi GuyanDampMat {6}{6} - - "Guyan Damping Matrix, see also CBB" +typedef ^ SD_InitType INTEGER Members {:}{:} - - "Member joints connection " +typedef ^ SD_InitType CHARACTER(ChanLen) SSOutList {:} - - "List of Output Channels " +typedef ^ SD_InitType LOGICAL OutCOSM - - - "Output Cos-matrices Flag " +typedef ^ SD_InitType LOGICAL TabDelim - - - "Generate a tab-delimited output file in OutJckF-Flag " +typedef ^ SD_InitType R8Ki SSIK {:}{:} - - "SSI stiffness packed matrix elements (21 of them), for each reaction joint " +typedef ^ SD_InitType R8Ki SSIM {:}{:} - - "SSI mass packed matrix elements (21 of them), for each reaction joint " +typedef ^ SD_InitType CHARACTER(1024) SSIfile {:} - - "Soil Structure Interaction (SSI) files to associate with each reaction node" +typedef ^ SD_InitType ReKi Soil_K {:}{:}{:} - - "Soil stiffness (at passed at Init, not in input file) 6x6xn " +typedef ^ SD_InitType ReKi Soil_Points {:}{:} - - "Node positions where soil stiffness will be added " +typedef ^ SD_InitType Integer Soil_Nodes {:} - - "Node indices where soil stiffness will be added " +typedef ^ SD_InitType INTEGER NElem - - - "Total number of elements" +typedef ^ SD_InitType INTEGER NPropB - - - "Total number of property sets for Beams" +typedef ^ SD_InitType INTEGER NPropC - - - "Total number of property sets for Cable" +typedef ^ SD_InitType INTEGER NPropR - - - "Total number of property sets for Rigid" +typedef ^ SD_InitType ReKi Nodes {:}{:} - - "Nodes number and coordinates " +typedef ^ SD_InitType ReKi PropsB {:}{:} - - "Property sets and values for Beams " +typedef ^ SD_InitType ReKi PropsC {:}{:} - - "Property sets and values for Cable " +typedef ^ SD_InitType ReKi PropsR {:}{:} - - "Property sets and values for Rigid link" +typedef ^ SD_InitType R8Ki K {:}{:} - - "System stiffness matrix " +typedef ^ SD_InitType R8Ki M {:}{:} - - "System mass matrix " +typedef ^ SD_InitType ReKi ElemProps {:}{:} - - "Element properties(A, L, Ixx, Iyy, Jzz, Shear, Kappa, E, G, Rho, DirCos(1,1), DirCos(2, 1), ....., DirCos(3, 3) )" +typedef ^ SD_InitType INTEGER MemberNodes {:}{:} - - "Member number and list of nodes making up a member (>2 if subdivided)" +typedef ^ SD_InitType INTEGER NodesConnN {:}{:} - - "Nodes that connect to a common node " +typedef ^ SD_InitType INTEGER NodesConnE {:}{:} - - "Elements that connect to a common node" +typedef ^ SD_InitType LOGICAL SSSum - - - "SubDyn Summary File Flag " # ============================== States ============================================================================================================================================ -# Define continuous (differentiable) states here: -typedef ^ ContinuousStateType ReKi qm {:} - - "Virtual states, Nmod elements" -typedef ^ ContinuousStateType ReKi qmdot {:} - - "Derivative of states, Nmod elements" -# 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" +typedef ^ ContinuousStateType R8Ki qm {:} - - "Virtual states, Nmod elements" +typedef ^ ContinuousStateType R8Ki qmdot {:} - - "Derivative of states, Nmod elements" + +typedef ^ DiscreteStateType ReKi DummyDiscState - - - "Remove this variable if you have discrete states" -# Define any other states, including integer or logical states here: -typedef SubDyn/SD OtherStateType SD_ContinuousStateType xdot {:} - - "previous state derivs for m-step time integrator" -typedef ^ ^ IntKi n - - - "tracks time step for which OtherState was updated last" +typedef ^ ConstraintStateType ReKi DummyConstrState - - - "Remove this variable if you have constraint states" +typedef ^ OtherStateType SD_ContinuousStateType xdot {:} - - "previous state derivs for m-step time integrator" +typedef ^ ^ IntKi n - - - "tracks time step for which OtherState was updated last" # ..... 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 qmdotdot {:} - - "2nd Derivative of states, used only for output-file purposes" -typedef ^ ^ ReKi u_TP 6 - - -typedef ^ ^ ReKi udot_TP 6 - - -typedef ^ ^ ReKi udotdot_TP 6 - - -typedef ^ ^ ReKi UFL {:} - - -typedef ^ ^ ReKi UR_bar {:} - - -typedef ^ ^ ReKi UR_bar_dot {:} - - -typedef ^ ^ ReKi UR_bar_dotdot {:} - - -typedef ^ ^ ReKi UL {:} - - -typedef ^ ^ ReKi UL_dot {:} - - -typedef ^ ^ ReKi UL_dotdot {:} - - +typedef ^ MiscVarType ReKi qmdotdot {:} - - "2nd Derivative of states, used only for output-file purposes" +typedef ^ MiscVarType ReKi u_TP 6 - - +typedef ^ MiscVarType ReKi udot_TP 6 - - +typedef ^ MiscVarType ReKi udotdot_TP 6 - - +typedef ^ MiscVarType ReKi F_L {:} - - +typedef ^ MiscVarType ReKi UR_bar {:} - - +typedef ^ MiscVarType ReKi UR_bar_dot {:} - - +typedef ^ MiscVarType ReKi UR_bar_dotdot {:} - - +typedef ^ MiscVarType ReKi UL {:} - - +typedef ^ MiscVarType ReKi UL_dot {:} - - +typedef ^ MiscVarType ReKi UL_dotdot {:} - - +typedef ^ MiscVarType ReKi DU_full {:} - - "Delta U used for extra moment" +typedef ^ MiscVarType ReKi U_full {:} - - +typedef ^ MiscVarType ReKi U_full_dot {:} - - +typedef ^ MiscVarType ReKi U_full_dotdot {:} - - +typedef ^ MiscVarType ReKi U_full_elast {:} - - "Elastic displacements for computation of K ue (without rigid body mode for floating)" +typedef ^ MiscVarType ReKi U_red {:} - - +typedef ^ MiscVarType ReKi U_red_dot {:} - - +typedef ^ MiscVarType ReKi U_red_dotdot {:} - - +typedef ^ MiscVarType ReKi FC_unit {:} - - "Cable Force vector (for varying cable load, of unit cable load)" N +typedef ^ MiscVarType ReKi SDWrOutput {:} - - "Data from previous step to be written to a SubDyn output file" +typedef ^ MiscVarType DbKi LastOutTime - - - "The time of the most recent stored output data" "s" +typedef ^ MiscVarType IntKi Decimat - - - "Current output decimation counter" "-" +typedef ^ MiscVarType ReKi Fext {:} - - "External loads on unconstrained DOFs" "-" +typedef ^ MiscVarType ReKi Fext_red {:} - - "External loads on constrained DOFs, Fext_red= T^t Fext" "-" ### data for writing to an output file (this data is associated with time, but saved/written in CalcOutput so not stored as an other state) ### -typedef ^ ^ ReKi SDWrOutput {:} - - "Data from previous step to be written to a SubDyn output file" -typedef ^ ^ DbKi LastOutTime - - - "The time of the most recent stored output data" "s" -typedef ^ ^ IntKi Decimat - - - "Current output decimation counter" "-" - - # ============================== Parameters ============================================================================================================================================ -typedef ^ ParameterType DbKi SDDeltaT - - - "Time step (for integration of continuous states)" seconds -typedef ^ ParameterType Logical SttcSolve - - - "Solve dynamics about static equilibrium point (flag)" -typedef ^ ParameterType ReKi NOmegaM2 {:} - - "Coefficient of x in X (negative omegaM squared)" -typedef ^ ParameterType ReKi N2OmegaMJDamp {:} - - "Coefficient of x in X (negative 2 omegaM * JDamping)" -typedef ^ ParameterType ReKi MMB {:}{:} - - "Matrix after C-B reduction (transpose of MBM" -typedef ^ ParameterType ReKi FX {:} - - "Load components in X" -typedef ^ ParameterType ReKi C1_11 {:}{:} - - "Coefficient of x in Y1" -typedef ^ ParameterType ReKi C1_12 {:}{:} - - "Coefficient of x in Y1" -typedef ^ ParameterType ReKi D1_13 {:}{:} - - "Coefficient of u in Y1" -typedef ^ ParameterType ReKi D1_14 {:}{:} - - "Coefficient of u in Y1" -typedef ^ ParameterType ReKi FY {:} - - "Load Components in Y1" -typedef ^ ParameterType ReKi PhiM {:}{:} - - "Coefficient of x in Y2" -typedef ^ ParameterType ReKi C2_61 {:}{:} - - "Coefficient of x in Y2 (URdotdot ULdotdot)" -typedef ^ ParameterType ReKi C2_62 {:}{:} - - "Coefficient of x in Y2 (URdotdot ULdotdot)" -typedef ^ ParameterType ReKi PhiRb_TI {:}{:} - - "Coefficient of u in Y2 (Phi_R bar * TI)" -typedef ^ ParameterType ReKi D2_63 {:}{:} - - "Coefficient of u in Y2 (URdotdot ULdotdot)" -typedef ^ ParameterType ReKi D2_64 {:}{:} - - "Coefficient of u in Y2 (URdotdot ULdotdot)" -typedef ^ ParameterType ReKi F2_61 {:} - - "Load Component in Y2" -typedef ^ ParameterType ReKi MBB {:}{:} - - "Matrix after C-B reduction" -typedef ^ ParameterType ReKi KBB {:}{:} - - "Matrix after C-B reduction" -typedef ^ ParameterType ReKi MBM {:}{:} - - "Matrix after C-B reduction" -typedef ^ ParameterType ReKi PhiL_T {:}{:} - - "Transpose of Matrix of C-B modes" -typedef ^ ParameterType ReKi PhiLInvOmgL2 {:}{:} - - "Matrix of C-B modes times the inverse of OmegaL**2 (Phi_L*(Omg**2)^-1)" -typedef ^ ParameterType ReKi FGL {:} - - "Internal node DOFL, gravity loads" -typedef ^ ParameterType ReKi AM2Jac {:}{:} - - "Jacobian (factored) for Adams-Boulton 2nd order Integration" -typedef ^ ParameterType IntKi AM2JacPiv {:} - - "Pivot array for Jacobian factorization (for Adams-Boulton 2nd order Integration)" -typedef ^ ParameterType ReKi TI {:}{:} - - "Matrix to calculate TP reference point reaction at top of structure" -typedef ^ ParameterType ReKi TIreact {:}{:} - - "Matrix to calculate single point reaction at base of structure" -typedef ^ ParameterType IntKi NModes - - - "Number of modes to retain in C-B method" -typedef ^ ParameterType IntKi Elems {:}{:} - - "Element nodes connections" -typedef ^ ParameterType IntKi qmL - - - "Length of state array" -typedef ^ ParameterType IntKi DofL - - - "Internal nodes # of DOFs" -typedef ^ ParameterType IntKi NNodes_I - - - "Number of Interface nodes" -typedef ^ ParameterType IntKi NNodes_L - - - "Number of Internal nodes" -typedef ^ ParameterType IntKi NNodes_RbarL - - - "Number of Interface + Internal nodes" -typedef ^ ParameterType IntKi DofI - - - "Interface nodes # of DOFs" -typedef ^ ParameterType IntKi DofR - - - "Interface and restrained nodes # of DOFs" -typedef ^ ParameterType IntKi DofC - - - "Contrained nodes # of DOFs" -typedef ^ ParameterType IntKi NReact - - - "Number of joints with reactions" -typedef ^ ParameterType IntKi Reacts {:}{:} - - "React degree of freedoms" -typedef ^ ParameterType IntKi Nmembers - - - "Number of members of the sub structure" -typedef ^ ParameterType IntKi URbarL - - - "Length of URbar, subarray of y2 array (DOFRb)" -typedef ^ ParameterType IntKi IntMethod - - - "INtegration Method (1/2/3)Length of y2 array" -typedef ^ ParameterType IntKi NAvgEls - 2 - "Max number of elements that should be averaged when calculating outputs at nodes" -typedef ^ ParameterType IntKi IDI {:} - - "Index array of the interface(nodes connect to TP) dofs" -typedef ^ ParameterType IntKi IDR {:} - - "Index array of the interface and restraint dofs" -typedef ^ ParameterType IntKi IDL {:} - - "Index array of the internal dofs" -typedef ^ ParameterType IntKi IDC {:} - - "Index array of the contraint dofs" -typedef ^ ParameterType IntKi IDY {:} - - "Index array of the all dofs in Y2" -typedef ^ ParameterType IntKi NMOutputs - - - "Number of members whose output is written" -typedef ^ ParameterType IntKi NumOuts - - - "Number of output channels read from input file" -typedef ^ ParameterType IntKi OutSwtch - - - "Output Requested Channels to local or global output file [1/2/3]" -typedef ^ ParameterType IntKi UnJckF - - - "Unit of SD ouput file" -typedef ^ ParameterType CHARACTER(1) Delim - - - "Column delimiter for output text files" -typedef ^ ParameterType CHARACTER(20) OutFmt - - - "Format for Output" -typedef ^ ParameterType CHARACTER(20) OutSFmt - - - "Format for Output Headers" -typedef ^ ParameterType MeshAuxDataType MoutLst {:} - - "List of user requested members and nodes" -typedef ^ ParameterType MeshAuxDataType MoutLst2 {:} - - "List of all member joint nodes and elements for output" -typedef ^ ParameterType MeshAuxDataType MoutLst3 {:} - - "List of all member joint nodes and elements for output" -typedef ^ ParameterType ElemPropType ElemProps {:} - - "List of element properties" -typedef ^ ParameterType OutParmType OutParam {:} - - "An array holding names, units, and indices of all of the selected output channels. # logical" -typedef ^ ParameterType LOGICAL OutAll - - - "Flag to output or not all joint forces" -typedef ^ ParameterType LOGICAL OutReact - - - "Flag to check whether reactions are requested" -typedef ^ ParameterType IntKi OutAllInt - - - "Integer version of OutAll" -typedef ^ ParameterType IntKi OutAllDims - - - "Integer version of OutAll" -typedef ^ ParameterType IntKi OutDec - - - "Output Decimation for Requested Channels" +# --- Parameters - Algo +typedef ^ ParameterType DbKi SDDeltaT - - - "Time step (for integration of continuous states)" seconds +typedef ^ ParameterType IntKi IntMethod - - - "Integration Method (1/2/3)Length of y2 array" +# --- Parameters - FEM +typedef ^ ParameterType INTEGER nDOF - - - "Total degree of freedom" +typedef ^ ParameterType INTEGER nDOF_red - - - "Total degree of freedom after constraint reduction" +typedef ^ ParameterType IntKi Nmembers - - - "Number of members of the sub structure" +typedef ^ ParameterType IntKi Elems {:}{:} - - "Element nodes connections" +typedef ^ ParameterType ElemPropType ElemProps {:} - - "List of element properties" +typedef ^ ParameterType R8Ki FG {:} - - "Gravity force vector (with initial cable force T0), not reduced" N +typedef ^ ParameterType ReKi DP0 {:}{:} - - "Vector from TP to a Node at t=0, used for Floating Rigid Body motion" m +# --- Parameters - Constraints reduction +typedef ^ ParameterType Logical reduced - - - "True if system has been reduced to account for constraints" "-" +typedef ^ ParameterType R8Ki T_red {:}{:} - - "Transformation matrix performing the constraint reduction x = T. xtilde" "-" +typedef ^ ParameterType R8Ki T_red_T {:}{:} - - "Transpose of T_red" "-" +typedef ^ ParameterType IList NodesDOF {:} - - "DOF indices of each nodes in unconstrained assembled system " "-" +typedef ^ ParameterType IList NodesDOFred {:} - - "DOF indices of each nodes in constrained assembled system " "-" +typedef ^ ParameterType IntKi ElemsDOF {:}{:} - - "12 DOF indices of node 1 and 2 of a given member in unconstrained assembled system " "-" +typedef ^ ParameterType IntKi DOFred2Nodes {:}{:} - - "nDOFRed x 3, for each constrained DOF, col1 node index, col2 number of DOF, col3 DOF starting from 1" "-" +# --- Parameters - Control +typedef ^ ParameterType IntKi CtrlElem2Channel {:}{:} - - "nCtrlCable x 2, for each CtrlCable, Elem index, and Channel Index" +# --- Parameters - CB reduction +typedef ^ ParameterType IntKi nDOFM - - - "retained degrees of freedom (modes)" +typedef ^ ParameterType IntKi SttcSolve - - - "Solve dynamics about static equilibrium point (flag)" +typedef ^ ParameterType Logical GuyanLoadCorrection - - - "Add Extra lever arm contribution to interface reaction outputs" +typedef ^ ParameterType Logical Floating - - - "True if floating bottom (the 6 DOF are free at all reaction nodes)" +typedef ^ ParameterType ReKi KMMDiag {:} - - "Diagonal coefficients of Kmm (OmegaM squared)" +typedef ^ ParameterType ReKi CMMDiag {:} - - "Diagonal coefficients of Cmm (~2 Zeta OmegaM))" +typedef ^ ParameterType ReKi MMB {:}{:} - - "Matrix after C-B reduction (transpose of MBM" +typedef ^ ParameterType ReKi MBmmB {:}{:} - - "MBm * MmB, used for Y1" +typedef ^ ParameterType ReKi C1_11 {:}{:} - - "Coefficient of x in Y1" +typedef ^ ParameterType ReKi C1_12 {:}{:} - - "Coefficient of x in Y1" +typedef ^ ParameterType ReKi D1_141 {:}{:} - - "MBm PhiM^T" +typedef ^ ParameterType ReKi D1_142 {:}{:} - - "TI^T PhiR^T" +typedef ^ ParameterType ReKi PhiM {:}{:} - - "Coefficient of x in Y2" +typedef ^ ParameterType ReKi C2_61 {:}{:} - - "Coefficient of x in Y2 (URdotdot ULdotdot)" +typedef ^ ParameterType ReKi C2_62 {:}{:} - - "Coefficient of x in Y2 (URdotdot ULdotdot)" +typedef ^ ParameterType ReKi PhiRb_TI {:}{:} - - "Coefficient of u in Y2 (Phi_R bar * TI)" +typedef ^ ParameterType ReKi D2_63 {:}{:} - - "Coefficient of u in Y2 (URdotdot ULdotdot)" +typedef ^ ParameterType ReKi D2_64 {:}{:} - - "Coefficient of u in Y2 (URdotdot ULdotdot)" +typedef ^ ParameterType ReKi MBB {:}{:} - - "Guyan Mass Matrix after C-B reduction" +typedef ^ ParameterType ReKi KBB {:}{:} - - "Guyan Stiffness Matrix after C-B reduction" +typedef ^ ParameterType ReKi CBB {:}{:} - - "Guyan Damping Matrix after C-B reduction" +typedef ^ ParameterType ReKi CMM {:}{:} - - "CB damping matrix" +typedef ^ ParameterType ReKi MBM {:}{:} - - "Matrix after C-B reduction" +typedef ^ ParameterType ReKi PhiL_T {:}{:} - - "Transpose of Matrix of C-B modes" +typedef ^ ParameterType ReKi PhiLInvOmgL2 {:}{:} - - "Matrix of C-B modes times the inverse of OmegaL**2 (Phi_L*(Omg**2)^-1)" +typedef ^ ParameterType ReKi KLLm1 {:}{:} - - "KLL^{-1}, inverse of matrix KLL, for static solve only" +typedef ^ ParameterType ReKi AM2Jac {:}{:} - - "Jacobian (factored) for Adams-Boulton 2nd order Integration" +typedef ^ ParameterType IntKi AM2JacPiv {:} - - "Pivot array for Jacobian factorization (for Adams-Boulton 2nd order Integration)" +typedef ^ ParameterType ReKi TI {:}{:} - - "Matrix to calculate TP reference point reaction at top of structure" +typedef ^ ParameterType ReKi TIreact {:}{:} - - "Matrix to calculate single point reaction at base of structure" +# --- Parameters - Partitioning I L C Y, R=[C I] +typedef ^ ParameterType IntKi nNodes - - - "Total number of nodes" +typedef ^ ParameterType IntKi nNodes_I - - - "Number of Interface nodes" +typedef ^ ParameterType IntKi nNodes_L - - - "Number of Internal nodes" +typedef ^ ParameterType IntKi nNodes_C - - - "Number of joints with reactions" +typedef ^ ParameterType IntKi Nodes_I {:}{:} - - "Interface degree of freedoms" +typedef ^ ParameterType IntKi Nodes_L {:}{:} - - "Internal nodes (not interface nor reaction)" +typedef ^ ParameterType IntKi Nodes_C {:}{:} - - "React degree of freedoms" +typedef ^ ParameterType IntKi nDOFI__ - - - "Size of IDI__" +typedef ^ ParameterType IntKi nDOFI_Rb - - - "Size of IDI_Rb" +typedef ^ ParameterType IntKi nDOFI_F - - - "Size of IDI_F" +typedef ^ ParameterType IntKi nDOFL_L - - - "Size of IDL_L" +typedef ^ ParameterType IntKi nDOFC__ - - - "Size of IDC__" +typedef ^ ParameterType IntKi nDOFC_Rb - - - "Size of IDC_Rb" +typedef ^ ParameterType IntKi nDOFC_L - - - "Size of IDC_L" +typedef ^ ParameterType IntKi nDOFC_F - - - "Size of IDC_F" +typedef ^ ParameterType IntKi nDOFR__ - - - "Size of IDR__" +typedef ^ ParameterType IntKi nDOF__Rb - - - "Size of ID__Rb" +typedef ^ ParameterType IntKi nDOF__L - - - "Size of ID__L" +typedef ^ ParameterType IntKi nDOF__F - - - "Size of ID__F" +typedef ^ ParameterType IntKi IDI__ {:} - - "Index of all Interface DOFs" +typedef ^ ParameterType IntKi IDI_Rb {:} - - "Index array of the interface (nodes connect to TP) dofs that are retained/master/follower DOFs" +typedef ^ ParameterType IntKi IDI_F {:} - - "Index array of the interface (nodes connect to TP) dofs that are fixed DOF" +typedef ^ ParameterType IntKi IDL_L {:} - - "Index array of the internal dofs coming from internal nodes" +typedef ^ ParameterType IntKi IDC__ {:} - - "Index of all bottom DOF" +typedef ^ ParameterType IntKi IDC_Rb {:} - - "Index array of the contraint dofs that are retained/master/follower DOF" +typedef ^ ParameterType IntKi IDC_L {:} - - "Index array of the contraint dofs that are follower/internal DOF" +typedef ^ ParameterType IntKi IDC_F {:} - - "Index array of the contraint dofs that are fixd DOF" +typedef ^ ParameterType IntKi IDR__ {:} - - "Index array of the interface and restraint dofs" +typedef ^ ParameterType IntKi ID__Rb {:} - - "Index array of all the retained/leader/master dofs (from any nodes of the structure)" +typedef ^ ParameterType IntKi ID__L {:} - - "Index array of all the follower/internal dofs (from any nodes of the structure)" +typedef ^ ParameterType IntKi ID__F {:} - - "Index array of the DOF that are fixed (from any nodes of the structure)" +# --- Parameters - Outputs +typedef ^ ParameterType IntKi NMOutputs - - - "Number of members whose output is written" +typedef ^ ParameterType IntKi NumOuts - - - "Number of output channels read from input file" +typedef ^ ParameterType IntKi OutSwtch - - - "Output Requested Channels to local or global output file [1/2/3]" +typedef ^ ParameterType IntKi UnJckF - - - "Unit of SD ouput file" +typedef ^ ParameterType CHARACTER(1) Delim - - - "Column delimiter for output text files" +typedef ^ ParameterType CHARACTER(20) OutFmt - - - "Format for Output" +typedef ^ ParameterType CHARACTER(20) OutSFmt - - - "Format for Output Headers" +typedef ^ ParameterType MeshAuxDataType MoutLst {:} - - "List of user requested members and nodes" +typedef ^ ParameterType MeshAuxDataType MoutLst2 {:} - - "List of all member joint nodes and elements for output" +typedef ^ ParameterType MeshAuxDataType MoutLst3 {:} - - "List of all member joint nodes and elements for output" +typedef ^ ParameterType OutParmType OutParam {:} - - "An array holding names, units, and indices of all of the selected output channels. # logical" +typedef ^ ParameterType LOGICAL OutAll - - - "Flag to output or not all joint forces" +typedef ^ ParameterType LOGICAL OutReact - - - "Flag to check whether reactions are requested" +typedef ^ ParameterType IntKi OutAllInt - - - "Integer version of OutAll" +typedef ^ ParameterType IntKi OutAllDims - - - "Integer version of OutAll" +typedef ^ ParameterType IntKi OutDec - - - "Output Decimation for Requested Channels" +# --- Parametesr - Linearization +typedef ^ ParameterType Integer Jac_u_indx {:}{:} - - "matrix to help fill/pack the u vector in computing the jacobian" - +typedef ^ ParameterType R8Ki du {:} - - "vector that determines size of perturbation for u (inputs)" +typedef ^ ParameterType R8Ki dx {2} - - "vector that determines size of perturbation for x (continuous states)" +typedef ^ ParameterType Integer Jac_ny - - - "number of outputs in jacobian matrix" - +typedef ^ ParameterType Integer Jac_nx - - - "half the number of continuous states in jacobian matrix" - +typedef ^ ParameterType logical RotStates - - - "Orient states in rotating frame during linearization? (flag)" - # ============================== Inputs ============================================================================================================================================ -typedef ^ InputType MeshType TPMesh - - - "Transition piece inputs on a point mesh" -typedef ^ InputType MeshType LMesh - - - "Point mesh for interior node inputs" +typedef ^ InputType MeshType TPMesh - - - "Transition piece inputs on a point mesh" +typedef ^ InputType MeshType LMesh - - - "Point mesh for interior node inputs" +typedef ^ InputType ReKi CableDeltaL {:} - - "Cable tension, control input" # ============================== Outputs ============================================================================================================================================ -typedef ^ OutputType MeshType Y1Mesh - - - "Transition piece outputs on a point mesh" -typedef ^ OutputType MeshType Y2Mesh - - - "Interior+Interface nodes outputs on a point mesh" -typedef ^ OutputType ReKi WriteOutput {:} - - "Data to be written to an output file" +typedef ^ OutputType MeshType Y1Mesh - - - "Transition piece outputs on a point mesh" +typedef ^ OutputType MeshType Y2Mesh - - - "Interior+Interface nodes outputs on a point mesh" +typedef ^ OutputType ReKi WriteOutput {:} - - "Data to be written to an output file" diff --git a/modules/subdyn/src/SubDyn_Tests.f90 b/modules/subdyn/src/SubDyn_Tests.f90 new file mode 100644 index 0000000000..138435f85f --- /dev/null +++ b/modules/subdyn/src/SubDyn_Tests.f90 @@ -0,0 +1,549 @@ +module SubDyn_Tests + use NWTC_Library + use SubDyn_Types + use SD_FEM + use IntegerList + + implicit none + + public :: SD_Tests + private + + character(len=255),save :: testname + interface test_equal; module procedure & + test_equal_i1, & + test_equal_i0 + end interface + interface test_almost_equal; module procedure & + test_almost_equal_0, & + test_almost_equal_1, & + test_almost_equal_1d, & + test_almost_equal_2, & + test_almost_equal_2d + end interface +contains + + ! -------------------------------------------------------------------------------- + ! --- Helper functions (should be part of NWTC library) + ! -------------------------------------------------------------------------------- + subroutine test_success(info,bPrint_in) + character(len=*), intent(in) :: info + logical, intent(in), optional :: bPrint_in + if(present(bPrint_in)) then + if(bPrint_in) then + write(*,'(A)')'[ OK ] '//trim(testname)//': '//trim(Info) + endif + else + write(*,'(A)')'[ OK ] '//trim(testname)//': '//trim(Info) + endif + end subroutine + + subroutine test_fail(info,bPrint_in,bStop_in) + character(len=*), intent(in) :: info + logical, intent(in), optional :: bPrint_in + logical, intent(in), optional :: bStop_in + if(present(bPrint_in)) then + if(bPrint_in) then + write(*,'(A)')'[FAIL] '//trim(testname)//': '//trim(Info) + endif + else + write(*,'(A)')'[FAIL] '//trim(testname)//': '//trim(Info) + endif + if(present(bStop_in)) then + if(bStop_in) then + STOP + endif + else + STOP + endif + end subroutine + + subroutine test_equal_i0(Var,iTry,iRef) + ! Arguments + character(len=*), intent(in) :: Var + integer, intent(in) :: iTry !< + integer, intent(in) :: iRef !< + ! Variables + character(len=255) :: InfoAbs + if(iRef/=iTry) then + write(InfoAbs,'(A,I0,A,I0)') trim(Var),iRef,'/',iTry + call test_fail(InfoAbs) + STOP + else + write(InfoAbs,'(A,A,I0)') trim(Var),' ok ',iRef + call test_success(InfoAbs) + endif + end subroutine + + subroutine test_equal_i1(Var,VecTry,VecRef,bTest,bPrintOnly,bPassed) + ! Arguments + character(len=*), intent(in) :: Var + integer, dimension(:), intent(in) :: VecTry !< + integer, dimension(:), intent(in) :: VecRef !< + logical, intent(in) :: bTest + logical, intent(in) :: bPrintOnly + logical, intent(out),optional :: bPassed + ! Variables + character(len=255) :: InfoAbs + integer :: i,cpt + ! + cpt=0 + do i=1,size(VecRef) + if(VecRef(i)/=VecTry(i)) then + cpt=cpt+1 + endif + enddo + if(cpt>0) then + write(InfoAbs,'(A,I0)') trim(Var)//' Elements different: ',cpt + if(present(bPassed)) then + bPassed=.false. + endif + else + write(InfoAbs,'(A)') trim(Var)//' reproduced to identity' + if(present(bPassed)) then + bPassed=.true. + endif + endif + if(bPrintOnly) then + print'(A)',trim(InfoAbs) + endif + if(bTest) then + if(cpt>0) then + call test_fail(InfoAbs) + STOP + else + call test_success(InfoAbs) + endif + endif + end subroutine + + subroutine test_almost_equal_0(Var,Ref,Try,MINNORM,bStop,bPrint,bPassed) + ! Arguments + character(len=*), intent(in) :: Var + real(ReKi), intent(in) :: Ref !< + real(ReKi), intent(in) :: Try !< + real(ReKi), intent(in) :: MINNORM + logical, intent(in) :: bStop + logical, intent(in) :: bPrint + logical, intent(out),optional :: bPassed + ! Variables + character(len=255) :: InfoAbs + real(ReKi) :: delta + integer :: cpt + ! + cpt=0 + delta=abs(Ref-Try) + if(delta>MINNORM) then + write(InfoAbs,'(A,ES8.1E2,A,ES8.1E2,A,I0)') trim(Var)//' tol: ',MINNORM,', mean: ',delta,' - Failed:',cpt + call test_fail(InfoAbs,bPrint,bStop) + else + write(InfoAbs,'(A,ES8.1E2,A,ES8.1E2)') trim(Var)//' tol: ',MINNORM,', mean: ',delta + call test_success(InfoAbs,bPrint) + endif + if(present(bPassed)) then + bPassed=delta>MINNORM + endif + end subroutine + subroutine test_almost_equal_1(Var,VecRef,VecTry,MINNORM,bStop,bPrint,bPassed) + ! Arguments + character(len=*), intent(in) :: Var + real(SiKi), dimension(:), intent(in) :: VecRef !< + real(SiKi), dimension(:), intent(in) :: VecTry !< + real(SiKi), intent(in) :: MINNORM + logical, intent(in) :: bStop + logical, intent(in) :: bPrint + logical, intent(out),optional :: bPassed + ! Variables + character(len=255) :: InfoAbs + integer :: i,cpt + real(SiKi) :: delta + real(SiKi) :: delta_cum + ! + cpt=0 + delta_cum=0.0_SiKi + do i=1,size(VecRef,1) + delta=abs(VecRef(i)-VecTry(i)) + delta_cum=delta_cum+delta + if(delta>MINNORM) then + cpt=cpt+1 + endif + enddo + delta_cum=delta_cum/size(VecRef) + + if(cpt>0) then + write(InfoAbs,'(A,ES8.1E2,A,ES8.1E2,A,I0)') trim(Var)//' tol: ',MINNORM,', mean: ',delta_cum,' - Failed:',cpt + call test_fail(InfoAbs,bPrint,bStop) + else + write(InfoAbs,'(A,ES8.1E2,A,ES8.1E2)') trim(Var)//' tol: ',MINNORM,', mean: ',delta_cum + call test_success(InfoAbs,bPrint) + endif + if(present(bPassed)) then + bPassed=(cpt==0) + endif + end subroutine + subroutine test_almost_equal_1d(Var,VecRef,VecTry,MINNORM,bStop,bPrint,bPassed) + ! Arguments + character(len=*), intent(in) :: Var + real(R8Ki), dimension(:), intent(in) :: VecRef !< + real(R8Ki), dimension(:), intent(in) :: VecTry !< + real(R8Ki), intent(in) :: MINNORM + logical, intent(in) :: bStop + logical, intent(in) :: bPrint + logical, intent(out),optional :: bPassed + ! Variables + character(len=255) :: InfoAbs + integer :: i,cpt + real(R8Ki) :: delta + real(R8Ki) :: delta_cum + ! + cpt=0 + delta_cum=0.0_R8Ki + do i=1,size(VecRef,1) + delta=abs(VecRef(i)-VecTry(i)) + delta_cum=delta_cum+delta + if(delta>MINNORM) then + cpt=cpt+1 + endif + enddo + delta_cum=delta_cum/size(VecRef) + + if(cpt>0) then + write(InfoAbs,'(A,ES8.1E2,A,ES8.1E2,A,I0)') trim(Var)//' tol: ',MINNORM,', mean: ',delta_cum,' - Failed:',cpt + call test_fail(InfoAbs,bPrint,bStop) + else + write(InfoAbs,'(A,ES8.1E2,A,ES8.1E2)') trim(Var)//' tol: ',MINNORM,', mean: ',delta_cum + call test_success(InfoAbs,bPrint) + endif + if(present(bPassed)) then + bPassed=(cpt==0) + endif + end subroutine + subroutine test_almost_equal_2(Var,VecRef,VecTry,MINNORM,bStop,bPrint,bPassed) + ! Arguments + character(len=*), intent(in) :: Var + real(SiKi), dimension(:,:), intent(in) :: VecRef !< + real(SiKi), dimension(:,:), intent(in) :: VecTry !< + real(SiKi), intent(in) :: MINNORM + logical, intent(in) :: bStop + logical, intent(in) :: bPrint + logical, intent(out),optional :: bPassed + ! Variables + real(SiKi), dimension(:),allocatable :: VecRef2 !< + real(SiKi), dimension(:),allocatable :: VecTry2 !< + integer :: p, i,j,n1,n2,nCPs + ! + n1 = size(VecRef,1); n2 = size(VecRef,2); nCPs=n1*n2 + allocate ( VecRef2 (n1*n2) ) ; allocate ( VecTry2 (n1*n2) ) + p=0 + do j=1,n2; do i=1,n1 + p=p+1 + VecRef2(p)=VecRef(i,j) + VecTry2(p)=VecTry(i,j) + enddo; enddo; + call test_almost_equal(Var,VecRef2,VecTry2,MINNORM,bStop,bPrint,bPassed) + end subroutine + subroutine test_almost_equal_2d(Var,VecRef,VecTry,MINNORM,bStop,bPrint,bPassed) + ! Arguments + character(len=*), intent(in) :: Var + real(R8Ki), dimension(:,:), intent(in) :: VecRef !< + real(R8Ki), dimension(:,:), intent(in) :: VecTry !< + real(R8Ki), intent(in) :: MINNORM + logical, intent(in) :: bStop + logical, intent(in) :: bPrint + logical, intent(out),optional :: bPassed + ! Variables + real(R8Ki), dimension(:),allocatable :: VecRef2 !< + real(R8Ki), dimension(:),allocatable :: VecTry2 !< + integer :: p, i,j,n1,n2,nCPs + ! + n1 = size(VecRef,1); n2 = size(VecRef,2); nCPs=n1*n2 + allocate ( VecRef2 (n1*n2) ) ; allocate ( VecTry2 (n1*n2) ) + p=0 + do j=1,n2; do i=1,n1 + p=p+1 + VecRef2(p)=VecRef(i,j) + VecTry2(p)=VecTry(i,j) + enddo; enddo; + call test_almost_equal(Var,VecRef2,VecTry2,MINNORM,bStop,bPrint,bPassed) + end subroutine + + + + ! --------------------------------------------------------------------------------} + ! --- Specific SubDyn tests + ! --------------------------------------------------------------------------------{ + subroutine Test_CB_Results(MBBt, MBMt, KBBt, OmegaM, DOFTP, DOFM, ErrStat, ErrMsg) + INTEGER(IntKi) :: DOFTP, DOFM + REAL(ReKi) :: MBBt(DOFTP, DOFTP) + REAL(ReKi) :: MBmt(DOFTP, DOFM) + REAL(ReKi) :: KBBt(DOFTP, DOFTP) + REAL(ReKi) :: OmegaM(DOFM) + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! local variables + INTEGER(IntKi) :: DOFT, NM, i + REAL(ReKi), Allocatable :: OmegaCB(:), PhiCB(:, :) + REAL(ReKi), Allocatable :: K(:, :) + REAL(ReKi), Allocatable :: M(:, :) + Character(1024) :: rootname + ErrStat = ErrID_None + ErrMsg = '' + print*,'This test is not a unit test' + + DOFT = DOFTP + DOFM + NM = DOFT - 3 + Allocate( OmegaCB(NM), K(DOFT, DOFT), M(DOFT, DOFT), PhiCB(DOFT, NM) ) + K = 0.0 + M = 0.0 + OmegaCB = 0.0 + PhiCB = 0.0 + + M(1:DOFTP, 1:DOFTP) = MBBt + M(1:DOFTP, (DOFTP+1):DOFT ) = MBMt + M((DOFTP+1):DOFT, 1:DOFTP ) = transpose(mbmt) + + DO i = 1, DOFM + K(DOFTP+i, DOFTP+i) = OmegaM(i)*OmegaM(i) + M(DOFTP+i, DOFTP+i) = 1.0 + ENDDO + + K(1:DOFTP, 1:DOFTP) = KBBt + + ! temporary rootname + rootname = './test_assemble_C-B_out' + + ! NOTE: Eigensolve is in SubDyn + !CALL EigenSolve(K, M, DOFT, NM,.False.,Init,p, PhiCB, OmegaCB, ErrStat, ErrMsg) + IF ( ErrStat /= 0 ) RETURN + end subroutine Test_CB_Results + + !> Transformation matrices tests + subroutine Test_Transformations(ErrStat,ErrMsg) + integer(IntKi) , intent(out) :: ErrStat + character(ErrMsgLen), intent(out) :: ErrMsg + + real(ReKi), dimension(3) :: P1, P2, e1, e2, e3 + real(FEKi), dimension(3,3) :: DirCos, Ref + real(ReKi), dimension(6,6) :: T, Tref + real(ReKi) :: L + integer(IntKi) :: I + testname='Transf' + + ! --- DirCos + P1=(/0,0,0/) + P2=(/2,0,0/) + call GetDirCos(P1, P2, DirCos, L, ErrStat, ErrMsg) + Ref = reshape( (/0_FEKi,-1_FEKi,0_FEKi, 0_FEKi, 0_FEKi, -1_FEKi, 1_FEKi, 0_FEKi, 0_FEKi/) , (/3,3/)) + call test_almost_equal('DirCos',Ref,DirCos,1e-8_FEKi,.true.,.true.) + + ! --- Rigid Transo + P1=(/1,2,-1/) + P2=(/2,5,5/) + call GetRigidTransformation(P1, P2, T, ErrStat, ErrMsg) + Tref = 0; do I=1,6; Tref(I,I) =1_ReKi; enddo + Tref(1,5) = 6._ReKi; Tref(1,6) =-3._ReKi; + Tref(2,4) =-6._ReKi; Tref(2,6) = 1._ReKi; + Tref(3,4) = 3._ReKi; Tref(3,5) =-1._ReKi; + call test_almost_equal('TRigid',Tref,T,1e-8_ReKi,.true.,.true.) + + + ! --- Orthogonal vectors + e1 = (/10,0,0/) + call GetOrthVectors(e1,e2,e3,ErrStat, ErrMsg) + call test_almost_equal('orth',e2,(/0._ReKi,0._ReKi,-1._ReKi/),1e-8_ReKi,.true.,.true.) + call test_almost_equal('orth',e3,(/0._ReKi,1._ReKi, 0._ReKi/),1e-8_ReKi,.true.,.true.) + e1 = (/0,10,0/) + call GetOrthVectors(e1,e2,e3,ErrStat, ErrMsg) + call test_almost_equal('orth',e2,(/0._ReKi,0._ReKi, 1._ReKi/),1e-8_ReKi,.true.,.true.) + call test_almost_equal('orth',e3,(/1._ReKi,0._ReKi, 0._ReKi/),1e-8_ReKi,.true.,.true.) + e1 = (/1,2,4/) + call GetOrthVectors(e1,e2,e3,ErrStat, ErrMsg) + call test_almost_equal('dot', 0._ReKi, dot_product(e1,e2), 1e-8_ReKi, .true., .true.) + call test_almost_equal('dot', 0._ReKi, dot_product(e1,e3), 1e-8_ReKi, .true., .true.) + end subroutine Test_Transformations + + + !> Linear algebra tests + subroutine Test_Linalg(ErrStat,ErrMsg) + integer(IntKi) , intent(out) :: ErrStat + character(ErrMsgLen), intent(out) :: ErrMsg + real(FEKi), dimension(:,:), allocatable :: A, Ainv, Aref + real(DbKi) :: det + testname='Linalg' + + ! --- Determinant of a singular matrix + ! Commented since might lead to floating invalid + !allocate(A(3,3)); + !A(1,1) = 0 ; A(1,2) = 0 ; A(1,3) = 1 ; + !A(2,1) = 0 ; A(2,2) = 0 ; A(2,3) = -1 ; + !A(3,1) =-3 ; A(3,2) = 4 ; A(3,3) = -2 ; + !det = Determinant(A,ErrStat, ErrMsg) + !call test_almost_equal('Det of singular 3x3 matrix', real(det,ReKi), 0.0_ReKi, 1e-8_ReKi, .true. , .true.) + !deallocate(A ) + + ! --- Inverse and determinant of a 3x3 matrix + allocate(A(3,3)); allocate(Aref(3,3)) + A(1,1) = 7 ; A(1,2) = 2 ; A(1,3) = 1 ; + A(2,1) = 0 ; A(2,2) = 3 ; A(2,3) = -1 ; + A(3,1) =-3 ; A(3,2) = 4 ; A(3,3) = -2 ; + Aref(1,1) =-2 ; Aref(1,2) = 8 ; Aref(1,3) = -5 ; + Aref(2,1) = 3 ; Aref(2,2) =-11; Aref(2,3) = 7 ; + Aref(3,1) = 9 ; Aref(3,2) =-34; Aref(3,3) = 21; + call PseudoInverse(A, Ainv, ErrStat, ErrMsg) + ! Determinant test + det = Determinant(A,ErrStat, ErrMsg) + call test_almost_equal('Det of 3x3 matrix', real(det,ReKi), 1.0_ReKi, 1e-8_ReKi, .true. , .true.) + det = Determinant(Ainv,ErrStat, ErrMsg) + call test_almost_equal('Det of 3x3 matrix', real(det,ReKi), 1.0_ReKi, 1e-8_ReKi, .true. , .true.) + ! Inverse test + call test_almost_equal('Inverse of 3x3 matrix', real(Aref,ReKi), real(Ainv,ReKi), 1e-8_ReKi, .true., .true.) + deallocate(A ) + deallocate(Ainv) + deallocate(Aref) + + ! --- Inverse of a 3x6 matrix + allocate(A(3,6)) + allocate(Aref(6,3)) + A(1,:) = (/ 0, 1, 2, 0, 1, 2 /) + A(2,:) = (/ -1, 1, 2, -0, 0, 0 /) + A(3,:) = (/ -0, 0, 0, -1, 1, 2 /) + Aref(:,:) = transpose(reshape( (/ 0.500000, -0.583333, -0.416667, 0.100000, 0.083333, -0.083333 , 0.200000, 0.166667, -0.166667 , 0.500000, -0.416667, -0.583333 , 0.100000, -0.083333, 0.083333 , 0.200000, -0.166667, 0.166667 /), (/ 3, 6 /))) + call PseudoInverse(A, Ainv, ErrStat, ErrMsg) + call test_almost_equal('Inverse of 3x6 matrix', real(Aref,ReKi), real(Ainv,ReKi), 1e-6_ReKi, .true., .true.) + deallocate(A ) + deallocate(Ainv) + deallocate(Aref) + + ! --- Inverse of a 6x3 matrix + allocate(A(6,3)) + allocate(Aref(3,6)) + A(:,1) = (/ 0, 1, 2, 0, 1, 2 /) + A(:,2) = (/ -1, 1, 2, -0, 0, 0 /) + A(:,3) = (/ -0, 0, 0, -1, 1, 2 /) + Aref(:,:) = reshape( (/ 0.500000, -0.583333, -0.416667, 0.100000, 0.083333, -0.083333 , 0.200000, 0.166667, -0.166667 , 0.500000, -0.416667, -0.583333 , 0.100000, -0.083333, 0.083333 , 0.200000, -0.166667, 0.166667 /), (/ 3, 6 /)) + call PseudoInverse(A, Ainv, ErrStat, ErrMsg) + call test_almost_equal('Inverse of 6x3 matrix', real(Aref,ReKi), real(Ainv,ReKi), 1e-6_ReKi, .true., .true.) + end subroutine Test_Linalg + + !> Series of tests for integer lists + subroutine Test_lists(ErrStat,ErrMsg) + integer(IntKi) , intent(out) :: ErrStat + character(ErrMsgLen), intent(out) :: ErrMsg + type(IList) :: L1 + type(IList) :: L2 + integer(IntKi) :: e + ErrStat = ErrID_None + ErrMsg = "" + testname='Lists' + + call init_list(L1, 0, 0 ,ErrStat, ErrMsg) + call init_list(L2, 10, 12,ErrStat, ErrMsg) + + ! test len + call test_equal('length',0 ,len(L1)) + call test_equal('length',10,len(L2)) + + ! test append + call append(L1, 5, ErrStat, ErrMsg) + call append(L1, 3, ErrStat, ErrMsg) + call append(L1, 1, ErrStat, ErrMsg) + call test_equal('appnd',L1%List, (/5,3,1/) , .true. , .false.) + + ! test get + call test_equal('get ',get(L1,2, ErrStat, ErrMsg), 3) + e = get(L1,0, ErrStat, ErrMsg) + call test_equal('get <0 ', ErrStat, ErrID_Fatal) + e = get(L1,7, ErrStat, ErrMsg) + call test_equal('get >n ', ErrStat, ErrID_Fatal) + + ! test sort + call sort(L1, ErrStat, ErrMsg) + call test_equal('sort ',L1%List, (/1,3,5/) , .true. , .false.) + + ! test reverse + call reverse(L1, ErrStat, ErrMsg) + call test_equal('rev ',L1%List, (/5,3,1/) , .true. , .false.) + + ! test pop + e = pop(L1, ErrStat, ErrMsg) + call test_equal('pop ',e , 1) + e = pop(L1, ErrStat, ErrMsg) + call test_equal('pop ',e , 3) + e = pop(L1, ErrStat, ErrMsg) + call test_equal('pop ',e , 5) + call destroy_list(L1, ErrStat, ErrMsg) + + ! test unique + call init_list(L1,(/5,3,2,3,8/),ErrStat, ErrMsg) + call unique(L1, ErrStat, ErrMsg) + call test_equal('uniq ',L1%List, (/5,3,2,8/) , .true. , .false.) + + call destroy_list(L1, ErrStat, ErrMsg) + call destroy_list(L2, ErrStat, ErrMsg) + end subroutine Test_lists + + !> Test CheckBoard (from FEM), useful for joint stiffness + subroutine Test_ChessBoard(ErrStat,ErrMsg) + integer(IntKi) , intent(out) :: ErrStat + character(ErrMsgLen), intent(out) :: ErrMsg + real(ReKi), dimension(:,:), allocatable :: M, Mref + ErrStat = ErrID_None + ErrMsg = "" + testname='ChessBoard' + allocate(M(1:6,1:6), Mref(1:6,1:6)) + ! Typical example for pin joint Stiffness add + Mref(1 , :)= (/4 , -1 , -1 , -1 , -1, -1/) + Mref(2 , :)= (/-1 , 4 , -1 , -1 , -1, -1/) + Mref(3 , :)= (/-1 , -1 , 4 , -1 , -1, -1/) + Mref(4 , :)= (/-1 , -1 , -1 , 4 , -1, -1/) + Mref(5 , :)= (/-1 , -1 , -1 , -1 , 4, -1/) + Mref(6 , :)= (/-1 , -1 , -1 , -1 , -1, 4/) + call ChessBoard(M, -1._ReKi, -10._ReKi, nSpace=0, diagVal=4._ReKi) + call test_almost_equal('ChessBoardPin', Mref, M, 1e-6_ReKi, .true., .true.) + + ! Typical example for universal joint Stiffness add + Mref=0.0_ReKi + Mref(1 , :)= (/2 , 0 , -1 , 0 , -1, 0 /) + Mref(2 , :)= (/0 , 2 , 0 , -1 , 0, -1 /) + Mref(3 , :)= (/-1 , 0 , 2 , 0 , -1, 0 /) + Mref(4 , :)= (/ 0 , -1 , 0 , 2 , 0, -1 /) + Mref(5 , :)= (/-1 , 0 , -1 , 0 , 2, 0 /) + Mref(6 , :)= (/ 0 , -1 , 0 , -1 , 0, 2 /) + call ChessBoard(M, -1._ReKi, 0._ReKi, nSpace=1, diagVal=2._ReKi) + call test_almost_equal('ChessBoardUnv', Mref, M, 1e-6_ReKi, .true., .true.) + + ! Typical example for ball joint Stiffness add + Mref(1 , :)= (/ 1 , 0 , 0 , -1 , 0, 0 /) + Mref(2 , :)= (/ 0 , 1 , 0 , 0 , -1, 0 /) + Mref(3 , :)= (/ 0 , 0 , 1 , 0 , 0, -1 /) + Mref(4 , :)= (/-1 , 0 , 0 , 1 , 0, 0 /) + Mref(5 , :)= (/ 0 , -1 , 0 , 0 , 1, 0 /) + Mref(6 , :)= (/ 0 , 0 , -1 , 0 , 0, 1 /) + call ChessBoard(M, -1._ReKi, 0._ReKi, nSpace=2, diagVal=1._ReKi) + call test_almost_equal('ChessBoardBll', Mref, M, 1e-6_ReKi, .true., .true.) + + deallocate(M,Mref) + end subroutine Test_ChessBoard + + subroutine SD_Tests(ErrStat,ErrMsg) + integer(IntKi) , intent(out) :: ErrStat !< Error status of the operation + character(ErrMsgLen), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + + call Test_lists(ErrStat2, ErrMsg2); if(Failed()) return + call Test_Transformations(ErrStat2, ErrMsg2); if(Failed()) return + call Test_Linalg(ErrStat2, ErrMsg2); if(Failed()) return + call Test_ChessBoard(ErrStat2, ErrMsg2); if(Failed()) return + contains + logical function Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SD_Tests') + Failed = ErrStat >= AbortErrLev + end function failed + end subroutine SD_Tests + + +end module SubDyn_Tests diff --git a/modules/subdyn/src/SubDyn_Types.f90 b/modules/subdyn/src/SubDyn_Types.f90 index 31efd0db7d..6a0d60bdad 100644 --- a/modules/subdyn/src/SubDyn_Types.f90 +++ b/modules/subdyn/src/SubDyn_Types.f90 @@ -33,22 +33,10 @@ MODULE SubDyn_Types !--------------------------------------------------------------------------------------------------------------------------------- USE NWTC_Library IMPLICIT NONE -! ========= SD_InitInputType ======= - TYPE, PUBLIC :: SD_InitInputType - CHARACTER(1024) :: SDInputFile !< Name of the input file [-] - CHARACTER(1024) :: RootName !< SubDyn rootname [-] - REAL(ReKi) :: g !< Gravity acceleration [-] - REAL(ReKi) :: WtrDpth !< Water Depth (positive valued) [-] - REAL(ReKi) , DIMENSION(1:3) :: TP_RefPoint !< global position of transition piece reference point (could also be defined in SubDyn itself) [-] - REAL(ReKi) :: SubRotateZ !< Rotation angle in degrees about global Z [-] - END TYPE SD_InitInputType -! ======================= -! ========= SD_InitOutputType ======= - TYPE, PUBLIC :: SD_InitOutputType - CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< Names of the output-to-file channels [-] - CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputUnt !< Units of the output-to-file channels [-] - TYPE(ProgDesc) :: Ver !< This module's name, version, and date [-] - END TYPE SD_InitOutputType +! ========= IList ======= + TYPE, PUBLIC :: IList + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: List !< List of integers [-] + END TYPE IList ! ======================= ! ========= MeshAuxDataType ======= TYPE, PUBLIC :: MeshAuxDataType @@ -58,38 +46,24 @@ MODULE SubDyn_Types INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: NodeIDs !< Node IDs associated with ordinal numbers for the output member [-] INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: ElmIDs !< Element IDs connected to each NodeIDs; max 10 elements [-] INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: ElmNds !< Flag to indicate 1st or 2nd node of element for each ElmIDs [-] - INTEGER(IntKi) , DIMENSION(1:2) :: ElmID2s !< Element IDs connected to each joint node [-] - INTEGER(IntKi) , DIMENSION(1:2) :: ElmNd2s !< Flag [to] - REAL(ReKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Me !< Mass matrix connected to each joint element for outAll output [-] - REAL(ReKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Ke !< Mass matrix connected to each joint element for outAll output [-] - REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Fg !< Gravity load vector connected to each joint element for requested member output [-] - REAL(ReKi) , DIMENSION(1:12,1:12,1:2) :: Me2 !< Mass matrix connected to each joint element for outAll output [-] - REAL(ReKi) , DIMENSION(1:12,1:12,1:2) :: Ke2 !< Mass matrix connected to each joint element for outAll output [-] - REAL(ReKi) , DIMENSION(1:12,1:2) :: Fg2 !< Gravity load vector connected to each joint element for outAll output [-] + REAL(R8Ki) , DIMENSION(:,:,:,:), ALLOCATABLE :: Me !< Mass matrix connected to each joint element for outAll output [-] + REAL(R8Ki) , DIMENSION(:,:,:,:), ALLOCATABLE :: Ke !< Mass matrix connected to each joint element for outAll output [-] + REAL(R8Ki) , DIMENSION(:,:,:), ALLOCATABLE :: Fg !< Gravity load vector connected to each joint element for requested member output [-] END TYPE MeshAuxDataType ! ======================= ! ========= CB_MatArrays ======= TYPE, PUBLIC :: CB_MatArrays - INTEGER(IntKi) :: DOFM !< retained degrees of freedom (modes) [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: TI2 !< TI2 matrix to refer to total mass to (0,0,0) [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: MBB !< FULL MBB ( no constraints applied) [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: MBM !< FULL MBM ( no constraints applied) [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: KBB !< FULL KBB ( no constraints applied) [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PhiL !< Retained CB modes, possibly allPhiL(DOFL,DOFL), or PhiL(DOFL,DOFM) [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PhiR !< FULL PhiR ( no constraints applied) [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: OmegaL !< Eigenvalues of retained CB modes, possibly all (DOFL or DOFM) [-] + REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: MBB !< FULL MBB ( no constraints applied) [-] + REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: MBM !< FULL MBM ( no constraints applied) [-] + REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: KBB !< FULL KBB ( no constraints applied) [-] + REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: PhiL !< Retained CB modes, possibly allPhiL(nDOFL,nDOFL), or PhiL(nDOFL,nDOFM) [-] + REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: PhiR !< FULL PhiR ( no constraints applied) [-] + REAL(R8Ki) , DIMENSION(:), ALLOCATABLE :: OmegaL !< Eigenvalues of retained CB modes, possibly all (nDOFL or nDOFM) [-] END TYPE CB_MatArrays ! ======================= -! ========= FEM_MatArrays ======= - TYPE, PUBLIC :: FEM_MatArrays - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Omega !< Eigenvalues of full FEM model, we calculate them all [-] - INTEGER(IntKi) :: NOmega !< Number of full FEM Eigenvalues (for now TDOF-6*Nreact) [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Modes !< Eigenmodes of full FEM model, we calculate them all [-] - END TYPE FEM_MatArrays -! ======================= ! ========= ElemPropType ======= TYPE, PUBLIC :: ElemPropType - REAL(ReKi) :: Area !< Area of an element [-] + INTEGER(IntKi) :: eType !< Element Type [-] REAL(ReKi) :: Length !< Length of an element [-] REAL(ReKi) :: Ixx !< Moment of inertia of an element [-] REAL(ReKi) :: Iyy !< Moment of inertia of an element [-] @@ -97,11 +71,41 @@ MODULE SubDyn_Types LOGICAL :: Shear !< Use timoshenko (true) E-B (false) [-] REAL(ReKi) :: Kappa !< Shear coefficient [-] REAL(ReKi) :: YoungE !< Young's modulus [-] - REAL(ReKi) :: ShearG !< Shear modulus [-] - REAL(ReKi) :: Rho !< Density [-] - REAL(ReKi) , DIMENSION(1:3,1:3) :: DirCos !< Element direction cosine matrix [-] + REAL(ReKi) :: ShearG !< Shear modulus [N/m^2] + REAL(ReKi) :: Area !< Area of an element [m^2] + REAL(ReKi) :: Rho !< Density [kg/m^3] + REAL(ReKi) :: T0 !< Pretension [N] + REAL(R8Ki) , DIMENSION(1:3,1:3) :: DirCos !< Element direction cosine matrix [-] END TYPE ElemPropType ! ======================= +! ========= SD_InitInputType ======= + TYPE, PUBLIC :: SD_InitInputType + CHARACTER(1024) :: SDInputFile !< Name of the input file [-] + CHARACTER(1024) :: RootName !< SubDyn rootname [-] + REAL(ReKi) :: g !< Gravity acceleration [-] + REAL(ReKi) :: WtrDpth !< Water Depth (positive valued) [-] + REAL(ReKi) , DIMENSION(1:3) :: TP_RefPoint !< global position of transition piece reference point (could also be defined in SubDyn itself) [-] + REAL(ReKi) :: SubRotateZ !< Rotation angle in degrees about global Z [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: SoilStiffness !< Soil stiffness matrices from SoilDyn ['(N/m,] + TYPE(MeshType) :: SoilMesh !< Mesh for soil stiffness locations [-] + LOGICAL :: Linearize = .FALSE. !< Flag that tells this module if the glue code wants to linearize. [-] + END TYPE SD_InitInputType +! ======================= +! ========= SD_InitOutputType ======= + TYPE, PUBLIC :: SD_InitOutputType + CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< Names of the output-to-file channels [-] + CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputUnt !< Units of the output-to-file channels [-] + TYPE(ProgDesc) :: Ver !< This module's name, version, and date [-] + CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_y !< Names of the outputs used in linearization [-] + CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_x !< Names of the continuous states used in linearization [-] + CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_u !< Names of the inputs used in linearization [-] + LOGICAL , DIMENSION(:), ALLOCATABLE :: RotFrame_y !< Flag that tells FAST/MBC3 if the outputs used in linearization are in the rotating frame [-] + LOGICAL , DIMENSION(:), ALLOCATABLE :: RotFrame_x !< Flag that tells FAST/MBC3 if the continuous states used in linearization are in the rotating frame (not used for glue) [-] + LOGICAL , DIMENSION(:), ALLOCATABLE :: RotFrame_u !< Flag that tells FAST/MBC3 if the inputs used in linearization are in the rotating frame [-] + LOGICAL , DIMENSION(:), ALLOCATABLE :: IsLoad_u !< Flag that tells FAST if the inputs used in linearization are loads (for preconditioning matrix) [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: DerivOrder_x !< Integer that tells FAST/MBC3 the maximum derivative order of continuous states used in linearization [-] + END TYPE SD_InitOutputType +! ======================= ! ========= SD_InitType ======= TYPE, PUBLIC :: SD_InitType CHARACTER(1024) :: RootName !< SubDyn rootname [-] @@ -110,48 +114,57 @@ MODULE SubDyn_Types REAL(ReKi) :: g !< Gravity acceleration [-] REAL(DbKi) :: DT !< Time step from Glue Code [seconds] INTEGER(IntKi) :: NJoints !< Number of joints of the sub structure [-] - INTEGER(IntKi) :: NPropSets !< Number of property sets [-] - INTEGER(IntKi) :: NXPropSets !< Number of extended property sets [-] - INTEGER(IntKi) :: NInterf !< Number of joints attached to transition piece [-] + INTEGER(IntKi) :: NPropSetsX !< Number of extended property sets [-] + INTEGER(IntKi) :: NPropSetsB !< Number of property sets for beams [-] + INTEGER(IntKi) :: NPropSetsC !< Number of property sets for cables [-] + INTEGER(IntKi) :: NPropSetsR !< Number of property sets for rigid links [-] INTEGER(IntKi) :: NCMass !< Number of joints with concentrated mass [-] INTEGER(IntKi) :: NCOSMs !< Number of independent cosine matrices [-] - INTEGER(IntKi) :: FEMMod !< FEM switch: element model in the FEM [-] + INTEGER(IntKi) :: FEMMod !< FEM switch element model in the FEM [-] INTEGER(IntKi) :: NDiv !< Number of divisions for each member [-] LOGICAL :: CBMod !< Perform C-B flag [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Joints !< Joints number and coordinate values [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PropSets !< Property sets number and values [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: XPropSets !< Extended property sets [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PropSetsB !< Property sets number and values [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PropSetsC !< Property ID and values for cables [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PropSetsR !< Property ID and values for rigid link [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PropSetsX !< Extended property sets [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: COSMs !< Independent direction cosine matrices [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: CMass !< Concentrated mass information [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: JDampings !< Damping coefficients for internal modes [-] - INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: Members !< Member joints connection [-] - INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: Interf !< Interface degree of freedoms [-] - CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: SSOutList !< List of Output Channels [-] - LOGICAL :: OutCOSM !< Output Cos-matrices Flag [-] - LOGICAL :: TabDelim !< Generate a tab-delimited output file in OutJckF-Flag [-] - INTEGER(IntKi) :: NNode !< Total number of nodes [-] + INTEGER(IntKi) :: GuyanDampMod !< Guyan damping [0=none, 1=Rayleigh Damping, 2= user specified 6x6 matrix] [-] + REAL(ReKi) , DIMENSION(1:2) :: RayleighDamp !< Mass and stiffness proportional damping coefficients (Rayleigh Damping) [only if GuyanDampMod=1] [-] + REAL(ReKi) , DIMENSION(1:6,1:6) :: GuyanDampMat !< Guyan Damping Matrix, see also CBB [-] + INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: Members !< Member joints connection [-] + CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: SSOutList !< List of Output Channels [-] + LOGICAL :: OutCOSM !< Output Cos-matrices Flag [-] + LOGICAL :: TabDelim !< Generate a tab-delimited output file in OutJckF-Flag [-] + REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: SSIK !< SSI stiffness packed matrix elements (21 of them), for each reaction joint [-] + REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: SSIM !< SSI mass packed matrix elements (21 of them), for each reaction joint [-] + CHARACTER(1024) , DIMENSION(:), ALLOCATABLE :: SSIfile !< Soil Structure Interaction (SSI) files to associate with each reaction node [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Soil_K !< Soil stiffness (at passed at Init, not in input file) 6x6xn [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Soil_Points !< Node positions where soil stiffness will be added [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: Soil_Nodes !< Node indices where soil stiffness will be added [-] INTEGER(IntKi) :: NElem !< Total number of elements [-] - INTEGER(IntKi) :: NProp !< Total number of property sets [-] - INTEGER(IntKi) :: TDOF !< Total degree of freedom [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Nodes !< Nodes number and coordinates [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Props !< Property sets and values [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: K !< System stiffness matrix [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: M !< System mass matrix [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: F !< System force vector [N] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FG !< Gravity force vector [N] + INTEGER(IntKi) :: NPropB !< Total number of property sets for Beams [-] + INTEGER(IntKi) :: NPropC !< Total number of property sets for Cable [-] + INTEGER(IntKi) :: NPropR !< Total number of property sets for Rigid [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Nodes !< Nodes number and coordinates [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PropsB !< Property sets and values for Beams [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PropsC !< Property sets and values for Cable [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PropsR !< Property sets and values for Rigid link [-] + REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: K !< System stiffness matrix [-] + REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: M !< System mass matrix [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: ElemProps !< Element properties(A, L, Ixx, Iyy, Jzz, Shear, Kappa, E, G, Rho, DirCos(1,1), DirCos(2, 1), ....., DirCos(3, 3) ) [-] - INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: BCs !< Boundary constraint degree of freedoms. First column - DOFs(rows in the system matrices), Second column - constrained(1) or not(0) [-] - INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: IntFc !< Interface constraint degree of freedoms [-] - INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: MemberNodes !< Member number and nodes in the member [-] - INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: NodesConnN !< Nodes that connect to a common node [-] + INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: MemberNodes !< Member number and list of nodes making up a member (>2 if subdivided) [-] + INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: NodesConnN !< Nodes that connect to a common node [-] INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: NodesConnE !< Elements that connect to a common node [-] - LOGICAL :: SSSum !< SubDyn Summary File Flag [-] + LOGICAL :: SSSum !< SubDyn Summary File Flag [-] END TYPE SD_InitType ! ======================= ! ========= SD_ContinuousStateType ======= TYPE, PUBLIC :: SD_ContinuousStateType - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: qm !< Virtual states, Nmod elements [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: qmdot !< Derivative of states, Nmod elements [-] + REAL(R8Ki) , DIMENSION(:), ALLOCATABLE :: qm !< Virtual states, Nmod elements [-] + REAL(R8Ki) , DIMENSION(:), ALLOCATABLE :: qmdot !< Derivative of states, Nmod elements [-] END TYPE SD_ContinuousStateType ! ======================= ! ========= SD_DiscreteStateType ======= @@ -176,69 +189,109 @@ MODULE SubDyn_Types REAL(ReKi) , DIMENSION(1:6) :: u_TP REAL(ReKi) , DIMENSION(1:6) :: udot_TP REAL(ReKi) , DIMENSION(1:6) :: udotdot_TP - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: UFL + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: F_L REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: UR_bar REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: UR_bar_dot REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: UR_bar_dotdot REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: UL REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: UL_dot REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: UL_dotdot + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: DU_full !< Delta U used for extra moment [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: U_full + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: U_full_dot + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: U_full_dotdot + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: U_full_elast !< Elastic displacements for computation of K ue (without rigid body mode for floating) [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: U_red + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: U_red_dot + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: U_red_dotdot + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FC_unit !< Cable Force vector (for varying cable load, of unit cable load) [N] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: SDWrOutput !< Data from previous step to be written to a SubDyn output file [-] REAL(DbKi) :: LastOutTime !< The time of the most recent stored output data [s] INTEGER(IntKi) :: Decimat !< Current output decimation counter [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Fext !< External loads on unconstrained DOFs [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Fext_red !< External loads on constrained DOFs, Fext_red= T^t Fext [-] END TYPE SD_MiscVarType ! ======================= ! ========= SD_ParameterType ======= TYPE, PUBLIC :: SD_ParameterType REAL(DbKi) :: SDDeltaT !< Time step (for integration of continuous states) [seconds] - LOGICAL :: SttcSolve !< Solve dynamics about static equilibrium point (flag) [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: NOmegaM2 !< Coefficient of x in X (negative omegaM squared) [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: N2OmegaMJDamp !< Coefficient of x in X (negative 2 omegaM * JDamping) [-] + INTEGER(IntKi) :: IntMethod !< Integration Method (1/2/3)Length of y2 array [-] + INTEGER(IntKi) :: nDOF !< Total degree of freedom [-] + INTEGER(IntKi) :: nDOF_red !< Total degree of freedom after constraint reduction [-] + INTEGER(IntKi) :: Nmembers !< Number of members of the sub structure [-] + INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: Elems !< Element nodes connections [-] + TYPE(ElemPropType) , DIMENSION(:), ALLOCATABLE :: ElemProps !< List of element properties [-] + REAL(R8Ki) , DIMENSION(:), ALLOCATABLE :: FG !< Gravity force vector (with initial cable force T0), not reduced [N] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: DP0 !< Vector from TP to a Node at t=0, used for Floating Rigid Body motion [m] + LOGICAL :: reduced !< True if system has been reduced to account for constraints [-] + REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: T_red !< Transformation matrix performing the constraint reduction x = T. xtilde [-] + REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: T_red_T !< Transpose of T_red [-] + TYPE(IList) , DIMENSION(:), ALLOCATABLE :: NodesDOF !< DOF indices of each nodes in unconstrained assembled system [-] + TYPE(IList) , DIMENSION(:), ALLOCATABLE :: NodesDOFred !< DOF indices of each nodes in constrained assembled system [-] + INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: ElemsDOF !< 12 DOF indices of node 1 and 2 of a given member in unconstrained assembled system [-] + INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: DOFred2Nodes !< nDOFRed x 3, for each constrained DOF, col1 node index, col2 number of DOF, col3 DOF starting from 1 [-] + INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: CtrlElem2Channel !< nCtrlCable x 2, for each CtrlCable, Elem index, and Channel Index [-] + INTEGER(IntKi) :: nDOFM !< retained degrees of freedom (modes) [-] + INTEGER(IntKi) :: SttcSolve !< Solve dynamics about static equilibrium point (flag) [-] + LOGICAL :: GuyanLoadCorrection !< Add Extra lever arm contribution to interface reaction outputs [-] + LOGICAL :: Floating !< True if floating bottom (the 6 DOF are free at all reaction nodes) [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: KMMDiag !< Diagonal coefficients of Kmm (OmegaM squared) [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: CMMDiag !< Diagonal coefficients of Cmm (~2 Zeta OmegaM)) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: MMB !< Matrix after C-B reduction (transpose of MBM [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FX !< Load components in X [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: MBmmB !< MBm * MmB, used for Y1 [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: C1_11 !< Coefficient of x in Y1 [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: C1_12 !< Coefficient of x in Y1 [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D1_13 !< Coefficient of u in Y1 [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D1_14 !< Coefficient of u in Y1 [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FY !< Load Components in Y1 [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D1_141 !< MBm PhiM^T [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D1_142 !< TI^T PhiR^T [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PhiM !< Coefficient of x in Y2 [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: C2_61 !< Coefficient of x in Y2 (URdotdot ULdotdot) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: C2_62 !< Coefficient of x in Y2 (URdotdot ULdotdot) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PhiRb_TI !< Coefficient of u in Y2 (Phi_R bar * TI) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D2_63 !< Coefficient of u in Y2 (URdotdot ULdotdot) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D2_64 !< Coefficient of u in Y2 (URdotdot ULdotdot) [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: F2_61 !< Load Component in Y2 [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: MBB !< Matrix after C-B reduction [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: KBB !< Matrix after C-B reduction [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: MBB !< Guyan Mass Matrix after C-B reduction [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: KBB !< Guyan Stiffness Matrix after C-B reduction [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: CBB !< Guyan Damping Matrix after C-B reduction [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: CMM !< CB damping matrix [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: MBM !< Matrix after C-B reduction [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PhiL_T !< Transpose of Matrix of C-B modes [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PhiLInvOmgL2 !< Matrix of C-B modes times the inverse of OmegaL**2 (Phi_L*(Omg**2)^-1) [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FGL !< Internal node DOFL, gravity loads [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: KLLm1 !< KLL^{-1}, inverse of matrix KLL, for static solve only [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: AM2Jac !< Jacobian (factored) for Adams-Boulton 2nd order Integration [-] INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: AM2JacPiv !< Pivot array for Jacobian factorization (for Adams-Boulton 2nd order Integration) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: TI !< Matrix to calculate TP reference point reaction at top of structure [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: TIreact !< Matrix to calculate single point reaction at base of structure [-] - INTEGER(IntKi) :: NModes !< Number of modes to retain in C-B method [-] - INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: Elems !< Element nodes connections [-] - INTEGER(IntKi) :: qmL !< Length of state array [-] - INTEGER(IntKi) :: DofL !< Internal nodes of DOFs [-] - INTEGER(IntKi) :: NNodes_I !< Number of Interface nodes [-] - INTEGER(IntKi) :: NNodes_L !< Number of Internal nodes [-] - INTEGER(IntKi) :: NNodes_RbarL !< Number of Interface + Internal nodes [-] - INTEGER(IntKi) :: DofI !< Interface nodes of DOFs [-] - INTEGER(IntKi) :: DofR !< Interface and restrained nodes of DOFs [-] - INTEGER(IntKi) :: DofC !< Contrained nodes of DOFs [-] - INTEGER(IntKi) :: NReact !< Number of joints with reactions [-] - INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: Reacts !< React degree of freedoms [-] - INTEGER(IntKi) :: Nmembers !< Number of members of the sub structure [-] - INTEGER(IntKi) :: URbarL !< Length of URbar, subarray of y2 array (DOFRb) [-] - INTEGER(IntKi) :: IntMethod !< INtegration Method (1/2/3)Length of y2 array [-] - INTEGER(IntKi) :: NAvgEls = 2 !< Max number of elements that should be averaged when calculating outputs at nodes [-] - INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: IDI !< Index array of the interface(nodes connect to TP) dofs [-] - INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: IDR !< Index array of the interface and restraint dofs [-] - INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: IDL !< Index array of the internal dofs [-] - INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: IDC !< Index array of the contraint dofs [-] - INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: IDY !< Index array of the all dofs in Y2 [-] + INTEGER(IntKi) :: nNodes !< Total number of nodes [-] + INTEGER(IntKi) :: nNodes_I !< Number of Interface nodes [-] + INTEGER(IntKi) :: nNodes_L !< Number of Internal nodes [-] + INTEGER(IntKi) :: nNodes_C !< Number of joints with reactions [-] + INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: Nodes_I !< Interface degree of freedoms [-] + INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: Nodes_L !< Internal nodes (not interface nor reaction) [-] + INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: Nodes_C !< React degree of freedoms [-] + INTEGER(IntKi) :: nDOFI__ !< Size of IDI__ [-] + INTEGER(IntKi) :: nDOFI_Rb !< Size of IDI_Rb [-] + INTEGER(IntKi) :: nDOFI_F !< Size of IDI_F [-] + INTEGER(IntKi) :: nDOFL_L !< Size of IDL_L [-] + INTEGER(IntKi) :: nDOFC__ !< Size of IDC__ [-] + INTEGER(IntKi) :: nDOFC_Rb !< Size of IDC_Rb [-] + INTEGER(IntKi) :: nDOFC_L !< Size of IDC_L [-] + INTEGER(IntKi) :: nDOFC_F !< Size of IDC_F [-] + INTEGER(IntKi) :: nDOFR__ !< Size of IDR__ [-] + INTEGER(IntKi) :: nDOF__Rb !< Size of ID__Rb [-] + INTEGER(IntKi) :: nDOF__L !< Size of ID__L [-] + INTEGER(IntKi) :: nDOF__F !< Size of ID__F [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: IDI__ !< Index of all Interface DOFs [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: IDI_Rb !< Index array of the interface (nodes connect to TP) dofs that are retained/master/follower DOFs [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: IDI_F !< Index array of the interface (nodes connect to TP) dofs that are fixed DOF [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: IDL_L !< Index array of the internal dofs coming from internal nodes [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: IDC__ !< Index of all bottom DOF [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: IDC_Rb !< Index array of the contraint dofs that are retained/master/follower DOF [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: IDC_L !< Index array of the contraint dofs that are follower/internal DOF [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: IDC_F !< Index array of the contraint dofs that are fixd DOF [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: IDR__ !< Index array of the interface and restraint dofs [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: ID__Rb !< Index array of all the retained/leader/master dofs (from any nodes of the structure) [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: ID__L !< Index array of all the follower/internal dofs (from any nodes of the structure) [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: ID__F !< Index array of the DOF that are fixed (from any nodes of the structure) [-] INTEGER(IntKi) :: NMOutputs !< Number of members whose output is written [-] INTEGER(IntKi) :: NumOuts !< Number of output channels read from input file [-] INTEGER(IntKi) :: OutSwtch !< Output Requested Channels to local or global output file [1/2/3] [-] @@ -249,19 +302,25 @@ MODULE SubDyn_Types TYPE(MeshAuxDataType) , DIMENSION(:), ALLOCATABLE :: MoutLst !< List of user requested members and nodes [-] TYPE(MeshAuxDataType) , DIMENSION(:), ALLOCATABLE :: MoutLst2 !< List of all member joint nodes and elements for output [-] TYPE(MeshAuxDataType) , DIMENSION(:), ALLOCATABLE :: MoutLst3 !< List of all member joint nodes and elements for output [-] - TYPE(ElemPropType) , DIMENSION(:), ALLOCATABLE :: ElemProps !< List of element properties [-] TYPE(OutParmType) , DIMENSION(:), ALLOCATABLE :: OutParam !< An array holding names, units, and indices of all of the selected output channels. logical [-] LOGICAL :: OutAll !< Flag to output or not all joint forces [-] LOGICAL :: OutReact !< Flag to check whether reactions are requested [-] INTEGER(IntKi) :: OutAllInt !< Integer version of OutAll [-] INTEGER(IntKi) :: OutAllDims !< Integer version of OutAll [-] INTEGER(IntKi) :: OutDec !< Output Decimation for Requested Channels [-] + INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: Jac_u_indx !< matrix to help fill/pack the u vector in computing the jacobian [-] + REAL(R8Ki) , DIMENSION(:), ALLOCATABLE :: du !< vector that determines size of perturbation for u (inputs) [-] + REAL(R8Ki) , DIMENSION(1:2) :: dx !< vector that determines size of perturbation for x (continuous states) [-] + INTEGER(IntKi) :: Jac_ny !< number of outputs in jacobian matrix [-] + INTEGER(IntKi) :: Jac_nx !< half the number of continuous states in jacobian matrix [-] + LOGICAL :: RotStates !< Orient states in rotating frame during linearization? (flag) [-] END TYPE SD_ParameterType ! ======================= ! ========= SD_InputType ======= TYPE, PUBLIC :: SD_InputType TYPE(MeshType) :: TPMesh !< Transition piece inputs on a point mesh [-] TYPE(MeshType) :: LMesh !< Point mesh for interior node inputs [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: CableDeltaL !< Cable tension, control input [-] END TYPE SD_InputType ! ======================= ! ========= SD_OutputType ======= @@ -272,9 +331,9 @@ MODULE SubDyn_Types END TYPE SD_OutputType ! ======================= CONTAINS - SUBROUTINE SD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(SD_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(SD_InitInputType), INTENT(INOUT) :: DstInitInputData + SUBROUTINE SD_CopyIList( SrcIListData, DstIListData, CtrlCode, ErrStat, ErrMsg ) + TYPE(IList), INTENT(IN) :: SrcIListData + TYPE(IList), INTENT(INOUT) :: DstIListData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -286,34 +345,43 @@ SUBROUTINE SD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrSt INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyInitInput' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyIList' ! ErrStat = ErrID_None ErrMsg = "" - DstInitInputData%SDInputFile = SrcInitInputData%SDInputFile - DstInitInputData%RootName = SrcInitInputData%RootName - DstInitInputData%g = SrcInitInputData%g - DstInitInputData%WtrDpth = SrcInitInputData%WtrDpth - DstInitInputData%TP_RefPoint = SrcInitInputData%TP_RefPoint - DstInitInputData%SubRotateZ = SrcInitInputData%SubRotateZ - END SUBROUTINE SD_CopyInitInput +IF (ALLOCATED(SrcIListData%List)) THEN + i1_l = LBOUND(SrcIListData%List,1) + i1_u = UBOUND(SrcIListData%List,1) + IF (.NOT. ALLOCATED(DstIListData%List)) THEN + ALLOCATE(DstIListData%List(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstIListData%List.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstIListData%List = SrcIListData%List +ENDIF + END SUBROUTINE SD_CopyIList - SUBROUTINE SD_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) - TYPE(SD_InitInputType), INTENT(INOUT) :: InitInputData + SUBROUTINE SD_DestroyIList( IListData, ErrStat, ErrMsg ) + TYPE(IList), INTENT(INOUT) :: IListData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyInitInput' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyIList' INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 ! ErrStat = ErrID_None ErrMsg = "" - END SUBROUTINE SD_DestroyInitInput +IF (ALLOCATED(IListData%List)) THEN + DEALLOCATE(IListData%List) +ENDIF + END SUBROUTINE SD_DestroyIList - SUBROUTINE SD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE SD_PackIList( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(SD_InitInputType), INTENT(IN) :: InData + TYPE(IList), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -328,7 +396,7 @@ SUBROUTINE SD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_PackInitInput' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_PackIList' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -344,12 +412,11 @@ SUBROUTINE SD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1*LEN(InData%SDInputFile) ! SDInputFile - Int_BufSz = Int_BufSz + 1*LEN(InData%RootName) ! RootName - Re_BufSz = Re_BufSz + 1 ! g - Re_BufSz = Re_BufSz + 1 ! WtrDpth - Re_BufSz = Re_BufSz + SIZE(InData%TP_RefPoint) ! TP_RefPoint - Re_BufSz = Re_BufSz + 1 ! SubRotateZ + Int_BufSz = Int_BufSz + 1 ! List allocated yes/no + IF ( ALLOCATED(InData%List) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! List upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%List) ! List + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -377,31 +444,28 @@ SUBROUTINE SD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Db_Xferred = 1 Int_Xferred = 1 - DO I = 1, LEN(InData%SDInputFile) - IntKiBuf(Int_Xferred) = ICHAR(InData%SDInputFile(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - DO I = 1, LEN(InData%RootName) - IntKiBuf(Int_Xferred) = ICHAR(InData%RootName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - ReKiBuf(Re_Xferred) = InData%g - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%WtrDpth - Re_Xferred = Re_Xferred + 1 - DO i1 = LBOUND(InData%TP_RefPoint,1), UBOUND(InData%TP_RefPoint,1) - ReKiBuf(Re_Xferred) = InData%TP_RefPoint(i1) - Re_Xferred = Re_Xferred + 1 - END DO - ReKiBuf(Re_Xferred) = InData%SubRotateZ - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE SD_PackInitInput + IF ( .NOT. ALLOCATED(InData%List) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%List,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%List,1) + Int_Xferred = Int_Xferred + 2 - SUBROUTINE SD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + DO i1 = LBOUND(InData%List,1), UBOUND(InData%List,1) + IntKiBuf(Int_Xferred) = InData%List(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + END SUBROUTINE SD_PackIList + + SUBROUTINE SD_UnPackIList( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(SD_InitInputType), INTENT(INOUT) :: OutData + TYPE(IList), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -416,7 +480,7 @@ SUBROUTINE SD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackInitInput' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackIList' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -427,153 +491,256 @@ SUBROUTINE SD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - DO I = 1, LEN(OutData%SDInputFile) - OutData%SDInputFile(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - DO I = 1, LEN(OutData%RootName) - OutData%RootName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%g = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%WtrDpth = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - i1_l = LBOUND(OutData%TP_RefPoint,1) - i1_u = UBOUND(OutData%TP_RefPoint,1) - DO i1 = LBOUND(OutData%TP_RefPoint,1), UBOUND(OutData%TP_RefPoint,1) - OutData%TP_RefPoint(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%SubRotateZ = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE SD_UnPackInitInput + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! List not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%List)) DEALLOCATE(OutData%List) + ALLOCATE(OutData%List(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%List.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%List,1), UBOUND(OutData%List,1) + OutData%List(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + END SUBROUTINE SD_UnPackIList - SUBROUTINE SD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(SD_InitOutputType), INTENT(IN) :: SrcInitOutputData - TYPE(SD_InitOutputType), INTENT(INOUT) :: DstInitOutputData + SUBROUTINE SD_CopyMeshAuxDataType( SrcMeshAuxDataTypeData, DstMeshAuxDataTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MeshAuxDataType), INTENT(IN) :: SrcMeshAuxDataTypeData + TYPE(MeshAuxDataType), INTENT(INOUT) :: DstMeshAuxDataTypeData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyInitOutput' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyMeshAuxDataType' ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(SrcInitOutputData%WriteOutputHdr)) THEN - i1_l = LBOUND(SrcInitOutputData%WriteOutputHdr,1) - i1_u = UBOUND(SrcInitOutputData%WriteOutputHdr,1) - IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputHdr)) THEN - ALLOCATE(DstInitOutputData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) + DstMeshAuxDataTypeData%MemberID = SrcMeshAuxDataTypeData%MemberID + DstMeshAuxDataTypeData%NOutCnt = SrcMeshAuxDataTypeData%NOutCnt +IF (ALLOCATED(SrcMeshAuxDataTypeData%NodeCnt)) THEN + i1_l = LBOUND(SrcMeshAuxDataTypeData%NodeCnt,1) + i1_u = UBOUND(SrcMeshAuxDataTypeData%NodeCnt,1) + IF (.NOT. ALLOCATED(DstMeshAuxDataTypeData%NodeCnt)) THEN + ALLOCATE(DstMeshAuxDataTypeData%NodeCnt(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMeshAuxDataTypeData%NodeCnt.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInitOutputData%WriteOutputHdr = SrcInitOutputData%WriteOutputHdr + DstMeshAuxDataTypeData%NodeCnt = SrcMeshAuxDataTypeData%NodeCnt ENDIF -IF (ALLOCATED(SrcInitOutputData%WriteOutputUnt)) THEN - i1_l = LBOUND(SrcInitOutputData%WriteOutputUnt,1) - i1_u = UBOUND(SrcInitOutputData%WriteOutputUnt,1) - IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputUnt)) THEN - ALLOCATE(DstInitOutputData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMeshAuxDataTypeData%NodeIDs)) THEN + i1_l = LBOUND(SrcMeshAuxDataTypeData%NodeIDs,1) + i1_u = UBOUND(SrcMeshAuxDataTypeData%NodeIDs,1) + IF (.NOT. ALLOCATED(DstMeshAuxDataTypeData%NodeIDs)) THEN + ALLOCATE(DstMeshAuxDataTypeData%NodeIDs(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMeshAuxDataTypeData%NodeIDs.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInitOutputData%WriteOutputUnt = SrcInitOutputData%WriteOutputUnt + DstMeshAuxDataTypeData%NodeIDs = SrcMeshAuxDataTypeData%NodeIDs ENDIF - CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE SD_CopyInitOutput - - SUBROUTINE SD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) - TYPE(SD_InitOutputType), INTENT(INOUT) :: InitOutputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyInitOutput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN - DEALLOCATE(InitOutputData%WriteOutputHdr) +IF (ALLOCATED(SrcMeshAuxDataTypeData%ElmIDs)) THEN + i1_l = LBOUND(SrcMeshAuxDataTypeData%ElmIDs,1) + i1_u = UBOUND(SrcMeshAuxDataTypeData%ElmIDs,1) + i2_l = LBOUND(SrcMeshAuxDataTypeData%ElmIDs,2) + i2_u = UBOUND(SrcMeshAuxDataTypeData%ElmIDs,2) + IF (.NOT. ALLOCATED(DstMeshAuxDataTypeData%ElmIDs)) THEN + ALLOCATE(DstMeshAuxDataTypeData%ElmIDs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMeshAuxDataTypeData%ElmIDs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMeshAuxDataTypeData%ElmIDs = SrcMeshAuxDataTypeData%ElmIDs ENDIF -IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN - DEALLOCATE(InitOutputData%WriteOutputUnt) +IF (ALLOCATED(SrcMeshAuxDataTypeData%ElmNds)) THEN + i1_l = LBOUND(SrcMeshAuxDataTypeData%ElmNds,1) + i1_u = UBOUND(SrcMeshAuxDataTypeData%ElmNds,1) + i2_l = LBOUND(SrcMeshAuxDataTypeData%ElmNds,2) + i2_u = UBOUND(SrcMeshAuxDataTypeData%ElmNds,2) + IF (.NOT. ALLOCATED(DstMeshAuxDataTypeData%ElmNds)) THEN + ALLOCATE(DstMeshAuxDataTypeData%ElmNds(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMeshAuxDataTypeData%ElmNds.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMeshAuxDataTypeData%ElmNds = SrcMeshAuxDataTypeData%ElmNds ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) - END SUBROUTINE SD_DestroyInitOutput - - SUBROUTINE SD_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(SD_InitOutputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_PackInitOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 +IF (ALLOCATED(SrcMeshAuxDataTypeData%Me)) THEN + i1_l = LBOUND(SrcMeshAuxDataTypeData%Me,1) + i1_u = UBOUND(SrcMeshAuxDataTypeData%Me,1) + i2_l = LBOUND(SrcMeshAuxDataTypeData%Me,2) + i2_u = UBOUND(SrcMeshAuxDataTypeData%Me,2) + i3_l = LBOUND(SrcMeshAuxDataTypeData%Me,3) + i3_u = UBOUND(SrcMeshAuxDataTypeData%Me,3) + i4_l = LBOUND(SrcMeshAuxDataTypeData%Me,4) + i4_u = UBOUND(SrcMeshAuxDataTypeData%Me,4) + IF (.NOT. ALLOCATED(DstMeshAuxDataTypeData%Me)) THEN + ALLOCATE(DstMeshAuxDataTypeData%Me(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMeshAuxDataTypeData%Me.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMeshAuxDataTypeData%Me = SrcMeshAuxDataTypeData%Me +ENDIF +IF (ALLOCATED(SrcMeshAuxDataTypeData%Ke)) THEN + i1_l = LBOUND(SrcMeshAuxDataTypeData%Ke,1) + i1_u = UBOUND(SrcMeshAuxDataTypeData%Ke,1) + i2_l = LBOUND(SrcMeshAuxDataTypeData%Ke,2) + i2_u = UBOUND(SrcMeshAuxDataTypeData%Ke,2) + i3_l = LBOUND(SrcMeshAuxDataTypeData%Ke,3) + i3_u = UBOUND(SrcMeshAuxDataTypeData%Ke,3) + i4_l = LBOUND(SrcMeshAuxDataTypeData%Ke,4) + i4_u = UBOUND(SrcMeshAuxDataTypeData%Ke,4) + IF (.NOT. ALLOCATED(DstMeshAuxDataTypeData%Ke)) THEN + ALLOCATE(DstMeshAuxDataTypeData%Ke(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMeshAuxDataTypeData%Ke.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMeshAuxDataTypeData%Ke = SrcMeshAuxDataTypeData%Ke +ENDIF +IF (ALLOCATED(SrcMeshAuxDataTypeData%Fg)) THEN + i1_l = LBOUND(SrcMeshAuxDataTypeData%Fg,1) + i1_u = UBOUND(SrcMeshAuxDataTypeData%Fg,1) + i2_l = LBOUND(SrcMeshAuxDataTypeData%Fg,2) + i2_u = UBOUND(SrcMeshAuxDataTypeData%Fg,2) + i3_l = LBOUND(SrcMeshAuxDataTypeData%Fg,3) + i3_u = UBOUND(SrcMeshAuxDataTypeData%Fg,3) + IF (.NOT. ALLOCATED(DstMeshAuxDataTypeData%Fg)) THEN + ALLOCATE(DstMeshAuxDataTypeData%Fg(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMeshAuxDataTypeData%Fg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMeshAuxDataTypeData%Fg = SrcMeshAuxDataTypeData%Fg +ENDIF + END SUBROUTINE SD_CopyMeshAuxDataType + + SUBROUTINE SD_DestroyMeshAuxDataType( MeshAuxDataTypeData, ErrStat, ErrMsg ) + TYPE(MeshAuxDataType), INTENT(INOUT) :: MeshAuxDataTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyMeshAuxDataType' + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(MeshAuxDataTypeData%NodeCnt)) THEN + DEALLOCATE(MeshAuxDataTypeData%NodeCnt) +ENDIF +IF (ALLOCATED(MeshAuxDataTypeData%NodeIDs)) THEN + DEALLOCATE(MeshAuxDataTypeData%NodeIDs) +ENDIF +IF (ALLOCATED(MeshAuxDataTypeData%ElmIDs)) THEN + DEALLOCATE(MeshAuxDataTypeData%ElmIDs) +ENDIF +IF (ALLOCATED(MeshAuxDataTypeData%ElmNds)) THEN + DEALLOCATE(MeshAuxDataTypeData%ElmNds) +ENDIF +IF (ALLOCATED(MeshAuxDataTypeData%Me)) THEN + DEALLOCATE(MeshAuxDataTypeData%Me) +ENDIF +IF (ALLOCATED(MeshAuxDataTypeData%Ke)) THEN + DEALLOCATE(MeshAuxDataTypeData%Ke) +ENDIF +IF (ALLOCATED(MeshAuxDataTypeData%Fg)) THEN + DEALLOCATE(MeshAuxDataTypeData%Fg) +ENDIF + END SUBROUTINE SD_DestroyMeshAuxDataType + + SUBROUTINE SD_PackMeshAuxDataType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(MeshAuxDataType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_PackMeshAuxDataType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! WriteOutputHdr allocated yes/no - IF ( ALLOCATED(InData%WriteOutputHdr) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! WriteOutputHdr upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputHdr)*LEN(InData%WriteOutputHdr) ! WriteOutputHdr + Int_BufSz = Int_BufSz + 1 ! MemberID + Int_BufSz = Int_BufSz + 1 ! NOutCnt + Int_BufSz = Int_BufSz + 1 ! NodeCnt allocated yes/no + IF ( ALLOCATED(InData%NodeCnt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! NodeCnt upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%NodeCnt) ! NodeCnt END IF - Int_BufSz = Int_BufSz + 1 ! WriteOutputUnt allocated yes/no - IF ( ALLOCATED(InData%WriteOutputUnt) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! WriteOutputUnt upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputUnt)*LEN(InData%WriteOutputUnt) ! WriteOutputUnt + Int_BufSz = Int_BufSz + 1 ! NodeIDs allocated yes/no + IF ( ALLOCATED(InData%NodeIDs) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! NodeIDs upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%NodeIDs) ! NodeIDs + END IF + Int_BufSz = Int_BufSz + 1 ! ElmIDs allocated yes/no + IF ( ALLOCATED(InData%ElmIDs) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! ElmIDs upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%ElmIDs) ! ElmIDs + END IF + Int_BufSz = Int_BufSz + 1 ! ElmNds allocated yes/no + IF ( ALLOCATED(InData%ElmNds) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! ElmNds upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%ElmNds) ! ElmNds + END IF + Int_BufSz = Int_BufSz + 1 ! Me allocated yes/no + IF ( ALLOCATED(InData%Me) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! Me upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%Me) ! Me + END IF + Int_BufSz = Int_BufSz + 1 ! Ke allocated yes/no + IF ( ALLOCATED(InData%Ke) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! Ke upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%Ke) ! Ke + END IF + Int_BufSz = Int_BufSz + 1 ! Fg allocated yes/no + IF ( ALLOCATED(InData%Fg) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! Fg upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%Fg) ! Fg END IF - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Ver - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Ver - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Ver - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -601,75 +768,172 @@ SUBROUTINE SD_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_Xferred = 1 Int_Xferred = 1 - IF ( .NOT. ALLOCATED(InData%WriteOutputHdr) ) THEN + IntKiBuf(Int_Xferred) = InData%MemberID + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NOutCnt + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%NodeCnt) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutputHdr,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputHdr,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%NodeCnt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NodeCnt,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%WriteOutputHdr,1), UBOUND(InData%WriteOutputHdr,1) - DO I = 1, LEN(InData%WriteOutputHdr) - IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputHdr(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I + DO i1 = LBOUND(InData%NodeCnt,1), UBOUND(InData%NodeCnt,1) + IntKiBuf(Int_Xferred) = InData%NodeCnt(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%WriteOutputUnt) ) THEN + IF ( .NOT. ALLOCATED(InData%NodeIDs) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutputUnt,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputUnt,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%NodeIDs,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NodeIDs,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%WriteOutputUnt,1), UBOUND(InData%WriteOutputUnt,1) - DO I = 1, LEN(InData%WriteOutputUnt) - IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputUnt(i1)(I:I), IntKi) + DO i1 = LBOUND(InData%NodeIDs,1), UBOUND(InData%NodeIDs,1) + IntKiBuf(Int_Xferred) = InData%NodeIDs(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%ElmIDs) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ElmIDs,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ElmIDs,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ElmIDs,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ElmIDs,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%ElmIDs,2), UBOUND(InData%ElmIDs,2) + DO i1 = LBOUND(InData%ElmIDs,1), UBOUND(InData%ElmIDs,1) + IntKiBuf(Int_Xferred) = InData%ElmIDs(i1,i2) Int_Xferred = Int_Xferred + 1 - END DO ! I + END DO END DO END IF - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, OnlySize ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + IF ( .NOT. ALLOCATED(InData%ElmNds) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ElmNds,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ElmNds,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ElmNds,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ElmNds,2) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE SD_PackInitOutput + DO i2 = LBOUND(InData%ElmNds,2), UBOUND(InData%ElmNds,2) + DO i1 = LBOUND(InData%ElmNds,1), UBOUND(InData%ElmNds,1) + IntKiBuf(Int_Xferred) = InData%ElmNds(i1,i2) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Me) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Me,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Me,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Me,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Me,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Me,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Me,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Me,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Me,4) + Int_Xferred = Int_Xferred + 2 - SUBROUTINE SD_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + DO i4 = LBOUND(InData%Me,4), UBOUND(InData%Me,4) + DO i3 = LBOUND(InData%Me,3), UBOUND(InData%Me,3) + DO i2 = LBOUND(InData%Me,2), UBOUND(InData%Me,2) + DO i1 = LBOUND(InData%Me,1), UBOUND(InData%Me,1) + DbKiBuf(Db_Xferred) = InData%Me(i1,i2,i3,i4) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Ke) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Ke,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Ke,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Ke,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Ke,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Ke,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Ke,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Ke,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Ke,4) + Int_Xferred = Int_Xferred + 2 + + DO i4 = LBOUND(InData%Ke,4), UBOUND(InData%Ke,4) + DO i3 = LBOUND(InData%Ke,3), UBOUND(InData%Ke,3) + DO i2 = LBOUND(InData%Ke,2), UBOUND(InData%Ke,2) + DO i1 = LBOUND(InData%Ke,1), UBOUND(InData%Ke,1) + DbKiBuf(Db_Xferred) = InData%Ke(i1,i2,i3,i4) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Fg) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Fg,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Fg,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Fg,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Fg,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Fg,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Fg,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%Fg,3), UBOUND(InData%Fg,3) + DO i2 = LBOUND(InData%Fg,2), UBOUND(InData%Fg,2) + DO i1 = LBOUND(InData%Fg,1), UBOUND(InData%Fg,1) + DbKiBuf(Db_Xferred) = InData%Fg(i1,i2,i3) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END IF + END SUBROUTINE SD_PackMeshAuxDataType + + SUBROUTINE SD_UnPackMeshAuxDataType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(SD_InitOutputType), INTENT(INOUT) :: OutData + TYPE(MeshAuxDataType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -679,9 +943,12 @@ SUBROUTINE SD_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackInitOutput' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackMeshAuxDataType' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -692,256 +959,322 @@ SUBROUTINE SD_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputHdr not allocated + OutData%MemberID = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NOutCnt = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NodeCnt not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%WriteOutputHdr)) DEALLOCATE(OutData%WriteOutputHdr) - ALLOCATE(OutData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%NodeCnt)) DEALLOCATE(OutData%NodeCnt) + ALLOCATE(OutData%NodeCnt(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%NodeCnt.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%WriteOutputHdr,1), UBOUND(OutData%WriteOutputHdr,1) - DO I = 1, LEN(OutData%WriteOutputHdr) - OutData%WriteOutputHdr(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I + DO i1 = LBOUND(OutData%NodeCnt,1), UBOUND(OutData%NodeCnt,1) + OutData%NodeCnt(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputUnt not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NodeIDs not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%WriteOutputUnt)) DEALLOCATE(OutData%WriteOutputUnt) - ALLOCATE(OutData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%NodeIDs)) DEALLOCATE(OutData%NodeIDs) + ALLOCATE(OutData%NodeIDs(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%NodeIDs.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%WriteOutputUnt,1), UBOUND(OutData%WriteOutputUnt,1) - DO I = 1, LEN(OutData%WriteOutputUnt) - OutData%WriteOutputUnt(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I + DO i1 = LBOUND(OutData%NodeIDs,1), UBOUND(OutData%NodeIDs,1) + OutData%NodeIDs(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 END DO END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE SD_UnPackInitOutput - - SUBROUTINE SD_CopyMeshAuxDataType( SrcMeshAuxDataTypeData, DstMeshAuxDataTypeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(MeshAuxDataType), INTENT(IN) :: SrcMeshAuxDataTypeData - TYPE(MeshAuxDataType), INTENT(INOUT) :: DstMeshAuxDataTypeData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyMeshAuxDataType' -! - ErrStat = ErrID_None - ErrMsg = "" - DstMeshAuxDataTypeData%MemberID = SrcMeshAuxDataTypeData%MemberID - DstMeshAuxDataTypeData%NOutCnt = SrcMeshAuxDataTypeData%NOutCnt -IF (ALLOCATED(SrcMeshAuxDataTypeData%NodeCnt)) THEN - i1_l = LBOUND(SrcMeshAuxDataTypeData%NodeCnt,1) - i1_u = UBOUND(SrcMeshAuxDataTypeData%NodeCnt,1) - IF (.NOT. ALLOCATED(DstMeshAuxDataTypeData%NodeCnt)) THEN - ALLOCATE(DstMeshAuxDataTypeData%NodeCnt(i1_l:i1_u),STAT=ErrStat2) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ElmIDs not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ElmIDs)) DEALLOCATE(OutData%ElmIDs) + ALLOCATE(OutData%ElmIDs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMeshAuxDataTypeData%NodeCnt.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ElmIDs.', ErrStat, ErrMsg,RoutineName) + RETURN END IF + DO i2 = LBOUND(OutData%ElmIDs,2), UBOUND(OutData%ElmIDs,2) + DO i1 = LBOUND(OutData%ElmIDs,1), UBOUND(OutData%ElmIDs,1) + OutData%ElmIDs(i1,i2) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END DO END IF - DstMeshAuxDataTypeData%NodeCnt = SrcMeshAuxDataTypeData%NodeCnt -ENDIF -IF (ALLOCATED(SrcMeshAuxDataTypeData%NodeIDs)) THEN - i1_l = LBOUND(SrcMeshAuxDataTypeData%NodeIDs,1) - i1_u = UBOUND(SrcMeshAuxDataTypeData%NodeIDs,1) - IF (.NOT. ALLOCATED(DstMeshAuxDataTypeData%NodeIDs)) THEN - ALLOCATE(DstMeshAuxDataTypeData%NodeIDs(i1_l:i1_u),STAT=ErrStat2) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ElmNds not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ElmNds)) DEALLOCATE(OutData%ElmNds) + ALLOCATE(OutData%ElmNds(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMeshAuxDataTypeData%NodeIDs.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ElmNds.', ErrStat, ErrMsg,RoutineName) + RETURN END IF - END IF - DstMeshAuxDataTypeData%NodeIDs = SrcMeshAuxDataTypeData%NodeIDs + DO i2 = LBOUND(OutData%ElmNds,2), UBOUND(OutData%ElmNds,2) + DO i1 = LBOUND(OutData%ElmNds,1), UBOUND(OutData%ElmNds,1) + OutData%ElmNds(i1,i2) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Me not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i4_l = IntKiBuf( Int_Xferred ) + i4_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Me)) DEALLOCATE(OutData%Me) + ALLOCATE(OutData%Me(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Me.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%Me,4), UBOUND(OutData%Me,4) + DO i3 = LBOUND(OutData%Me,3), UBOUND(OutData%Me,3) + DO i2 = LBOUND(OutData%Me,2), UBOUND(OutData%Me,2) + DO i1 = LBOUND(OutData%Me,1), UBOUND(OutData%Me,1) + OutData%Me(i1,i2,i3,i4) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Ke not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i4_l = IntKiBuf( Int_Xferred ) + i4_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Ke)) DEALLOCATE(OutData%Ke) + ALLOCATE(OutData%Ke(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Ke.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%Ke,4), UBOUND(OutData%Ke,4) + DO i3 = LBOUND(OutData%Ke,3), UBOUND(OutData%Ke,3) + DO i2 = LBOUND(OutData%Ke,2), UBOUND(OutData%Ke,2) + DO i1 = LBOUND(OutData%Ke,1), UBOUND(OutData%Ke,1) + OutData%Ke(i1,i2,i3,i4) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Fg not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Fg)) DEALLOCATE(OutData%Fg) + ALLOCATE(OutData%Fg(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Fg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%Fg,3), UBOUND(OutData%Fg,3) + DO i2 = LBOUND(OutData%Fg,2), UBOUND(OutData%Fg,2) + DO i1 = LBOUND(OutData%Fg,1), UBOUND(OutData%Fg,1) + OutData%Fg(i1,i2,i3) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END IF + END SUBROUTINE SD_UnPackMeshAuxDataType + + SUBROUTINE SD_CopyCB_MatArrays( SrcCB_MatArraysData, DstCB_MatArraysData, CtrlCode, ErrStat, ErrMsg ) + TYPE(CB_MatArrays), INTENT(IN) :: SrcCB_MatArraysData + TYPE(CB_MatArrays), INTENT(INOUT) :: DstCB_MatArraysData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyCB_MatArrays' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcCB_MatArraysData%MBB)) THEN + i1_l = LBOUND(SrcCB_MatArraysData%MBB,1) + i1_u = UBOUND(SrcCB_MatArraysData%MBB,1) + i2_l = LBOUND(SrcCB_MatArraysData%MBB,2) + i2_u = UBOUND(SrcCB_MatArraysData%MBB,2) + IF (.NOT. ALLOCATED(DstCB_MatArraysData%MBB)) THEN + ALLOCATE(DstCB_MatArraysData%MBB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstCB_MatArraysData%MBB.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstCB_MatArraysData%MBB = SrcCB_MatArraysData%MBB ENDIF -IF (ALLOCATED(SrcMeshAuxDataTypeData%ElmIDs)) THEN - i1_l = LBOUND(SrcMeshAuxDataTypeData%ElmIDs,1) - i1_u = UBOUND(SrcMeshAuxDataTypeData%ElmIDs,1) - i2_l = LBOUND(SrcMeshAuxDataTypeData%ElmIDs,2) - i2_u = UBOUND(SrcMeshAuxDataTypeData%ElmIDs,2) - IF (.NOT. ALLOCATED(DstMeshAuxDataTypeData%ElmIDs)) THEN - ALLOCATE(DstMeshAuxDataTypeData%ElmIDs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcCB_MatArraysData%MBM)) THEN + i1_l = LBOUND(SrcCB_MatArraysData%MBM,1) + i1_u = UBOUND(SrcCB_MatArraysData%MBM,1) + i2_l = LBOUND(SrcCB_MatArraysData%MBM,2) + i2_u = UBOUND(SrcCB_MatArraysData%MBM,2) + IF (.NOT. ALLOCATED(DstCB_MatArraysData%MBM)) THEN + ALLOCATE(DstCB_MatArraysData%MBM(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMeshAuxDataTypeData%ElmIDs.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstCB_MatArraysData%MBM.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMeshAuxDataTypeData%ElmIDs = SrcMeshAuxDataTypeData%ElmIDs + DstCB_MatArraysData%MBM = SrcCB_MatArraysData%MBM ENDIF -IF (ALLOCATED(SrcMeshAuxDataTypeData%ElmNds)) THEN - i1_l = LBOUND(SrcMeshAuxDataTypeData%ElmNds,1) - i1_u = UBOUND(SrcMeshAuxDataTypeData%ElmNds,1) - i2_l = LBOUND(SrcMeshAuxDataTypeData%ElmNds,2) - i2_u = UBOUND(SrcMeshAuxDataTypeData%ElmNds,2) - IF (.NOT. ALLOCATED(DstMeshAuxDataTypeData%ElmNds)) THEN - ALLOCATE(DstMeshAuxDataTypeData%ElmNds(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcCB_MatArraysData%KBB)) THEN + i1_l = LBOUND(SrcCB_MatArraysData%KBB,1) + i1_u = UBOUND(SrcCB_MatArraysData%KBB,1) + i2_l = LBOUND(SrcCB_MatArraysData%KBB,2) + i2_u = UBOUND(SrcCB_MatArraysData%KBB,2) + IF (.NOT. ALLOCATED(DstCB_MatArraysData%KBB)) THEN + ALLOCATE(DstCB_MatArraysData%KBB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMeshAuxDataTypeData%ElmNds.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstCB_MatArraysData%KBB.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMeshAuxDataTypeData%ElmNds = SrcMeshAuxDataTypeData%ElmNds + DstCB_MatArraysData%KBB = SrcCB_MatArraysData%KBB ENDIF - DstMeshAuxDataTypeData%ElmID2s = SrcMeshAuxDataTypeData%ElmID2s - DstMeshAuxDataTypeData%ElmNd2s = SrcMeshAuxDataTypeData%ElmNd2s -IF (ALLOCATED(SrcMeshAuxDataTypeData%Me)) THEN - i1_l = LBOUND(SrcMeshAuxDataTypeData%Me,1) - i1_u = UBOUND(SrcMeshAuxDataTypeData%Me,1) - i2_l = LBOUND(SrcMeshAuxDataTypeData%Me,2) - i2_u = UBOUND(SrcMeshAuxDataTypeData%Me,2) - i3_l = LBOUND(SrcMeshAuxDataTypeData%Me,3) - i3_u = UBOUND(SrcMeshAuxDataTypeData%Me,3) - i4_l = LBOUND(SrcMeshAuxDataTypeData%Me,4) - i4_u = UBOUND(SrcMeshAuxDataTypeData%Me,4) - IF (.NOT. ALLOCATED(DstMeshAuxDataTypeData%Me)) THEN - ALLOCATE(DstMeshAuxDataTypeData%Me(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) +IF (ALLOCATED(SrcCB_MatArraysData%PhiL)) THEN + i1_l = LBOUND(SrcCB_MatArraysData%PhiL,1) + i1_u = UBOUND(SrcCB_MatArraysData%PhiL,1) + i2_l = LBOUND(SrcCB_MatArraysData%PhiL,2) + i2_u = UBOUND(SrcCB_MatArraysData%PhiL,2) + IF (.NOT. ALLOCATED(DstCB_MatArraysData%PhiL)) THEN + ALLOCATE(DstCB_MatArraysData%PhiL(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMeshAuxDataTypeData%Me.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstCB_MatArraysData%PhiL.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMeshAuxDataTypeData%Me = SrcMeshAuxDataTypeData%Me + DstCB_MatArraysData%PhiL = SrcCB_MatArraysData%PhiL ENDIF -IF (ALLOCATED(SrcMeshAuxDataTypeData%Ke)) THEN - i1_l = LBOUND(SrcMeshAuxDataTypeData%Ke,1) - i1_u = UBOUND(SrcMeshAuxDataTypeData%Ke,1) - i2_l = LBOUND(SrcMeshAuxDataTypeData%Ke,2) - i2_u = UBOUND(SrcMeshAuxDataTypeData%Ke,2) - i3_l = LBOUND(SrcMeshAuxDataTypeData%Ke,3) - i3_u = UBOUND(SrcMeshAuxDataTypeData%Ke,3) - i4_l = LBOUND(SrcMeshAuxDataTypeData%Ke,4) - i4_u = UBOUND(SrcMeshAuxDataTypeData%Ke,4) - IF (.NOT. ALLOCATED(DstMeshAuxDataTypeData%Ke)) THEN - ALLOCATE(DstMeshAuxDataTypeData%Ke(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) +IF (ALLOCATED(SrcCB_MatArraysData%PhiR)) THEN + i1_l = LBOUND(SrcCB_MatArraysData%PhiR,1) + i1_u = UBOUND(SrcCB_MatArraysData%PhiR,1) + i2_l = LBOUND(SrcCB_MatArraysData%PhiR,2) + i2_u = UBOUND(SrcCB_MatArraysData%PhiR,2) + IF (.NOT. ALLOCATED(DstCB_MatArraysData%PhiR)) THEN + ALLOCATE(DstCB_MatArraysData%PhiR(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMeshAuxDataTypeData%Ke.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstCB_MatArraysData%PhiR.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMeshAuxDataTypeData%Ke = SrcMeshAuxDataTypeData%Ke + DstCB_MatArraysData%PhiR = SrcCB_MatArraysData%PhiR ENDIF -IF (ALLOCATED(SrcMeshAuxDataTypeData%Fg)) THEN - i1_l = LBOUND(SrcMeshAuxDataTypeData%Fg,1) - i1_u = UBOUND(SrcMeshAuxDataTypeData%Fg,1) - i2_l = LBOUND(SrcMeshAuxDataTypeData%Fg,2) - i2_u = UBOUND(SrcMeshAuxDataTypeData%Fg,2) - i3_l = LBOUND(SrcMeshAuxDataTypeData%Fg,3) - i3_u = UBOUND(SrcMeshAuxDataTypeData%Fg,3) - IF (.NOT. ALLOCATED(DstMeshAuxDataTypeData%Fg)) THEN - ALLOCATE(DstMeshAuxDataTypeData%Fg(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) +IF (ALLOCATED(SrcCB_MatArraysData%OmegaL)) THEN + i1_l = LBOUND(SrcCB_MatArraysData%OmegaL,1) + i1_u = UBOUND(SrcCB_MatArraysData%OmegaL,1) + IF (.NOT. ALLOCATED(DstCB_MatArraysData%OmegaL)) THEN + ALLOCATE(DstCB_MatArraysData%OmegaL(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMeshAuxDataTypeData%Fg.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstCB_MatArraysData%OmegaL.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMeshAuxDataTypeData%Fg = SrcMeshAuxDataTypeData%Fg + DstCB_MatArraysData%OmegaL = SrcCB_MatArraysData%OmegaL ENDIF - DstMeshAuxDataTypeData%Me2 = SrcMeshAuxDataTypeData%Me2 - DstMeshAuxDataTypeData%Ke2 = SrcMeshAuxDataTypeData%Ke2 - DstMeshAuxDataTypeData%Fg2 = SrcMeshAuxDataTypeData%Fg2 - END SUBROUTINE SD_CopyMeshAuxDataType + END SUBROUTINE SD_CopyCB_MatArrays - SUBROUTINE SD_DestroyMeshAuxDataType( MeshAuxDataTypeData, ErrStat, ErrMsg ) - TYPE(MeshAuxDataType), INTENT(INOUT) :: MeshAuxDataTypeData + SUBROUTINE SD_DestroyCB_MatArrays( CB_MatArraysData, ErrStat, ErrMsg ) + TYPE(CB_MatArrays), INTENT(INOUT) :: CB_MatArraysData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyMeshAuxDataType' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyCB_MatArrays' INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(MeshAuxDataTypeData%NodeCnt)) THEN - DEALLOCATE(MeshAuxDataTypeData%NodeCnt) -ENDIF -IF (ALLOCATED(MeshAuxDataTypeData%NodeIDs)) THEN - DEALLOCATE(MeshAuxDataTypeData%NodeIDs) +IF (ALLOCATED(CB_MatArraysData%MBB)) THEN + DEALLOCATE(CB_MatArraysData%MBB) ENDIF -IF (ALLOCATED(MeshAuxDataTypeData%ElmIDs)) THEN - DEALLOCATE(MeshAuxDataTypeData%ElmIDs) +IF (ALLOCATED(CB_MatArraysData%MBM)) THEN + DEALLOCATE(CB_MatArraysData%MBM) ENDIF -IF (ALLOCATED(MeshAuxDataTypeData%ElmNds)) THEN - DEALLOCATE(MeshAuxDataTypeData%ElmNds) +IF (ALLOCATED(CB_MatArraysData%KBB)) THEN + DEALLOCATE(CB_MatArraysData%KBB) ENDIF -IF (ALLOCATED(MeshAuxDataTypeData%Me)) THEN - DEALLOCATE(MeshAuxDataTypeData%Me) +IF (ALLOCATED(CB_MatArraysData%PhiL)) THEN + DEALLOCATE(CB_MatArraysData%PhiL) ENDIF -IF (ALLOCATED(MeshAuxDataTypeData%Ke)) THEN - DEALLOCATE(MeshAuxDataTypeData%Ke) +IF (ALLOCATED(CB_MatArraysData%PhiR)) THEN + DEALLOCATE(CB_MatArraysData%PhiR) ENDIF -IF (ALLOCATED(MeshAuxDataTypeData%Fg)) THEN - DEALLOCATE(MeshAuxDataTypeData%Fg) +IF (ALLOCATED(CB_MatArraysData%OmegaL)) THEN + DEALLOCATE(CB_MatArraysData%OmegaL) ENDIF - END SUBROUTINE SD_DestroyMeshAuxDataType + END SUBROUTINE SD_DestroyCB_MatArrays - SUBROUTINE SD_PackMeshAuxDataType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE SD_PackCB_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(MeshAuxDataType), INTENT(IN) :: InData + TYPE(CB_MatArrays), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -956,7 +1289,7 @@ SUBROUTINE SD_PackMeshAuxDataType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_PackMeshAuxDataType' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_PackCB_MatArrays' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -972,48 +1305,36 @@ SUBROUTINE SD_PackMeshAuxDataType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! MemberID - Int_BufSz = Int_BufSz + 1 ! NOutCnt - Int_BufSz = Int_BufSz + 1 ! NodeCnt allocated yes/no - IF ( ALLOCATED(InData%NodeCnt) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! NodeCnt upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%NodeCnt) ! NodeCnt - END IF - Int_BufSz = Int_BufSz + 1 ! NodeIDs allocated yes/no - IF ( ALLOCATED(InData%NodeIDs) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! NodeIDs upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%NodeIDs) ! NodeIDs + Int_BufSz = Int_BufSz + 1 ! MBB allocated yes/no + IF ( ALLOCATED(InData%MBB) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! MBB upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%MBB) ! MBB END IF - Int_BufSz = Int_BufSz + 1 ! ElmIDs allocated yes/no - IF ( ALLOCATED(InData%ElmIDs) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! ElmIDs upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%ElmIDs) ! ElmIDs + Int_BufSz = Int_BufSz + 1 ! MBM allocated yes/no + IF ( ALLOCATED(InData%MBM) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! MBM upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%MBM) ! MBM END IF - Int_BufSz = Int_BufSz + 1 ! ElmNds allocated yes/no - IF ( ALLOCATED(InData%ElmNds) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! ElmNds upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%ElmNds) ! ElmNds + Int_BufSz = Int_BufSz + 1 ! KBB allocated yes/no + IF ( ALLOCATED(InData%KBB) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! KBB upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%KBB) ! KBB END IF - Int_BufSz = Int_BufSz + SIZE(InData%ElmID2s) ! ElmID2s - Int_BufSz = Int_BufSz + SIZE(InData%ElmNd2s) ! ElmNd2s - Int_BufSz = Int_BufSz + 1 ! Me allocated yes/no - IF ( ALLOCATED(InData%Me) ) THEN - Int_BufSz = Int_BufSz + 2*4 ! Me upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Me) ! Me + Int_BufSz = Int_BufSz + 1 ! PhiL allocated yes/no + IF ( ALLOCATED(InData%PhiL) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! PhiL upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%PhiL) ! PhiL END IF - Int_BufSz = Int_BufSz + 1 ! Ke allocated yes/no - IF ( ALLOCATED(InData%Ke) ) THEN - Int_BufSz = Int_BufSz + 2*4 ! Ke upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Ke) ! Ke + Int_BufSz = Int_BufSz + 1 ! PhiR allocated yes/no + IF ( ALLOCATED(InData%PhiR) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! PhiR upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%PhiR) ! PhiR END IF - Int_BufSz = Int_BufSz + 1 ! Fg allocated yes/no - IF ( ALLOCATED(InData%Fg) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! Fg upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Fg) ! Fg + Int_BufSz = Int_BufSz + 1 ! OmegaL allocated yes/no + IF ( ALLOCATED(InData%OmegaL) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! OmegaL upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%OmegaL) ! OmegaL END IF - Re_BufSz = Re_BufSz + SIZE(InData%Me2) ! Me2 - Re_BufSz = Re_BufSz + SIZE(InData%Ke2) ! Ke2 - Re_BufSz = Re_BufSz + SIZE(InData%Fg2) ! Fg2 IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1041,202 +1362,128 @@ SUBROUTINE SD_PackMeshAuxDataType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = InData%MemberID - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NOutCnt - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%NodeCnt) ) THEN + IF ( .NOT. ALLOCATED(InData%MBB) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%NodeCnt,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NodeCnt,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%MBB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBB,1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%NodeCnt,1), UBOUND(InData%NodeCnt,1) - IntKiBuf(Int_Xferred) = InData%NodeCnt(i1) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%NodeIDs) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%NodeIDs,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NodeIDs,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%MBB,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBB,2) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%NodeIDs,1), UBOUND(InData%NodeIDs,1) - IntKiBuf(Int_Xferred) = InData%NodeIDs(i1) - Int_Xferred = Int_Xferred + 1 + DO i2 = LBOUND(InData%MBB,2), UBOUND(InData%MBB,2) + DO i1 = LBOUND(InData%MBB,1), UBOUND(InData%MBB,1) + DbKiBuf(Db_Xferred) = InData%MBB(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%ElmIDs) ) THEN + IF ( .NOT. ALLOCATED(InData%MBM) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%ElmIDs,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ElmIDs,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%MBM,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBM,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%ElmIDs,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ElmIDs,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%MBM,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBM,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%ElmIDs,2), UBOUND(InData%ElmIDs,2) - DO i1 = LBOUND(InData%ElmIDs,1), UBOUND(InData%ElmIDs,1) - IntKiBuf(Int_Xferred) = InData%ElmIDs(i1,i2) - Int_Xferred = Int_Xferred + 1 + DO i2 = LBOUND(InData%MBM,2), UBOUND(InData%MBM,2) + DO i1 = LBOUND(InData%MBM,1), UBOUND(InData%MBM,1) + DbKiBuf(Db_Xferred) = InData%MBM(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%ElmNds) ) THEN + IF ( .NOT. ALLOCATED(InData%KBB) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%ElmNds,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ElmNds,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%KBB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KBB,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%ElmNds,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ElmNds,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%KBB,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KBB,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%ElmNds,2), UBOUND(InData%ElmNds,2) - DO i1 = LBOUND(InData%ElmNds,1), UBOUND(InData%ElmNds,1) - IntKiBuf(Int_Xferred) = InData%ElmNds(i1,i2) - Int_Xferred = Int_Xferred + 1 + DO i2 = LBOUND(InData%KBB,2), UBOUND(InData%KBB,2) + DO i1 = LBOUND(InData%KBB,1), UBOUND(InData%KBB,1) + DbKiBuf(Db_Xferred) = InData%KBB(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF - DO i1 = LBOUND(InData%ElmID2s,1), UBOUND(InData%ElmID2s,1) - IntKiBuf(Int_Xferred) = InData%ElmID2s(i1) - Int_Xferred = Int_Xferred + 1 - END DO - DO i1 = LBOUND(InData%ElmNd2s,1), UBOUND(InData%ElmNd2s,1) - IntKiBuf(Int_Xferred) = InData%ElmNd2s(i1) - Int_Xferred = Int_Xferred + 1 - END DO - IF ( .NOT. ALLOCATED(InData%Me) ) THEN + IF ( .NOT. ALLOCATED(InData%PhiL) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Me,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Me,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Me,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Me,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Me,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Me,3) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiL,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiL,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Me,4) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Me,4) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiL,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiL,2) Int_Xferred = Int_Xferred + 2 - DO i4 = LBOUND(InData%Me,4), UBOUND(InData%Me,4) - DO i3 = LBOUND(InData%Me,3), UBOUND(InData%Me,3) - DO i2 = LBOUND(InData%Me,2), UBOUND(InData%Me,2) - DO i1 = LBOUND(InData%Me,1), UBOUND(InData%Me,1) - ReKiBuf(Re_Xferred) = InData%Me(i1,i2,i3,i4) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + DO i2 = LBOUND(InData%PhiL,2), UBOUND(InData%PhiL,2) + DO i1 = LBOUND(InData%PhiL,1), UBOUND(InData%PhiL,1) + DbKiBuf(Db_Xferred) = InData%PhiL(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%Ke) ) THEN + IF ( .NOT. ALLOCATED(InData%PhiR) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Ke,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Ke,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Ke,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Ke,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Ke,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Ke,3) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiR,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiR,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Ke,4) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Ke,4) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiR,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiR,2) Int_Xferred = Int_Xferred + 2 - DO i4 = LBOUND(InData%Ke,4), UBOUND(InData%Ke,4) - DO i3 = LBOUND(InData%Ke,3), UBOUND(InData%Ke,3) - DO i2 = LBOUND(InData%Ke,2), UBOUND(InData%Ke,2) - DO i1 = LBOUND(InData%Ke,1), UBOUND(InData%Ke,1) - ReKiBuf(Re_Xferred) = InData%Ke(i1,i2,i3,i4) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + DO i2 = LBOUND(InData%PhiR,2), UBOUND(InData%PhiR,2) + DO i1 = LBOUND(InData%PhiR,1), UBOUND(InData%PhiR,1) + DbKiBuf(Db_Xferred) = InData%PhiR(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%Fg) ) THEN + IF ( .NOT. ALLOCATED(InData%OmegaL) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Fg,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Fg,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Fg,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Fg,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Fg,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Fg,3) + IntKiBuf( Int_Xferred ) = LBOUND(InData%OmegaL,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%OmegaL,1) Int_Xferred = Int_Xferred + 2 - DO i3 = LBOUND(InData%Fg,3), UBOUND(InData%Fg,3) - DO i2 = LBOUND(InData%Fg,2), UBOUND(InData%Fg,2) - DO i1 = LBOUND(InData%Fg,1), UBOUND(InData%Fg,1) - ReKiBuf(Re_Xferred) = InData%Fg(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + DO i1 = LBOUND(InData%OmegaL,1), UBOUND(InData%OmegaL,1) + DbKiBuf(Db_Xferred) = InData%OmegaL(i1) + Db_Xferred = Db_Xferred + 1 END DO END IF - DO i3 = LBOUND(InData%Me2,3), UBOUND(InData%Me2,3) - DO i2 = LBOUND(InData%Me2,2), UBOUND(InData%Me2,2) - DO i1 = LBOUND(InData%Me2,1), UBOUND(InData%Me2,1) - ReKiBuf(Re_Xferred) = InData%Me2(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - DO i3 = LBOUND(InData%Ke2,3), UBOUND(InData%Ke2,3) - DO i2 = LBOUND(InData%Ke2,2), UBOUND(InData%Ke2,2) - DO i1 = LBOUND(InData%Ke2,1), UBOUND(InData%Ke2,1) - ReKiBuf(Re_Xferred) = InData%Ke2(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - DO i2 = LBOUND(InData%Fg2,2), UBOUND(InData%Fg2,2) - DO i1 = LBOUND(InData%Fg2,1), UBOUND(InData%Fg2,1) - ReKiBuf(Re_Xferred) = InData%Fg2(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END SUBROUTINE SD_PackMeshAuxDataType + END SUBROUTINE SD_PackCB_MatArrays - SUBROUTINE SD_UnPackMeshAuxDataType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE SD_UnPackCB_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(MeshAuxDataType), INTENT(INOUT) :: OutData + TYPE(CB_MatArrays), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -1247,11 +1494,9 @@ SUBROUTINE SD_UnPackMeshAuxDataType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackMeshAuxDataType' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackCB_MatArrays' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -1262,47 +1507,53 @@ SUBROUTINE SD_UnPackMeshAuxDataType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%MemberID = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%NOutCnt = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NodeCnt not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MBB not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%NodeCnt)) DEALLOCATE(OutData%NodeCnt) - ALLOCATE(OutData%NodeCnt(i1_l:i1_u),STAT=ErrStat2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MBB)) DEALLOCATE(OutData%MBB) + ALLOCATE(OutData%MBB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%NodeCnt.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MBB.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%NodeCnt,1), UBOUND(OutData%NodeCnt,1) - OutData%NodeCnt(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + DO i2 = LBOUND(OutData%MBB,2), UBOUND(OutData%MBB,2) + DO i1 = LBOUND(OutData%MBB,1), UBOUND(OutData%MBB,1) + OutData%MBB(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NodeIDs not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MBM not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%NodeIDs)) DEALLOCATE(OutData%NodeIDs) - ALLOCATE(OutData%NodeIDs(i1_l:i1_u),STAT=ErrStat2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MBM)) DEALLOCATE(OutData%MBM) + ALLOCATE(OutData%MBM(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%NodeIDs.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MBM.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%NodeIDs,1), UBOUND(OutData%NodeIDs,1) - OutData%NodeIDs(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + DO i2 = LBOUND(OutData%MBM,2), UBOUND(OutData%MBM,2) + DO i1 = LBOUND(OutData%MBM,1), UBOUND(OutData%MBM,1) + OutData%MBM(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ElmIDs not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! KBB not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -1312,55 +1563,20 @@ SUBROUTINE SD_UnPackMeshAuxDataType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%ElmIDs)) DEALLOCATE(OutData%ElmIDs) - ALLOCATE(OutData%ElmIDs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ElmIDs.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%ElmIDs,2), UBOUND(OutData%ElmIDs,2) - DO i1 = LBOUND(OutData%ElmIDs,1), UBOUND(OutData%ElmIDs,1) - OutData%ElmIDs(i1,i2) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ElmNds not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%ElmNds)) DEALLOCATE(OutData%ElmNds) - ALLOCATE(OutData%ElmNds(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%KBB)) DEALLOCATE(OutData%KBB) + ALLOCATE(OutData%KBB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ElmNds.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%KBB.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%ElmNds,2), UBOUND(OutData%ElmNds,2) - DO i1 = LBOUND(OutData%ElmNds,1), UBOUND(OutData%ElmNds,1) - OutData%ElmNds(i1,i2) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + DO i2 = LBOUND(OutData%KBB,2), UBOUND(OutData%KBB,2) + DO i1 = LBOUND(OutData%KBB,1), UBOUND(OutData%KBB,1) + OutData%KBB(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF - i1_l = LBOUND(OutData%ElmID2s,1) - i1_u = UBOUND(OutData%ElmID2s,1) - DO i1 = LBOUND(OutData%ElmID2s,1), UBOUND(OutData%ElmID2s,1) - OutData%ElmID2s(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - i1_l = LBOUND(OutData%ElmNd2s,1) - i1_u = UBOUND(OutData%ElmNd2s,1) - DO i1 = LBOUND(OutData%ElmNd2s,1), UBOUND(OutData%ElmNd2s,1) - OutData%ElmNd2s(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Me not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PhiL not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -1370,30 +1586,20 @@ SUBROUTINE SD_UnPackMeshAuxDataType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i4_l = IntKiBuf( Int_Xferred ) - i4_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Me)) DEALLOCATE(OutData%Me) - ALLOCATE(OutData%Me(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%PhiL)) DEALLOCATE(OutData%PhiL) + ALLOCATE(OutData%PhiL(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Me.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PhiL.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i4 = LBOUND(OutData%Me,4), UBOUND(OutData%Me,4) - DO i3 = LBOUND(OutData%Me,3), UBOUND(OutData%Me,3) - DO i2 = LBOUND(OutData%Me,2), UBOUND(OutData%Me,2) - DO i1 = LBOUND(OutData%Me,1), UBOUND(OutData%Me,1) - OutData%Me(i1,i2,i3,i4) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + DO i2 = LBOUND(OutData%PhiL,2), UBOUND(OutData%PhiL,2) + DO i1 = LBOUND(OutData%PhiL,1), UBOUND(OutData%PhiL,1) + OutData%PhiL(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Ke not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PhiR not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -1403,100 +1609,42 @@ SUBROUTINE SD_UnPackMeshAuxDataType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i4_l = IntKiBuf( Int_Xferred ) - i4_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Ke)) DEALLOCATE(OutData%Ke) - ALLOCATE(OutData%Ke(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%PhiR)) DEALLOCATE(OutData%PhiR) + ALLOCATE(OutData%PhiR(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Ke.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PhiR.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i4 = LBOUND(OutData%Ke,4), UBOUND(OutData%Ke,4) - DO i3 = LBOUND(OutData%Ke,3), UBOUND(OutData%Ke,3) - DO i2 = LBOUND(OutData%Ke,2), UBOUND(OutData%Ke,2) - DO i1 = LBOUND(OutData%Ke,1), UBOUND(OutData%Ke,1) - OutData%Ke(i1,i2,i3,i4) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + DO i2 = LBOUND(OutData%PhiR,2), UBOUND(OutData%PhiR,2) + DO i1 = LBOUND(OutData%PhiR,1), UBOUND(OutData%PhiR,1) + OutData%PhiR(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Fg not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OmegaL not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Fg)) DEALLOCATE(OutData%Fg) - ALLOCATE(OutData%Fg(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%OmegaL)) DEALLOCATE(OutData%OmegaL) + ALLOCATE(OutData%OmegaL(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Fg.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OmegaL.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i3 = LBOUND(OutData%Fg,3), UBOUND(OutData%Fg,3) - DO i2 = LBOUND(OutData%Fg,2), UBOUND(OutData%Fg,2) - DO i1 = LBOUND(OutData%Fg,1), UBOUND(OutData%Fg,1) - OutData%Fg(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + DO i1 = LBOUND(OutData%OmegaL,1), UBOUND(OutData%OmegaL,1) + OutData%OmegaL(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 END DO END IF - i1_l = LBOUND(OutData%Me2,1) - i1_u = UBOUND(OutData%Me2,1) - i2_l = LBOUND(OutData%Me2,2) - i2_u = UBOUND(OutData%Me2,2) - i3_l = LBOUND(OutData%Me2,3) - i3_u = UBOUND(OutData%Me2,3) - DO i3 = LBOUND(OutData%Me2,3), UBOUND(OutData%Me2,3) - DO i2 = LBOUND(OutData%Me2,2), UBOUND(OutData%Me2,2) - DO i1 = LBOUND(OutData%Me2,1), UBOUND(OutData%Me2,1) - OutData%Me2(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - i1_l = LBOUND(OutData%Ke2,1) - i1_u = UBOUND(OutData%Ke2,1) - i2_l = LBOUND(OutData%Ke2,2) - i2_u = UBOUND(OutData%Ke2,2) - i3_l = LBOUND(OutData%Ke2,3) - i3_u = UBOUND(OutData%Ke2,3) - DO i3 = LBOUND(OutData%Ke2,3), UBOUND(OutData%Ke2,3) - DO i2 = LBOUND(OutData%Ke2,2), UBOUND(OutData%Ke2,2) - DO i1 = LBOUND(OutData%Ke2,1), UBOUND(OutData%Ke2,1) - OutData%Ke2(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - i1_l = LBOUND(OutData%Fg2,1) - i1_u = UBOUND(OutData%Fg2,1) - i2_l = LBOUND(OutData%Fg2,2) - i2_u = UBOUND(OutData%Fg2,2) - DO i2 = LBOUND(OutData%Fg2,2), UBOUND(OutData%Fg2,2) - DO i1 = LBOUND(OutData%Fg2,1), UBOUND(OutData%Fg2,1) - OutData%Fg2(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END SUBROUTINE SD_UnPackMeshAuxDataType + END SUBROUTINE SD_UnPackCB_MatArrays - SUBROUTINE SD_CopyCB_MatArrays( SrcCB_MatArraysData, DstCB_MatArraysData, CtrlCode, ErrStat, ErrMsg ) - TYPE(CB_MatArrays), INTENT(IN) :: SrcCB_MatArraysData - TYPE(CB_MatArrays), INTENT(INOUT) :: DstCB_MatArraysData + SUBROUTINE SD_CopyElemPropType( SrcElemPropTypeData, DstElemPropTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ElemPropType), INTENT(IN) :: SrcElemPropTypeData + TYPE(ElemPropType), INTENT(INOUT) :: DstElemPropTypeData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -1506,146 +1654,41 @@ SUBROUTINE SD_CopyCB_MatArrays( SrcCB_MatArraysData, DstCB_MatArraysData, CtrlCo INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyCB_MatArrays' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyElemPropType' ! ErrStat = ErrID_None ErrMsg = "" - DstCB_MatArraysData%DOFM = SrcCB_MatArraysData%DOFM -IF (ALLOCATED(SrcCB_MatArraysData%TI2)) THEN - i1_l = LBOUND(SrcCB_MatArraysData%TI2,1) - i1_u = UBOUND(SrcCB_MatArraysData%TI2,1) - i2_l = LBOUND(SrcCB_MatArraysData%TI2,2) - i2_u = UBOUND(SrcCB_MatArraysData%TI2,2) - IF (.NOT. ALLOCATED(DstCB_MatArraysData%TI2)) THEN - ALLOCATE(DstCB_MatArraysData%TI2(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstCB_MatArraysData%TI2.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstCB_MatArraysData%TI2 = SrcCB_MatArraysData%TI2 -ENDIF -IF (ALLOCATED(SrcCB_MatArraysData%MBB)) THEN - i1_l = LBOUND(SrcCB_MatArraysData%MBB,1) - i1_u = UBOUND(SrcCB_MatArraysData%MBB,1) - i2_l = LBOUND(SrcCB_MatArraysData%MBB,2) - i2_u = UBOUND(SrcCB_MatArraysData%MBB,2) - IF (.NOT. ALLOCATED(DstCB_MatArraysData%MBB)) THEN - ALLOCATE(DstCB_MatArraysData%MBB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstCB_MatArraysData%MBB.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstCB_MatArraysData%MBB = SrcCB_MatArraysData%MBB -ENDIF -IF (ALLOCATED(SrcCB_MatArraysData%MBM)) THEN - i1_l = LBOUND(SrcCB_MatArraysData%MBM,1) - i1_u = UBOUND(SrcCB_MatArraysData%MBM,1) - i2_l = LBOUND(SrcCB_MatArraysData%MBM,2) - i2_u = UBOUND(SrcCB_MatArraysData%MBM,2) - IF (.NOT. ALLOCATED(DstCB_MatArraysData%MBM)) THEN - ALLOCATE(DstCB_MatArraysData%MBM(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstCB_MatArraysData%MBM.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstCB_MatArraysData%MBM = SrcCB_MatArraysData%MBM -ENDIF -IF (ALLOCATED(SrcCB_MatArraysData%KBB)) THEN - i1_l = LBOUND(SrcCB_MatArraysData%KBB,1) - i1_u = UBOUND(SrcCB_MatArraysData%KBB,1) - i2_l = LBOUND(SrcCB_MatArraysData%KBB,2) - i2_u = UBOUND(SrcCB_MatArraysData%KBB,2) - IF (.NOT. ALLOCATED(DstCB_MatArraysData%KBB)) THEN - ALLOCATE(DstCB_MatArraysData%KBB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstCB_MatArraysData%KBB.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstCB_MatArraysData%KBB = SrcCB_MatArraysData%KBB -ENDIF -IF (ALLOCATED(SrcCB_MatArraysData%PhiL)) THEN - i1_l = LBOUND(SrcCB_MatArraysData%PhiL,1) - i1_u = UBOUND(SrcCB_MatArraysData%PhiL,1) - i2_l = LBOUND(SrcCB_MatArraysData%PhiL,2) - i2_u = UBOUND(SrcCB_MatArraysData%PhiL,2) - IF (.NOT. ALLOCATED(DstCB_MatArraysData%PhiL)) THEN - ALLOCATE(DstCB_MatArraysData%PhiL(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstCB_MatArraysData%PhiL.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstCB_MatArraysData%PhiL = SrcCB_MatArraysData%PhiL -ENDIF -IF (ALLOCATED(SrcCB_MatArraysData%PhiR)) THEN - i1_l = LBOUND(SrcCB_MatArraysData%PhiR,1) - i1_u = UBOUND(SrcCB_MatArraysData%PhiR,1) - i2_l = LBOUND(SrcCB_MatArraysData%PhiR,2) - i2_u = UBOUND(SrcCB_MatArraysData%PhiR,2) - IF (.NOT. ALLOCATED(DstCB_MatArraysData%PhiR)) THEN - ALLOCATE(DstCB_MatArraysData%PhiR(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstCB_MatArraysData%PhiR.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstCB_MatArraysData%PhiR = SrcCB_MatArraysData%PhiR -ENDIF -IF (ALLOCATED(SrcCB_MatArraysData%OmegaL)) THEN - i1_l = LBOUND(SrcCB_MatArraysData%OmegaL,1) - i1_u = UBOUND(SrcCB_MatArraysData%OmegaL,1) - IF (.NOT. ALLOCATED(DstCB_MatArraysData%OmegaL)) THEN - ALLOCATE(DstCB_MatArraysData%OmegaL(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstCB_MatArraysData%OmegaL.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstCB_MatArraysData%OmegaL = SrcCB_MatArraysData%OmegaL -ENDIF - END SUBROUTINE SD_CopyCB_MatArrays + DstElemPropTypeData%eType = SrcElemPropTypeData%eType + DstElemPropTypeData%Length = SrcElemPropTypeData%Length + DstElemPropTypeData%Ixx = SrcElemPropTypeData%Ixx + DstElemPropTypeData%Iyy = SrcElemPropTypeData%Iyy + DstElemPropTypeData%Jzz = SrcElemPropTypeData%Jzz + DstElemPropTypeData%Shear = SrcElemPropTypeData%Shear + DstElemPropTypeData%Kappa = SrcElemPropTypeData%Kappa + DstElemPropTypeData%YoungE = SrcElemPropTypeData%YoungE + DstElemPropTypeData%ShearG = SrcElemPropTypeData%ShearG + DstElemPropTypeData%Area = SrcElemPropTypeData%Area + DstElemPropTypeData%Rho = SrcElemPropTypeData%Rho + DstElemPropTypeData%T0 = SrcElemPropTypeData%T0 + DstElemPropTypeData%DirCos = SrcElemPropTypeData%DirCos + END SUBROUTINE SD_CopyElemPropType - SUBROUTINE SD_DestroyCB_MatArrays( CB_MatArraysData, ErrStat, ErrMsg ) - TYPE(CB_MatArrays), INTENT(INOUT) :: CB_MatArraysData + SUBROUTINE SD_DestroyElemPropType( ElemPropTypeData, ErrStat, ErrMsg ) + TYPE(ElemPropType), INTENT(INOUT) :: ElemPropTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyCB_MatArrays' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyElemPropType' INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(CB_MatArraysData%TI2)) THEN - DEALLOCATE(CB_MatArraysData%TI2) -ENDIF -IF (ALLOCATED(CB_MatArraysData%MBB)) THEN - DEALLOCATE(CB_MatArraysData%MBB) -ENDIF -IF (ALLOCATED(CB_MatArraysData%MBM)) THEN - DEALLOCATE(CB_MatArraysData%MBM) -ENDIF -IF (ALLOCATED(CB_MatArraysData%KBB)) THEN - DEALLOCATE(CB_MatArraysData%KBB) -ENDIF -IF (ALLOCATED(CB_MatArraysData%PhiL)) THEN - DEALLOCATE(CB_MatArraysData%PhiL) -ENDIF -IF (ALLOCATED(CB_MatArraysData%PhiR)) THEN - DEALLOCATE(CB_MatArraysData%PhiR) -ENDIF -IF (ALLOCATED(CB_MatArraysData%OmegaL)) THEN - DEALLOCATE(CB_MatArraysData%OmegaL) -ENDIF - END SUBROUTINE SD_DestroyCB_MatArrays + END SUBROUTINE SD_DestroyElemPropType - SUBROUTINE SD_PackCB_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE SD_PackElemPropType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(CB_MatArrays), INTENT(IN) :: InData + TYPE(ElemPropType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -1660,7 +1703,7 @@ SUBROUTINE SD_PackCB_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_PackCB_MatArrays' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_PackElemPropType' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -1676,42 +1719,19 @@ SUBROUTINE SD_PackCB_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! DOFM - Int_BufSz = Int_BufSz + 1 ! TI2 allocated yes/no - IF ( ALLOCATED(InData%TI2) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! TI2 upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%TI2) ! TI2 - END IF - Int_BufSz = Int_BufSz + 1 ! MBB allocated yes/no - IF ( ALLOCATED(InData%MBB) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! MBB upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%MBB) ! MBB - END IF - Int_BufSz = Int_BufSz + 1 ! MBM allocated yes/no - IF ( ALLOCATED(InData%MBM) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! MBM upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%MBM) ! MBM - END IF - Int_BufSz = Int_BufSz + 1 ! KBB allocated yes/no - IF ( ALLOCATED(InData%KBB) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! KBB upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%KBB) ! KBB - END IF - Int_BufSz = Int_BufSz + 1 ! PhiL allocated yes/no - IF ( ALLOCATED(InData%PhiL) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! PhiL upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%PhiL) ! PhiL - END IF - Int_BufSz = Int_BufSz + 1 ! PhiR allocated yes/no - IF ( ALLOCATED(InData%PhiR) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! PhiR upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%PhiR) ! PhiR - END IF - Int_BufSz = Int_BufSz + 1 ! OmegaL allocated yes/no - IF ( ALLOCATED(InData%OmegaL) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! OmegaL upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%OmegaL) ! OmegaL - END IF + Int_BufSz = Int_BufSz + 1 ! eType + Re_BufSz = Re_BufSz + 1 ! Length + Re_BufSz = Re_BufSz + 1 ! Ixx + Re_BufSz = Re_BufSz + 1 ! Iyy + Re_BufSz = Re_BufSz + 1 ! Jzz + Int_BufSz = Int_BufSz + 1 ! Shear + Re_BufSz = Re_BufSz + 1 ! Kappa + Re_BufSz = Re_BufSz + 1 ! YoungE + Re_BufSz = Re_BufSz + 1 ! ShearG + Re_BufSz = Re_BufSz + 1 ! Area + Re_BufSz = Re_BufSz + 1 ! Rho + Re_BufSz = Re_BufSz + 1 ! T0 + Db_BufSz = Db_BufSz + SIZE(InData%DirCos) ! DirCos IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1739,150 +1759,43 @@ SUBROUTINE SD_PackCB_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = InData%DOFM - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%TI2) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TI2,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TI2,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TI2,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TI2,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%TI2,2), UBOUND(InData%TI2,2) - DO i1 = LBOUND(InData%TI2,1), UBOUND(InData%TI2,1) - ReKiBuf(Re_Xferred) = InData%TI2(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%MBB) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MBB,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBB,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MBB,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBB,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%MBB,2), UBOUND(InData%MBB,2) - DO i1 = LBOUND(InData%MBB,1), UBOUND(InData%MBB,1) - ReKiBuf(Re_Xferred) = InData%MBB(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%MBM) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MBM,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBM,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MBM,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBM,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%MBM,2), UBOUND(InData%MBM,2) - DO i1 = LBOUND(InData%MBM,1), UBOUND(InData%MBM,1) - ReKiBuf(Re_Xferred) = InData%MBM(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%KBB) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%KBB,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KBB,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%KBB,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KBB,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%KBB,2), UBOUND(InData%KBB,2) - DO i1 = LBOUND(InData%KBB,1), UBOUND(InData%KBB,1) - ReKiBuf(Re_Xferred) = InData%KBB(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%PhiL) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiL,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiL,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiL,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiL,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%PhiL,2), UBOUND(InData%PhiL,2) - DO i1 = LBOUND(InData%PhiL,1), UBOUND(InData%PhiL,1) - ReKiBuf(Re_Xferred) = InData%PhiL(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%PhiR) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiR,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiR,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiR,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiR,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%PhiR,2), UBOUND(InData%PhiR,2) - DO i1 = LBOUND(InData%PhiR,1), UBOUND(InData%PhiR,1) - ReKiBuf(Re_Xferred) = InData%PhiR(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%OmegaL) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IntKiBuf(Int_Xferred) = InData%eType Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 + ReKiBuf(Re_Xferred) = InData%Length + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Ixx + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Iyy + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Jzz + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%Shear, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%OmegaL,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%OmegaL,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%OmegaL,1), UBOUND(InData%OmegaL,1) - ReKiBuf(Re_Xferred) = InData%OmegaL(i1) - Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Kappa + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%YoungE + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%ShearG + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Area + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Rho + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%T0 + Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(InData%DirCos,2), UBOUND(InData%DirCos,2) + DO i1 = LBOUND(InData%DirCos,1), UBOUND(InData%DirCos,1) + DbKiBuf(Db_Xferred) = InData%DirCos(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO - END IF - END SUBROUTINE SD_PackCB_MatArrays + END DO + END SUBROUTINE SD_PackElemPropType - SUBROUTINE SD_UnPackCB_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE SD_UnPackElemPropType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(CB_MatArrays), INTENT(INOUT) :: OutData + TYPE(ElemPropType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -1895,7 +1808,7 @@ SUBROUTINE SD_UnPackCB_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackCB_MatArrays' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackElemPropType' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -1906,169 +1819,45 @@ SUBROUTINE SD_UnPackCB_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%DOFM = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TI2 not allocated + OutData%eType = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TI2)) DEALLOCATE(OutData%TI2) - ALLOCATE(OutData%TI2(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TI2.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%TI2,2), UBOUND(OutData%TI2,2) - DO i1 = LBOUND(OutData%TI2,1), UBOUND(OutData%TI2,1) - OutData%TI2(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MBB not allocated - Int_Xferred = Int_Xferred + 1 - ELSE + OutData%Length = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Ixx = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Iyy = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Jzz = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Shear = TRANSFER(IntKiBuf(Int_Xferred), OutData%Shear) Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%MBB)) DEALLOCATE(OutData%MBB) - ALLOCATE(OutData%MBB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MBB.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%MBB,2), UBOUND(OutData%MBB,2) - DO i1 = LBOUND(OutData%MBB,1), UBOUND(OutData%MBB,1) - OutData%MBB(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + OutData%Kappa = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%YoungE = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%ShearG = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Area = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Rho = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%T0 = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%DirCos,1) + i1_u = UBOUND(OutData%DirCos,1) + i2_l = LBOUND(OutData%DirCos,2) + i2_u = UBOUND(OutData%DirCos,2) + DO i2 = LBOUND(OutData%DirCos,2), UBOUND(OutData%DirCos,2) + DO i1 = LBOUND(OutData%DirCos,1), UBOUND(OutData%DirCos,1) + OutData%DirCos(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MBM not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%MBM)) DEALLOCATE(OutData%MBM) - ALLOCATE(OutData%MBM(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MBM.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%MBM,2), UBOUND(OutData%MBM,2) - DO i1 = LBOUND(OutData%MBM,1), UBOUND(OutData%MBM,1) - OutData%MBM(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! KBB not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%KBB)) DEALLOCATE(OutData%KBB) - ALLOCATE(OutData%KBB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%KBB.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%KBB,2), UBOUND(OutData%KBB,2) - DO i1 = LBOUND(OutData%KBB,1), UBOUND(OutData%KBB,1) - OutData%KBB(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PhiL not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%PhiL)) DEALLOCATE(OutData%PhiL) - ALLOCATE(OutData%PhiL(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PhiL.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%PhiL,2), UBOUND(OutData%PhiL,2) - DO i1 = LBOUND(OutData%PhiL,1), UBOUND(OutData%PhiL,1) - OutData%PhiL(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PhiR not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%PhiR)) DEALLOCATE(OutData%PhiR) - ALLOCATE(OutData%PhiR(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PhiR.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%PhiR,2), UBOUND(OutData%PhiR,2) - DO i1 = LBOUND(OutData%PhiR,1), UBOUND(OutData%PhiR,1) - OutData%PhiR(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OmegaL not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%OmegaL)) DEALLOCATE(OutData%OmegaL) - ALLOCATE(OutData%OmegaL(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OmegaL.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%OmegaL,1), UBOUND(OutData%OmegaL,1) - OutData%OmegaL(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - END SUBROUTINE SD_UnPackCB_MatArrays + END DO + END SUBROUTINE SD_UnPackElemPropType - SUBROUTINE SD_CopyFEM_MatArrays( SrcFEM_MatArraysData, DstFEM_MatArraysData, CtrlCode, ErrStat, ErrMsg ) - TYPE(FEM_MatArrays), INTENT(IN) :: SrcFEM_MatArraysData - TYPE(FEM_MatArrays), INTENT(INOUT) :: DstFEM_MatArraysData + SUBROUTINE SD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(SD_InitInputType), INTENT(INOUT) :: SrcInitInputData + TYPE(SD_InitInputType), INTENT(INOUT) :: DstInitInputData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -2076,63 +1865,61 @@ SUBROUTINE SD_CopyFEM_MatArrays( SrcFEM_MatArraysData, DstFEM_MatArraysData, Ctr INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyFEM_MatArrays' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyInitInput' ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(SrcFEM_MatArraysData%Omega)) THEN - i1_l = LBOUND(SrcFEM_MatArraysData%Omega,1) - i1_u = UBOUND(SrcFEM_MatArraysData%Omega,1) - IF (.NOT. ALLOCATED(DstFEM_MatArraysData%Omega)) THEN - ALLOCATE(DstFEM_MatArraysData%Omega(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstFEM_MatArraysData%Omega.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstFEM_MatArraysData%Omega = SrcFEM_MatArraysData%Omega -ENDIF - DstFEM_MatArraysData%NOmega = SrcFEM_MatArraysData%NOmega -IF (ALLOCATED(SrcFEM_MatArraysData%Modes)) THEN - i1_l = LBOUND(SrcFEM_MatArraysData%Modes,1) - i1_u = UBOUND(SrcFEM_MatArraysData%Modes,1) - i2_l = LBOUND(SrcFEM_MatArraysData%Modes,2) - i2_u = UBOUND(SrcFEM_MatArraysData%Modes,2) - IF (.NOT. ALLOCATED(DstFEM_MatArraysData%Modes)) THEN - ALLOCATE(DstFEM_MatArraysData%Modes(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstFEM_MatArraysData%Modes.', ErrStat, ErrMsg,RoutineName) + DstInitInputData%SDInputFile = SrcInitInputData%SDInputFile + DstInitInputData%RootName = SrcInitInputData%RootName + DstInitInputData%g = SrcInitInputData%g + DstInitInputData%WtrDpth = SrcInitInputData%WtrDpth + DstInitInputData%TP_RefPoint = SrcInitInputData%TP_RefPoint + DstInitInputData%SubRotateZ = SrcInitInputData%SubRotateZ +IF (ALLOCATED(SrcInitInputData%SoilStiffness)) THEN + i1_l = LBOUND(SrcInitInputData%SoilStiffness,1) + i1_u = UBOUND(SrcInitInputData%SoilStiffness,1) + i2_l = LBOUND(SrcInitInputData%SoilStiffness,2) + i2_u = UBOUND(SrcInitInputData%SoilStiffness,2) + i3_l = LBOUND(SrcInitInputData%SoilStiffness,3) + i3_u = UBOUND(SrcInitInputData%SoilStiffness,3) + IF (.NOT. ALLOCATED(DstInitInputData%SoilStiffness)) THEN + ALLOCATE(DstInitInputData%SoilStiffness(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%SoilStiffness.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstFEM_MatArraysData%Modes = SrcFEM_MatArraysData%Modes + DstInitInputData%SoilStiffness = SrcInitInputData%SoilStiffness ENDIF - END SUBROUTINE SD_CopyFEM_MatArrays + CALL MeshCopy( SrcInitInputData%SoilMesh, DstInitInputData%SoilMesh, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DstInitInputData%Linearize = SrcInitInputData%Linearize + END SUBROUTINE SD_CopyInitInput - SUBROUTINE SD_DestroyFEM_MatArrays( FEM_MatArraysData, ErrStat, ErrMsg ) - TYPE(FEM_MatArrays), INTENT(INOUT) :: FEM_MatArraysData + SUBROUTINE SD_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + TYPE(SD_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyFEM_MatArrays' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyInitInput' INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(FEM_MatArraysData%Omega)) THEN - DEALLOCATE(FEM_MatArraysData%Omega) +IF (ALLOCATED(InitInputData%SoilStiffness)) THEN + DEALLOCATE(InitInputData%SoilStiffness) ENDIF -IF (ALLOCATED(FEM_MatArraysData%Modes)) THEN - DEALLOCATE(FEM_MatArraysData%Modes) -ENDIF - END SUBROUTINE SD_DestroyFEM_MatArrays + CALL MeshDestroy( InitInputData%SoilMesh, ErrStat, ErrMsg ) + END SUBROUTINE SD_DestroyInitInput - SUBROUTINE SD_PackFEM_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE SD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(FEM_MatArrays), INTENT(IN) :: InData + TYPE(SD_InitInputType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -2147,7 +1934,7 @@ SUBROUTINE SD_PackFEM_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_PackFEM_MatArrays' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_PackInitInput' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -2163,17 +1950,36 @@ SUBROUTINE SD_PackFEM_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! Omega allocated yes/no - IF ( ALLOCATED(InData%Omega) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Omega upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Omega) ! Omega - END IF - Int_BufSz = Int_BufSz + 1 ! NOmega - Int_BufSz = Int_BufSz + 1 ! Modes allocated yes/no - IF ( ALLOCATED(InData%Modes) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! Modes upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Modes) ! Modes + Int_BufSz = Int_BufSz + 1*LEN(InData%SDInputFile) ! SDInputFile + Int_BufSz = Int_BufSz + 1*LEN(InData%RootName) ! RootName + Re_BufSz = Re_BufSz + 1 ! g + Re_BufSz = Re_BufSz + 1 ! WtrDpth + Re_BufSz = Re_BufSz + SIZE(InData%TP_RefPoint) ! TP_RefPoint + Re_BufSz = Re_BufSz + 1 ! SubRotateZ + Int_BufSz = Int_BufSz + 1 ! SoilStiffness allocated yes/no + IF ( ALLOCATED(InData%SoilStiffness) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! SoilStiffness upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%SoilStiffness) ! SoilStiffness END IF + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! SoilMesh: size of buffers for each call to pack subtype + CALL MeshPack( InData%SoilMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! SoilMesh + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! SoilMesh + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! SoilMesh + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! SoilMesh + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! Linearize IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -2201,50 +2007,86 @@ SUBROUTINE SD_PackFEM_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Db_Xferred = 1 Int_Xferred = 1 - IF ( .NOT. ALLOCATED(InData%Omega) ) THEN + DO I = 1, LEN(InData%SDInputFile) + IntKiBuf(Int_Xferred) = ICHAR(InData%SDInputFile(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DO I = 1, LEN(InData%RootName) + IntKiBuf(Int_Xferred) = ICHAR(InData%RootName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + ReKiBuf(Re_Xferred) = InData%g + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%WtrDpth + Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%TP_RefPoint,1), UBOUND(InData%TP_RefPoint,1) + ReKiBuf(Re_Xferred) = InData%TP_RefPoint(i1) + Re_Xferred = Re_Xferred + 1 + END DO + ReKiBuf(Re_Xferred) = InData%SubRotateZ + Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%SoilStiffness) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Omega,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Omega,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%SoilStiffness,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SoilStiffness,1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%Omega,1), UBOUND(InData%Omega,1) - ReKiBuf(Re_Xferred) = InData%Omega(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IntKiBuf(Int_Xferred) = InData%NOmega - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%Modes) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Modes,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Modes,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%SoilStiffness,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SoilStiffness,2) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Modes,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Modes,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%SoilStiffness,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SoilStiffness,3) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%Modes,2), UBOUND(InData%Modes,2) - DO i1 = LBOUND(InData%Modes,1), UBOUND(InData%Modes,1) - ReKiBuf(Re_Xferred) = InData%Modes(i1,i2) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(InData%SoilStiffness,3), UBOUND(InData%SoilStiffness,3) + DO i2 = LBOUND(InData%SoilStiffness,2), UBOUND(InData%SoilStiffness,2) + DO i1 = LBOUND(InData%SoilStiffness,1), UBOUND(InData%SoilStiffness,1) + ReKiBuf(Re_Xferred) = InData%SoilStiffness(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END IF - END SUBROUTINE SD_PackFEM_MatArrays + CALL MeshPack( InData%SoilMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! SoilMesh + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IntKiBuf(Int_Xferred) = TRANSFER(InData%Linearize, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE SD_PackInitInput - SUBROUTINE SD_UnPackFEM_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE SD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(FEM_MatArrays), INTENT(INOUT) :: OutData + TYPE(SD_InitInputType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -2255,9 +2097,10 @@ SUBROUTINE SD_UnPackFEM_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackFEM_MatArrays' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackInitInput' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -2268,27 +2111,27 @@ SUBROUTINE SD_UnPackFEM_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Omega not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Omega)) DEALLOCATE(OutData%Omega) - ALLOCATE(OutData%Omega(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Omega.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%Omega,1), UBOUND(OutData%Omega,1) - OutData%Omega(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - OutData%NOmega = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Modes not allocated + DO I = 1, LEN(OutData%SDInputFile) + OutData%SDInputFile(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DO I = 1, LEN(OutData%RootName) + OutData%RootName(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%g = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%WtrDpth = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%TP_RefPoint,1) + i1_u = UBOUND(OutData%TP_RefPoint,1) + DO i1 = LBOUND(OutData%TP_RefPoint,1), UBOUND(OutData%TP_RefPoint,1) + OutData%TP_RefPoint(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%SubRotateZ = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! SoilStiffness not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -2298,66 +2141,255 @@ SUBROUTINE SD_UnPackFEM_MatArrays( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Modes)) DEALLOCATE(OutData%Modes) - ALLOCATE(OutData%Modes(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%SoilStiffness)) DEALLOCATE(OutData%SoilStiffness) + ALLOCATE(OutData%SoilStiffness(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Modes.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%SoilStiffness.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%Modes,2), UBOUND(OutData%Modes,2) - DO i1 = LBOUND(OutData%Modes,1), UBOUND(OutData%Modes,1) - OutData%Modes(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(OutData%SoilStiffness,3), UBOUND(OutData%SoilStiffness,3) + DO i2 = LBOUND(OutData%SoilStiffness,2), UBOUND(OutData%SoilStiffness,2) + DO i1 = LBOUND(OutData%SoilStiffness,1), UBOUND(OutData%SoilStiffness,1) + OutData%SoilStiffness(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END IF - END SUBROUTINE SD_UnPackFEM_MatArrays + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MeshUnpack( OutData%SoilMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! SoilMesh + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN - SUBROUTINE SD_CopyElemPropType( SrcElemPropTypeData, DstElemPropTypeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(ElemPropType), INTENT(IN) :: SrcElemPropTypeData - TYPE(ElemPropType), INTENT(INOUT) :: DstElemPropTypeData + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + OutData%Linearize = TRANSFER(IntKiBuf(Int_Xferred), OutData%Linearize) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE SD_UnPackInitInput + + SUBROUTINE SD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(SD_InitOutputType), INTENT(IN) :: SrcInitOutputData + TYPE(SD_InitOutputType), INTENT(INOUT) :: DstInitOutputData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyElemPropType' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyInitOutput' ! ErrStat = ErrID_None ErrMsg = "" - DstElemPropTypeData%Area = SrcElemPropTypeData%Area - DstElemPropTypeData%Length = SrcElemPropTypeData%Length - DstElemPropTypeData%Ixx = SrcElemPropTypeData%Ixx - DstElemPropTypeData%Iyy = SrcElemPropTypeData%Iyy - DstElemPropTypeData%Jzz = SrcElemPropTypeData%Jzz - DstElemPropTypeData%Shear = SrcElemPropTypeData%Shear - DstElemPropTypeData%Kappa = SrcElemPropTypeData%Kappa - DstElemPropTypeData%YoungE = SrcElemPropTypeData%YoungE - DstElemPropTypeData%ShearG = SrcElemPropTypeData%ShearG - DstElemPropTypeData%Rho = SrcElemPropTypeData%Rho - DstElemPropTypeData%DirCos = SrcElemPropTypeData%DirCos - END SUBROUTINE SD_CopyElemPropType +IF (ALLOCATED(SrcInitOutputData%WriteOutputHdr)) THEN + i1_l = LBOUND(SrcInitOutputData%WriteOutputHdr,1) + i1_u = UBOUND(SrcInitOutputData%WriteOutputHdr,1) + IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputHdr)) THEN + ALLOCATE(DstInitOutputData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%WriteOutputHdr = SrcInitOutputData%WriteOutputHdr +ENDIF +IF (ALLOCATED(SrcInitOutputData%WriteOutputUnt)) THEN + i1_l = LBOUND(SrcInitOutputData%WriteOutputUnt,1) + i1_u = UBOUND(SrcInitOutputData%WriteOutputUnt,1) + IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputUnt)) THEN + ALLOCATE(DstInitOutputData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%WriteOutputUnt = SrcInitOutputData%WriteOutputUnt +ENDIF + CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcInitOutputData%LinNames_y)) THEN + i1_l = LBOUND(SrcInitOutputData%LinNames_y,1) + i1_u = UBOUND(SrcInitOutputData%LinNames_y,1) + IF (.NOT. ALLOCATED(DstInitOutputData%LinNames_y)) THEN + ALLOCATE(DstInitOutputData%LinNames_y(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%LinNames_y.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%LinNames_y = SrcInitOutputData%LinNames_y +ENDIF +IF (ALLOCATED(SrcInitOutputData%LinNames_x)) THEN + i1_l = LBOUND(SrcInitOutputData%LinNames_x,1) + i1_u = UBOUND(SrcInitOutputData%LinNames_x,1) + IF (.NOT. ALLOCATED(DstInitOutputData%LinNames_x)) THEN + ALLOCATE(DstInitOutputData%LinNames_x(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%LinNames_x.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%LinNames_x = SrcInitOutputData%LinNames_x +ENDIF +IF (ALLOCATED(SrcInitOutputData%LinNames_u)) THEN + i1_l = LBOUND(SrcInitOutputData%LinNames_u,1) + i1_u = UBOUND(SrcInitOutputData%LinNames_u,1) + IF (.NOT. ALLOCATED(DstInitOutputData%LinNames_u)) THEN + ALLOCATE(DstInitOutputData%LinNames_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%LinNames_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%LinNames_u = SrcInitOutputData%LinNames_u +ENDIF +IF (ALLOCATED(SrcInitOutputData%RotFrame_y)) THEN + i1_l = LBOUND(SrcInitOutputData%RotFrame_y,1) + i1_u = UBOUND(SrcInitOutputData%RotFrame_y,1) + IF (.NOT. ALLOCATED(DstInitOutputData%RotFrame_y)) THEN + ALLOCATE(DstInitOutputData%RotFrame_y(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%RotFrame_y.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%RotFrame_y = SrcInitOutputData%RotFrame_y +ENDIF +IF (ALLOCATED(SrcInitOutputData%RotFrame_x)) THEN + i1_l = LBOUND(SrcInitOutputData%RotFrame_x,1) + i1_u = UBOUND(SrcInitOutputData%RotFrame_x,1) + IF (.NOT. ALLOCATED(DstInitOutputData%RotFrame_x)) THEN + ALLOCATE(DstInitOutputData%RotFrame_x(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%RotFrame_x.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%RotFrame_x = SrcInitOutputData%RotFrame_x +ENDIF +IF (ALLOCATED(SrcInitOutputData%RotFrame_u)) THEN + i1_l = LBOUND(SrcInitOutputData%RotFrame_u,1) + i1_u = UBOUND(SrcInitOutputData%RotFrame_u,1) + IF (.NOT. ALLOCATED(DstInitOutputData%RotFrame_u)) THEN + ALLOCATE(DstInitOutputData%RotFrame_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%RotFrame_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%RotFrame_u = SrcInitOutputData%RotFrame_u +ENDIF +IF (ALLOCATED(SrcInitOutputData%IsLoad_u)) THEN + i1_l = LBOUND(SrcInitOutputData%IsLoad_u,1) + i1_u = UBOUND(SrcInitOutputData%IsLoad_u,1) + IF (.NOT. ALLOCATED(DstInitOutputData%IsLoad_u)) THEN + ALLOCATE(DstInitOutputData%IsLoad_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%IsLoad_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%IsLoad_u = SrcInitOutputData%IsLoad_u +ENDIF +IF (ALLOCATED(SrcInitOutputData%DerivOrder_x)) THEN + i1_l = LBOUND(SrcInitOutputData%DerivOrder_x,1) + i1_u = UBOUND(SrcInitOutputData%DerivOrder_x,1) + IF (.NOT. ALLOCATED(DstInitOutputData%DerivOrder_x)) THEN + ALLOCATE(DstInitOutputData%DerivOrder_x(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%DerivOrder_x.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%DerivOrder_x = SrcInitOutputData%DerivOrder_x +ENDIF + END SUBROUTINE SD_CopyInitOutput - SUBROUTINE SD_DestroyElemPropType( ElemPropTypeData, ErrStat, ErrMsg ) - TYPE(ElemPropType), INTENT(INOUT) :: ElemPropTypeData + SUBROUTINE SD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + TYPE(SD_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyElemPropType' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyInitOutput' INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 ! ErrStat = ErrID_None ErrMsg = "" - END SUBROUTINE SD_DestroyElemPropType +IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN + DEALLOCATE(InitOutputData%WriteOutputHdr) +ENDIF +IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN + DEALLOCATE(InitOutputData%WriteOutputUnt) +ENDIF + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) +IF (ALLOCATED(InitOutputData%LinNames_y)) THEN + DEALLOCATE(InitOutputData%LinNames_y) +ENDIF +IF (ALLOCATED(InitOutputData%LinNames_x)) THEN + DEALLOCATE(InitOutputData%LinNames_x) +ENDIF +IF (ALLOCATED(InitOutputData%LinNames_u)) THEN + DEALLOCATE(InitOutputData%LinNames_u) +ENDIF +IF (ALLOCATED(InitOutputData%RotFrame_y)) THEN + DEALLOCATE(InitOutputData%RotFrame_y) +ENDIF +IF (ALLOCATED(InitOutputData%RotFrame_x)) THEN + DEALLOCATE(InitOutputData%RotFrame_x) +ENDIF +IF (ALLOCATED(InitOutputData%RotFrame_u)) THEN + DEALLOCATE(InitOutputData%RotFrame_u) +ENDIF +IF (ALLOCATED(InitOutputData%IsLoad_u)) THEN + DEALLOCATE(InitOutputData%IsLoad_u) +ENDIF +IF (ALLOCATED(InitOutputData%DerivOrder_x)) THEN + DEALLOCATE(InitOutputData%DerivOrder_x) +ENDIF + END SUBROUTINE SD_DestroyInitOutput - SUBROUTINE SD_PackElemPropType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE SD_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(ElemPropType), INTENT(IN) :: InData + TYPE(SD_InitOutputType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -2372,7 +2404,7 @@ SUBROUTINE SD_PackElemPropType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_PackElemPropType' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_PackInitOutput' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -2388,17 +2420,74 @@ SUBROUTINE SD_PackElemPropType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! Area - Re_BufSz = Re_BufSz + 1 ! Length - Re_BufSz = Re_BufSz + 1 ! Ixx - Re_BufSz = Re_BufSz + 1 ! Iyy - Re_BufSz = Re_BufSz + 1 ! Jzz - Int_BufSz = Int_BufSz + 1 ! Shear - Re_BufSz = Re_BufSz + 1 ! Kappa - Re_BufSz = Re_BufSz + 1 ! YoungE - Re_BufSz = Re_BufSz + 1 ! ShearG - Re_BufSz = Re_BufSz + 1 ! Rho - Re_BufSz = Re_BufSz + SIZE(InData%DirCos) ! DirCos + Int_BufSz = Int_BufSz + 1 ! WriteOutputHdr allocated yes/no + IF ( ALLOCATED(InData%WriteOutputHdr) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WriteOutputHdr upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputHdr)*LEN(InData%WriteOutputHdr) ! WriteOutputHdr + END IF + Int_BufSz = Int_BufSz + 1 ! WriteOutputUnt allocated yes/no + IF ( ALLOCATED(InData%WriteOutputUnt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WriteOutputUnt upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%WriteOutputUnt)*LEN(InData%WriteOutputUnt) ! WriteOutputUnt + END IF + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype + CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Ver + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Ver + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Ver + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! LinNames_y allocated yes/no + IF ( ALLOCATED(InData%LinNames_y) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LinNames_y upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%LinNames_y)*LEN(InData%LinNames_y) ! LinNames_y + END IF + Int_BufSz = Int_BufSz + 1 ! LinNames_x allocated yes/no + IF ( ALLOCATED(InData%LinNames_x) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LinNames_x upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%LinNames_x)*LEN(InData%LinNames_x) ! LinNames_x + END IF + Int_BufSz = Int_BufSz + 1 ! LinNames_u allocated yes/no + IF ( ALLOCATED(InData%LinNames_u) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LinNames_u upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%LinNames_u)*LEN(InData%LinNames_u) ! LinNames_u + END IF + Int_BufSz = Int_BufSz + 1 ! RotFrame_y allocated yes/no + IF ( ALLOCATED(InData%RotFrame_y) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! RotFrame_y upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%RotFrame_y) ! RotFrame_y + END IF + Int_BufSz = Int_BufSz + 1 ! RotFrame_x allocated yes/no + IF ( ALLOCATED(InData%RotFrame_x) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! RotFrame_x upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%RotFrame_x) ! RotFrame_x + END IF + Int_BufSz = Int_BufSz + 1 ! RotFrame_u allocated yes/no + IF ( ALLOCATED(InData%RotFrame_u) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! RotFrame_u upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%RotFrame_u) ! RotFrame_u + END IF + Int_BufSz = Int_BufSz + 1 ! IsLoad_u allocated yes/no + IF ( ALLOCATED(InData%IsLoad_u) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! IsLoad_u upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%IsLoad_u) ! IsLoad_u + END IF + Int_BufSz = Int_BufSz + 1 ! DerivOrder_x allocated yes/no + IF ( ALLOCATED(InData%DerivOrder_x) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! DerivOrder_x upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%DerivOrder_x) ! DerivOrder_x + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -2426,52 +2515,213 @@ SUBROUTINE SD_PackElemPropType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Db_Xferred = 1 Int_Xferred = 1 - ReKiBuf(Re_Xferred) = InData%Area - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Length - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Ixx - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Iyy - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Jzz - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%Shear, IntKiBuf(1)) + IF ( .NOT. ALLOCATED(InData%WriteOutputHdr) ) THEN + IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Kappa - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%YoungE - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%ShearG - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Rho - Re_Xferred = Re_Xferred + 1 - DO i2 = LBOUND(InData%DirCos,2), UBOUND(InData%DirCos,2) - DO i1 = LBOUND(InData%DirCos,1), UBOUND(InData%DirCos,1) - ReKiBuf(Re_Xferred) = InData%DirCos(i1,i2) - Re_Xferred = Re_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutputHdr,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputHdr,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WriteOutputHdr,1), UBOUND(InData%WriteOutputHdr,1) + DO I = 1, LEN(InData%WriteOutputHdr) + IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputHdr(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I END DO - END DO - END SUBROUTINE SD_PackElemPropType + END IF + IF ( .NOT. ALLOCATED(InData%WriteOutputUnt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WriteOutputUnt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputUnt,1) + Int_Xferred = Int_Xferred + 2 - SUBROUTINE SD_UnPackElemPropType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(ElemPropType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables + DO i1 = LBOUND(InData%WriteOutputUnt,1), UBOUND(InData%WriteOutputUnt,1) + DO I = 1, LEN(InData%WriteOutputUnt) + IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputUnt(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, OnlySize ) ! Ver + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF ( .NOT. ALLOCATED(InData%LinNames_y) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LinNames_y,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LinNames_y,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LinNames_y,1), UBOUND(InData%LinNames_y,1) + DO I = 1, LEN(InData%LinNames_y) + IntKiBuf(Int_Xferred) = ICHAR(InData%LinNames_y(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IF ( .NOT. ALLOCATED(InData%LinNames_x) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LinNames_x,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LinNames_x,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LinNames_x,1), UBOUND(InData%LinNames_x,1) + DO I = 1, LEN(InData%LinNames_x) + IntKiBuf(Int_Xferred) = ICHAR(InData%LinNames_x(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IF ( .NOT. ALLOCATED(InData%LinNames_u) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LinNames_u,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LinNames_u,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LinNames_u,1), UBOUND(InData%LinNames_u,1) + DO I = 1, LEN(InData%LinNames_u) + IntKiBuf(Int_Xferred) = ICHAR(InData%LinNames_u(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IF ( .NOT. ALLOCATED(InData%RotFrame_y) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%RotFrame_y,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RotFrame_y,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%RotFrame_y,1), UBOUND(InData%RotFrame_y,1) + IntKiBuf(Int_Xferred) = TRANSFER(InData%RotFrame_y(i1), IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%RotFrame_x) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%RotFrame_x,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RotFrame_x,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%RotFrame_x,1), UBOUND(InData%RotFrame_x,1) + IntKiBuf(Int_Xferred) = TRANSFER(InData%RotFrame_x(i1), IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%RotFrame_u) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%RotFrame_u,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RotFrame_u,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%RotFrame_u,1), UBOUND(InData%RotFrame_u,1) + IntKiBuf(Int_Xferred) = TRANSFER(InData%RotFrame_u(i1), IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%IsLoad_u) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%IsLoad_u,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IsLoad_u,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%IsLoad_u,1), UBOUND(InData%IsLoad_u,1) + IntKiBuf(Int_Xferred) = TRANSFER(InData%IsLoad_u(i1), IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%DerivOrder_x) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%DerivOrder_x,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DerivOrder_x,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%DerivOrder_x,1), UBOUND(InData%DerivOrder_x,1) + IntKiBuf(Int_Xferred) = InData%DerivOrder_x(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + END SUBROUTINE SD_PackInitOutput + + SUBROUTINE SD_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(SD_InitOutputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables INTEGER(IntKi) :: Buf_size INTEGER(IntKi) :: Re_Xferred INTEGER(IntKi) :: Db_Xferred INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackElemPropType' + CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackInitOutput' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -2482,127 +2732,357 @@ SUBROUTINE SD_UnPackElemPropType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%Area = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Length = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Ixx = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Iyy = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Jzz = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Shear = TRANSFER(IntKiBuf(Int_Xferred), OutData%Shear) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputHdr not allocated Int_Xferred = Int_Xferred + 1 - OutData%Kappa = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%YoungE = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%ShearG = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Rho = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - i1_l = LBOUND(OutData%DirCos,1) - i1_u = UBOUND(OutData%DirCos,1) - i2_l = LBOUND(OutData%DirCos,2) - i2_u = UBOUND(OutData%DirCos,2) - DO i2 = LBOUND(OutData%DirCos,2), UBOUND(OutData%DirCos,2) - DO i1 = LBOUND(OutData%DirCos,1), UBOUND(OutData%DirCos,1) - OutData%DirCos(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END SUBROUTINE SD_UnPackElemPropType - - SUBROUTINE SD_CopyInitType( SrcInitTypeData, DstInitTypeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(SD_InitType), INTENT(IN) :: SrcInitTypeData - TYPE(SD_InitType), INTENT(INOUT) :: DstInitTypeData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyInitType' -! - ErrStat = ErrID_None - ErrMsg = "" - DstInitTypeData%RootName = SrcInitTypeData%RootName - DstInitTypeData%TP_RefPoint = SrcInitTypeData%TP_RefPoint - DstInitTypeData%SubRotateZ = SrcInitTypeData%SubRotateZ - DstInitTypeData%g = SrcInitTypeData%g - DstInitTypeData%DT = SrcInitTypeData%DT - DstInitTypeData%NJoints = SrcInitTypeData%NJoints - DstInitTypeData%NPropSets = SrcInitTypeData%NPropSets - DstInitTypeData%NXPropSets = SrcInitTypeData%NXPropSets - DstInitTypeData%NInterf = SrcInitTypeData%NInterf - DstInitTypeData%NCMass = SrcInitTypeData%NCMass - DstInitTypeData%NCOSMs = SrcInitTypeData%NCOSMs - DstInitTypeData%FEMMod = SrcInitTypeData%FEMMod - DstInitTypeData%NDiv = SrcInitTypeData%NDiv - DstInitTypeData%CBMod = SrcInitTypeData%CBMod -IF (ALLOCATED(SrcInitTypeData%Joints)) THEN - i1_l = LBOUND(SrcInitTypeData%Joints,1) - i1_u = UBOUND(SrcInitTypeData%Joints,1) - i2_l = LBOUND(SrcInitTypeData%Joints,2) - i2_u = UBOUND(SrcInitTypeData%Joints,2) - IF (.NOT. ALLOCATED(DstInitTypeData%Joints)) THEN - ALLOCATE(DstInitTypeData%Joints(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%Joints.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInitTypeData%Joints = SrcInitTypeData%Joints -ENDIF -IF (ALLOCATED(SrcInitTypeData%PropSets)) THEN - i1_l = LBOUND(SrcInitTypeData%PropSets,1) - i1_u = UBOUND(SrcInitTypeData%PropSets,1) - i2_l = LBOUND(SrcInitTypeData%PropSets,2) - i2_u = UBOUND(SrcInitTypeData%PropSets,2) - IF (.NOT. ALLOCATED(DstInitTypeData%PropSets)) THEN - ALLOCATE(DstInitTypeData%PropSets(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%PropSets.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInitTypeData%PropSets = SrcInitTypeData%PropSets -ENDIF -IF (ALLOCATED(SrcInitTypeData%XPropSets)) THEN - i1_l = LBOUND(SrcInitTypeData%XPropSets,1) - i1_u = UBOUND(SrcInitTypeData%XPropSets,1) - i2_l = LBOUND(SrcInitTypeData%XPropSets,2) - i2_u = UBOUND(SrcInitTypeData%XPropSets,2) - IF (.NOT. ALLOCATED(DstInitTypeData%XPropSets)) THEN - ALLOCATE(DstInitTypeData%XPropSets(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WriteOutputHdr)) DEALLOCATE(OutData%WriteOutputHdr) + ALLOCATE(OutData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%XPropSets.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) + RETURN END IF + DO i1 = LBOUND(OutData%WriteOutputHdr,1), UBOUND(OutData%WriteOutputHdr,1) + DO I = 1, LEN(OutData%WriteOutputHdr) + OutData%WriteOutputHdr(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO END IF - DstInitTypeData%XPropSets = SrcInitTypeData%XPropSets -ENDIF -IF (ALLOCATED(SrcInitTypeData%COSMs)) THEN - i1_l = LBOUND(SrcInitTypeData%COSMs,1) - i1_u = UBOUND(SrcInitTypeData%COSMs,1) - i2_l = LBOUND(SrcInitTypeData%COSMs,2) - i2_u = UBOUND(SrcInitTypeData%COSMs,2) - IF (.NOT. ALLOCATED(DstInitTypeData%COSMs)) THEN - ALLOCATE(DstInitTypeData%COSMs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputUnt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WriteOutputUnt)) DEALLOCATE(OutData%WriteOutputUnt) + ALLOCATE(OutData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%COSMs.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) + RETURN END IF + DO i1 = LBOUND(OutData%WriteOutputUnt,1), UBOUND(OutData%WriteOutputUnt,1) + DO I = 1, LEN(OutData%WriteOutputUnt) + OutData%WriteOutputUnt(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO END IF - DstInitTypeData%COSMs = SrcInitTypeData%COSMs -ENDIF -IF (ALLOCATED(SrcInitTypeData%CMass)) THEN - i1_l = LBOUND(SrcInitTypeData%CMass,1) - i1_u = UBOUND(SrcInitTypeData%CMass,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LinNames_y not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LinNames_y)) DEALLOCATE(OutData%LinNames_y) + ALLOCATE(OutData%LinNames_y(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LinNames_y.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LinNames_y,1), UBOUND(OutData%LinNames_y,1) + DO I = 1, LEN(OutData%LinNames_y) + OutData%LinNames_y(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LinNames_x not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LinNames_x)) DEALLOCATE(OutData%LinNames_x) + ALLOCATE(OutData%LinNames_x(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LinNames_x.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LinNames_x,1), UBOUND(OutData%LinNames_x,1) + DO I = 1, LEN(OutData%LinNames_x) + OutData%LinNames_x(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LinNames_u not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LinNames_u)) DEALLOCATE(OutData%LinNames_u) + ALLOCATE(OutData%LinNames_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LinNames_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LinNames_u,1), UBOUND(OutData%LinNames_u,1) + DO I = 1, LEN(OutData%LinNames_u) + OutData%LinNames_u(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! RotFrame_y not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%RotFrame_y)) DEALLOCATE(OutData%RotFrame_y) + ALLOCATE(OutData%RotFrame_y(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%RotFrame_y.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%RotFrame_y,1), UBOUND(OutData%RotFrame_y,1) + OutData%RotFrame_y(i1) = TRANSFER(IntKiBuf(Int_Xferred), OutData%RotFrame_y(i1)) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! RotFrame_x not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%RotFrame_x)) DEALLOCATE(OutData%RotFrame_x) + ALLOCATE(OutData%RotFrame_x(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%RotFrame_x.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%RotFrame_x,1), UBOUND(OutData%RotFrame_x,1) + OutData%RotFrame_x(i1) = TRANSFER(IntKiBuf(Int_Xferred), OutData%RotFrame_x(i1)) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! RotFrame_u not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%RotFrame_u)) DEALLOCATE(OutData%RotFrame_u) + ALLOCATE(OutData%RotFrame_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%RotFrame_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%RotFrame_u,1), UBOUND(OutData%RotFrame_u,1) + OutData%RotFrame_u(i1) = TRANSFER(IntKiBuf(Int_Xferred), OutData%RotFrame_u(i1)) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IsLoad_u not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%IsLoad_u)) DEALLOCATE(OutData%IsLoad_u) + ALLOCATE(OutData%IsLoad_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IsLoad_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%IsLoad_u,1), UBOUND(OutData%IsLoad_u,1) + OutData%IsLoad_u(i1) = TRANSFER(IntKiBuf(Int_Xferred), OutData%IsLoad_u(i1)) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! DerivOrder_x not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%DerivOrder_x)) DEALLOCATE(OutData%DerivOrder_x) + ALLOCATE(OutData%DerivOrder_x(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%DerivOrder_x.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%DerivOrder_x,1), UBOUND(OutData%DerivOrder_x,1) + OutData%DerivOrder_x(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + END SUBROUTINE SD_UnPackInitOutput + + SUBROUTINE SD_CopyInitType( SrcInitTypeData, DstInitTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(SD_InitType), INTENT(IN) :: SrcInitTypeData + TYPE(SD_InitType), INTENT(INOUT) :: DstInitTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyInitType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstInitTypeData%RootName = SrcInitTypeData%RootName + DstInitTypeData%TP_RefPoint = SrcInitTypeData%TP_RefPoint + DstInitTypeData%SubRotateZ = SrcInitTypeData%SubRotateZ + DstInitTypeData%g = SrcInitTypeData%g + DstInitTypeData%DT = SrcInitTypeData%DT + DstInitTypeData%NJoints = SrcInitTypeData%NJoints + DstInitTypeData%NPropSetsX = SrcInitTypeData%NPropSetsX + DstInitTypeData%NPropSetsB = SrcInitTypeData%NPropSetsB + DstInitTypeData%NPropSetsC = SrcInitTypeData%NPropSetsC + DstInitTypeData%NPropSetsR = SrcInitTypeData%NPropSetsR + DstInitTypeData%NCMass = SrcInitTypeData%NCMass + DstInitTypeData%NCOSMs = SrcInitTypeData%NCOSMs + DstInitTypeData%FEMMod = SrcInitTypeData%FEMMod + DstInitTypeData%NDiv = SrcInitTypeData%NDiv + DstInitTypeData%CBMod = SrcInitTypeData%CBMod +IF (ALLOCATED(SrcInitTypeData%Joints)) THEN + i1_l = LBOUND(SrcInitTypeData%Joints,1) + i1_u = UBOUND(SrcInitTypeData%Joints,1) + i2_l = LBOUND(SrcInitTypeData%Joints,2) + i2_u = UBOUND(SrcInitTypeData%Joints,2) + IF (.NOT. ALLOCATED(DstInitTypeData%Joints)) THEN + ALLOCATE(DstInitTypeData%Joints(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%Joints.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitTypeData%Joints = SrcInitTypeData%Joints +ENDIF +IF (ALLOCATED(SrcInitTypeData%PropSetsB)) THEN + i1_l = LBOUND(SrcInitTypeData%PropSetsB,1) + i1_u = UBOUND(SrcInitTypeData%PropSetsB,1) + i2_l = LBOUND(SrcInitTypeData%PropSetsB,2) + i2_u = UBOUND(SrcInitTypeData%PropSetsB,2) + IF (.NOT. ALLOCATED(DstInitTypeData%PropSetsB)) THEN + ALLOCATE(DstInitTypeData%PropSetsB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%PropSetsB.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitTypeData%PropSetsB = SrcInitTypeData%PropSetsB +ENDIF +IF (ALLOCATED(SrcInitTypeData%PropSetsC)) THEN + i1_l = LBOUND(SrcInitTypeData%PropSetsC,1) + i1_u = UBOUND(SrcInitTypeData%PropSetsC,1) + i2_l = LBOUND(SrcInitTypeData%PropSetsC,2) + i2_u = UBOUND(SrcInitTypeData%PropSetsC,2) + IF (.NOT. ALLOCATED(DstInitTypeData%PropSetsC)) THEN + ALLOCATE(DstInitTypeData%PropSetsC(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%PropSetsC.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitTypeData%PropSetsC = SrcInitTypeData%PropSetsC +ENDIF +IF (ALLOCATED(SrcInitTypeData%PropSetsR)) THEN + i1_l = LBOUND(SrcInitTypeData%PropSetsR,1) + i1_u = UBOUND(SrcInitTypeData%PropSetsR,1) + i2_l = LBOUND(SrcInitTypeData%PropSetsR,2) + i2_u = UBOUND(SrcInitTypeData%PropSetsR,2) + IF (.NOT. ALLOCATED(DstInitTypeData%PropSetsR)) THEN + ALLOCATE(DstInitTypeData%PropSetsR(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%PropSetsR.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitTypeData%PropSetsR = SrcInitTypeData%PropSetsR +ENDIF +IF (ALLOCATED(SrcInitTypeData%PropSetsX)) THEN + i1_l = LBOUND(SrcInitTypeData%PropSetsX,1) + i1_u = UBOUND(SrcInitTypeData%PropSetsX,1) + i2_l = LBOUND(SrcInitTypeData%PropSetsX,2) + i2_u = UBOUND(SrcInitTypeData%PropSetsX,2) + IF (.NOT. ALLOCATED(DstInitTypeData%PropSetsX)) THEN + ALLOCATE(DstInitTypeData%PropSetsX(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%PropSetsX.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitTypeData%PropSetsX = SrcInitTypeData%PropSetsX +ENDIF +IF (ALLOCATED(SrcInitTypeData%COSMs)) THEN + i1_l = LBOUND(SrcInitTypeData%COSMs,1) + i1_u = UBOUND(SrcInitTypeData%COSMs,1) + i2_l = LBOUND(SrcInitTypeData%COSMs,2) + i2_u = UBOUND(SrcInitTypeData%COSMs,2) + IF (.NOT. ALLOCATED(DstInitTypeData%COSMs)) THEN + ALLOCATE(DstInitTypeData%COSMs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%COSMs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitTypeData%COSMs = SrcInitTypeData%COSMs +ENDIF +IF (ALLOCATED(SrcInitTypeData%CMass)) THEN + i1_l = LBOUND(SrcInitTypeData%CMass,1) + i1_u = UBOUND(SrcInitTypeData%CMass,1) i2_l = LBOUND(SrcInitTypeData%CMass,2) i2_u = UBOUND(SrcInitTypeData%CMass,2) IF (.NOT. ALLOCATED(DstInitTypeData%CMass)) THEN @@ -2626,6 +3106,9 @@ SUBROUTINE SD_CopyInitType( SrcInitTypeData, DstInitTypeData, CtrlCode, ErrStat, END IF DstInitTypeData%JDampings = SrcInitTypeData%JDampings ENDIF + DstInitTypeData%GuyanDampMod = SrcInitTypeData%GuyanDampMod + DstInitTypeData%RayleighDamp = SrcInitTypeData%RayleighDamp + DstInitTypeData%GuyanDampMat = SrcInitTypeData%GuyanDampMat IF (ALLOCATED(SrcInitTypeData%Members)) THEN i1_l = LBOUND(SrcInitTypeData%Members,1) i1_u = UBOUND(SrcInitTypeData%Members,1) @@ -2640,20 +3123,6 @@ SUBROUTINE SD_CopyInitType( SrcInitTypeData, DstInitTypeData, CtrlCode, ErrStat, END IF DstInitTypeData%Members = SrcInitTypeData%Members ENDIF -IF (ALLOCATED(SrcInitTypeData%Interf)) THEN - i1_l = LBOUND(SrcInitTypeData%Interf,1) - i1_u = UBOUND(SrcInitTypeData%Interf,1) - i2_l = LBOUND(SrcInitTypeData%Interf,2) - i2_u = UBOUND(SrcInitTypeData%Interf,2) - IF (.NOT. ALLOCATED(DstInitTypeData%Interf)) THEN - ALLOCATE(DstInitTypeData%Interf(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%Interf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInitTypeData%Interf = SrcInitTypeData%Interf -ENDIF IF (ALLOCATED(SrcInitTypeData%SSOutList)) THEN i1_l = LBOUND(SrcInitTypeData%SSOutList,1) i1_u = UBOUND(SrcInitTypeData%SSOutList,1) @@ -2668,131 +3137,189 @@ SUBROUTINE SD_CopyInitType( SrcInitTypeData, DstInitTypeData, CtrlCode, ErrStat, ENDIF DstInitTypeData%OutCOSM = SrcInitTypeData%OutCOSM DstInitTypeData%TabDelim = SrcInitTypeData%TabDelim - DstInitTypeData%NNode = SrcInitTypeData%NNode - DstInitTypeData%NElem = SrcInitTypeData%NElem - DstInitTypeData%NProp = SrcInitTypeData%NProp - DstInitTypeData%TDOF = SrcInitTypeData%TDOF -IF (ALLOCATED(SrcInitTypeData%Nodes)) THEN - i1_l = LBOUND(SrcInitTypeData%Nodes,1) - i1_u = UBOUND(SrcInitTypeData%Nodes,1) - i2_l = LBOUND(SrcInitTypeData%Nodes,2) - i2_u = UBOUND(SrcInitTypeData%Nodes,2) - IF (.NOT. ALLOCATED(DstInitTypeData%Nodes)) THEN - ALLOCATE(DstInitTypeData%Nodes(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%Nodes.', ErrStat, ErrMsg,RoutineName) +IF (ALLOCATED(SrcInitTypeData%SSIK)) THEN + i1_l = LBOUND(SrcInitTypeData%SSIK,1) + i1_u = UBOUND(SrcInitTypeData%SSIK,1) + i2_l = LBOUND(SrcInitTypeData%SSIK,2) + i2_u = UBOUND(SrcInitTypeData%SSIK,2) + IF (.NOT. ALLOCATED(DstInitTypeData%SSIK)) THEN + ALLOCATE(DstInitTypeData%SSIK(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%SSIK.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInitTypeData%Nodes = SrcInitTypeData%Nodes + DstInitTypeData%SSIK = SrcInitTypeData%SSIK ENDIF -IF (ALLOCATED(SrcInitTypeData%Props)) THEN - i1_l = LBOUND(SrcInitTypeData%Props,1) - i1_u = UBOUND(SrcInitTypeData%Props,1) - i2_l = LBOUND(SrcInitTypeData%Props,2) - i2_u = UBOUND(SrcInitTypeData%Props,2) - IF (.NOT. ALLOCATED(DstInitTypeData%Props)) THEN - ALLOCATE(DstInitTypeData%Props(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcInitTypeData%SSIM)) THEN + i1_l = LBOUND(SrcInitTypeData%SSIM,1) + i1_u = UBOUND(SrcInitTypeData%SSIM,1) + i2_l = LBOUND(SrcInitTypeData%SSIM,2) + i2_u = UBOUND(SrcInitTypeData%SSIM,2) + IF (.NOT. ALLOCATED(DstInitTypeData%SSIM)) THEN + ALLOCATE(DstInitTypeData%SSIM(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%Props.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%SSIM.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInitTypeData%Props = SrcInitTypeData%Props + DstInitTypeData%SSIM = SrcInitTypeData%SSIM ENDIF -IF (ALLOCATED(SrcInitTypeData%K)) THEN - i1_l = LBOUND(SrcInitTypeData%K,1) - i1_u = UBOUND(SrcInitTypeData%K,1) - i2_l = LBOUND(SrcInitTypeData%K,2) - i2_u = UBOUND(SrcInitTypeData%K,2) - IF (.NOT. ALLOCATED(DstInitTypeData%K)) THEN - ALLOCATE(DstInitTypeData%K(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcInitTypeData%SSIfile)) THEN + i1_l = LBOUND(SrcInitTypeData%SSIfile,1) + i1_u = UBOUND(SrcInitTypeData%SSIfile,1) + IF (.NOT. ALLOCATED(DstInitTypeData%SSIfile)) THEN + ALLOCATE(DstInitTypeData%SSIfile(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%K.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%SSIfile.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInitTypeData%K = SrcInitTypeData%K + DstInitTypeData%SSIfile = SrcInitTypeData%SSIfile ENDIF -IF (ALLOCATED(SrcInitTypeData%M)) THEN - i1_l = LBOUND(SrcInitTypeData%M,1) - i1_u = UBOUND(SrcInitTypeData%M,1) - i2_l = LBOUND(SrcInitTypeData%M,2) - i2_u = UBOUND(SrcInitTypeData%M,2) - IF (.NOT. ALLOCATED(DstInitTypeData%M)) THEN - ALLOCATE(DstInitTypeData%M(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcInitTypeData%Soil_K)) THEN + i1_l = LBOUND(SrcInitTypeData%Soil_K,1) + i1_u = UBOUND(SrcInitTypeData%Soil_K,1) + i2_l = LBOUND(SrcInitTypeData%Soil_K,2) + i2_u = UBOUND(SrcInitTypeData%Soil_K,2) + i3_l = LBOUND(SrcInitTypeData%Soil_K,3) + i3_u = UBOUND(SrcInitTypeData%Soil_K,3) + IF (.NOT. ALLOCATED(DstInitTypeData%Soil_K)) THEN + ALLOCATE(DstInitTypeData%Soil_K(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%M.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%Soil_K.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInitTypeData%M = SrcInitTypeData%M + DstInitTypeData%Soil_K = SrcInitTypeData%Soil_K ENDIF -IF (ALLOCATED(SrcInitTypeData%F)) THEN - i1_l = LBOUND(SrcInitTypeData%F,1) - i1_u = UBOUND(SrcInitTypeData%F,1) - IF (.NOT. ALLOCATED(DstInitTypeData%F)) THEN - ALLOCATE(DstInitTypeData%F(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcInitTypeData%Soil_Points)) THEN + i1_l = LBOUND(SrcInitTypeData%Soil_Points,1) + i1_u = UBOUND(SrcInitTypeData%Soil_Points,1) + i2_l = LBOUND(SrcInitTypeData%Soil_Points,2) + i2_u = UBOUND(SrcInitTypeData%Soil_Points,2) + IF (.NOT. ALLOCATED(DstInitTypeData%Soil_Points)) THEN + ALLOCATE(DstInitTypeData%Soil_Points(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%F.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%Soil_Points.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInitTypeData%F = SrcInitTypeData%F + DstInitTypeData%Soil_Points = SrcInitTypeData%Soil_Points ENDIF -IF (ALLOCATED(SrcInitTypeData%FG)) THEN - i1_l = LBOUND(SrcInitTypeData%FG,1) - i1_u = UBOUND(SrcInitTypeData%FG,1) - IF (.NOT. ALLOCATED(DstInitTypeData%FG)) THEN - ALLOCATE(DstInitTypeData%FG(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcInitTypeData%Soil_Nodes)) THEN + i1_l = LBOUND(SrcInitTypeData%Soil_Nodes,1) + i1_u = UBOUND(SrcInitTypeData%Soil_Nodes,1) + IF (.NOT. ALLOCATED(DstInitTypeData%Soil_Nodes)) THEN + ALLOCATE(DstInitTypeData%Soil_Nodes(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%FG.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%Soil_Nodes.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInitTypeData%FG = SrcInitTypeData%FG + DstInitTypeData%Soil_Nodes = SrcInitTypeData%Soil_Nodes ENDIF -IF (ALLOCATED(SrcInitTypeData%ElemProps)) THEN - i1_l = LBOUND(SrcInitTypeData%ElemProps,1) - i1_u = UBOUND(SrcInitTypeData%ElemProps,1) - i2_l = LBOUND(SrcInitTypeData%ElemProps,2) - i2_u = UBOUND(SrcInitTypeData%ElemProps,2) - IF (.NOT. ALLOCATED(DstInitTypeData%ElemProps)) THEN - ALLOCATE(DstInitTypeData%ElemProps(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + DstInitTypeData%NElem = SrcInitTypeData%NElem + DstInitTypeData%NPropB = SrcInitTypeData%NPropB + DstInitTypeData%NPropC = SrcInitTypeData%NPropC + DstInitTypeData%NPropR = SrcInitTypeData%NPropR +IF (ALLOCATED(SrcInitTypeData%Nodes)) THEN + i1_l = LBOUND(SrcInitTypeData%Nodes,1) + i1_u = UBOUND(SrcInitTypeData%Nodes,1) + i2_l = LBOUND(SrcInitTypeData%Nodes,2) + i2_u = UBOUND(SrcInitTypeData%Nodes,2) + IF (.NOT. ALLOCATED(DstInitTypeData%Nodes)) THEN + ALLOCATE(DstInitTypeData%Nodes(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%ElemProps.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%Nodes.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInitTypeData%ElemProps = SrcInitTypeData%ElemProps + DstInitTypeData%Nodes = SrcInitTypeData%Nodes +ENDIF +IF (ALLOCATED(SrcInitTypeData%PropsB)) THEN + i1_l = LBOUND(SrcInitTypeData%PropsB,1) + i1_u = UBOUND(SrcInitTypeData%PropsB,1) + i2_l = LBOUND(SrcInitTypeData%PropsB,2) + i2_u = UBOUND(SrcInitTypeData%PropsB,2) + IF (.NOT. ALLOCATED(DstInitTypeData%PropsB)) THEN + ALLOCATE(DstInitTypeData%PropsB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%PropsB.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitTypeData%PropsB = SrcInitTypeData%PropsB +ENDIF +IF (ALLOCATED(SrcInitTypeData%PropsC)) THEN + i1_l = LBOUND(SrcInitTypeData%PropsC,1) + i1_u = UBOUND(SrcInitTypeData%PropsC,1) + i2_l = LBOUND(SrcInitTypeData%PropsC,2) + i2_u = UBOUND(SrcInitTypeData%PropsC,2) + IF (.NOT. ALLOCATED(DstInitTypeData%PropsC)) THEN + ALLOCATE(DstInitTypeData%PropsC(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%PropsC.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitTypeData%PropsC = SrcInitTypeData%PropsC +ENDIF +IF (ALLOCATED(SrcInitTypeData%PropsR)) THEN + i1_l = LBOUND(SrcInitTypeData%PropsR,1) + i1_u = UBOUND(SrcInitTypeData%PropsR,1) + i2_l = LBOUND(SrcInitTypeData%PropsR,2) + i2_u = UBOUND(SrcInitTypeData%PropsR,2) + IF (.NOT. ALLOCATED(DstInitTypeData%PropsR)) THEN + ALLOCATE(DstInitTypeData%PropsR(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%PropsR.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitTypeData%PropsR = SrcInitTypeData%PropsR ENDIF -IF (ALLOCATED(SrcInitTypeData%BCs)) THEN - i1_l = LBOUND(SrcInitTypeData%BCs,1) - i1_u = UBOUND(SrcInitTypeData%BCs,1) - i2_l = LBOUND(SrcInitTypeData%BCs,2) - i2_u = UBOUND(SrcInitTypeData%BCs,2) - IF (.NOT. ALLOCATED(DstInitTypeData%BCs)) THEN - ALLOCATE(DstInitTypeData%BCs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcInitTypeData%K)) THEN + i1_l = LBOUND(SrcInitTypeData%K,1) + i1_u = UBOUND(SrcInitTypeData%K,1) + i2_l = LBOUND(SrcInitTypeData%K,2) + i2_u = UBOUND(SrcInitTypeData%K,2) + IF (.NOT. ALLOCATED(DstInitTypeData%K)) THEN + ALLOCATE(DstInitTypeData%K(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%K.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitTypeData%K = SrcInitTypeData%K +ENDIF +IF (ALLOCATED(SrcInitTypeData%M)) THEN + i1_l = LBOUND(SrcInitTypeData%M,1) + i1_u = UBOUND(SrcInitTypeData%M,1) + i2_l = LBOUND(SrcInitTypeData%M,2) + i2_u = UBOUND(SrcInitTypeData%M,2) + IF (.NOT. ALLOCATED(DstInitTypeData%M)) THEN + ALLOCATE(DstInitTypeData%M(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%BCs.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%M.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInitTypeData%BCs = SrcInitTypeData%BCs + DstInitTypeData%M = SrcInitTypeData%M ENDIF -IF (ALLOCATED(SrcInitTypeData%IntFc)) THEN - i1_l = LBOUND(SrcInitTypeData%IntFc,1) - i1_u = UBOUND(SrcInitTypeData%IntFc,1) - i2_l = LBOUND(SrcInitTypeData%IntFc,2) - i2_u = UBOUND(SrcInitTypeData%IntFc,2) - IF (.NOT. ALLOCATED(DstInitTypeData%IntFc)) THEN - ALLOCATE(DstInitTypeData%IntFc(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcInitTypeData%ElemProps)) THEN + i1_l = LBOUND(SrcInitTypeData%ElemProps,1) + i1_u = UBOUND(SrcInitTypeData%ElemProps,1) + i2_l = LBOUND(SrcInitTypeData%ElemProps,2) + i2_u = UBOUND(SrcInitTypeData%ElemProps,2) + IF (.NOT. ALLOCATED(DstInitTypeData%ElemProps)) THEN + ALLOCATE(DstInitTypeData%ElemProps(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%IntFc.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitTypeData%ElemProps.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInitTypeData%IntFc = SrcInitTypeData%IntFc + DstInitTypeData%ElemProps = SrcInitTypeData%ElemProps ENDIF IF (ALLOCATED(SrcInitTypeData%MemberNodes)) THEN i1_l = LBOUND(SrcInitTypeData%MemberNodes,1) @@ -2851,11 +3378,17 @@ SUBROUTINE SD_DestroyInitType( InitTypeData, ErrStat, ErrMsg ) IF (ALLOCATED(InitTypeData%Joints)) THEN DEALLOCATE(InitTypeData%Joints) ENDIF -IF (ALLOCATED(InitTypeData%PropSets)) THEN - DEALLOCATE(InitTypeData%PropSets) +IF (ALLOCATED(InitTypeData%PropSetsB)) THEN + DEALLOCATE(InitTypeData%PropSetsB) ENDIF -IF (ALLOCATED(InitTypeData%XPropSets)) THEN - DEALLOCATE(InitTypeData%XPropSets) +IF (ALLOCATED(InitTypeData%PropSetsC)) THEN + DEALLOCATE(InitTypeData%PropSetsC) +ENDIF +IF (ALLOCATED(InitTypeData%PropSetsR)) THEN + DEALLOCATE(InitTypeData%PropSetsR) +ENDIF +IF (ALLOCATED(InitTypeData%PropSetsX)) THEN + DEALLOCATE(InitTypeData%PropSetsX) ENDIF IF (ALLOCATED(InitTypeData%COSMs)) THEN DEALLOCATE(InitTypeData%COSMs) @@ -2869,17 +3402,38 @@ SUBROUTINE SD_DestroyInitType( InitTypeData, ErrStat, ErrMsg ) IF (ALLOCATED(InitTypeData%Members)) THEN DEALLOCATE(InitTypeData%Members) ENDIF -IF (ALLOCATED(InitTypeData%Interf)) THEN - DEALLOCATE(InitTypeData%Interf) -ENDIF IF (ALLOCATED(InitTypeData%SSOutList)) THEN DEALLOCATE(InitTypeData%SSOutList) ENDIF +IF (ALLOCATED(InitTypeData%SSIK)) THEN + DEALLOCATE(InitTypeData%SSIK) +ENDIF +IF (ALLOCATED(InitTypeData%SSIM)) THEN + DEALLOCATE(InitTypeData%SSIM) +ENDIF +IF (ALLOCATED(InitTypeData%SSIfile)) THEN + DEALLOCATE(InitTypeData%SSIfile) +ENDIF +IF (ALLOCATED(InitTypeData%Soil_K)) THEN + DEALLOCATE(InitTypeData%Soil_K) +ENDIF +IF (ALLOCATED(InitTypeData%Soil_Points)) THEN + DEALLOCATE(InitTypeData%Soil_Points) +ENDIF +IF (ALLOCATED(InitTypeData%Soil_Nodes)) THEN + DEALLOCATE(InitTypeData%Soil_Nodes) +ENDIF IF (ALLOCATED(InitTypeData%Nodes)) THEN DEALLOCATE(InitTypeData%Nodes) ENDIF -IF (ALLOCATED(InitTypeData%Props)) THEN - DEALLOCATE(InitTypeData%Props) +IF (ALLOCATED(InitTypeData%PropsB)) THEN + DEALLOCATE(InitTypeData%PropsB) +ENDIF +IF (ALLOCATED(InitTypeData%PropsC)) THEN + DEALLOCATE(InitTypeData%PropsC) +ENDIF +IF (ALLOCATED(InitTypeData%PropsR)) THEN + DEALLOCATE(InitTypeData%PropsR) ENDIF IF (ALLOCATED(InitTypeData%K)) THEN DEALLOCATE(InitTypeData%K) @@ -2887,21 +3441,9 @@ SUBROUTINE SD_DestroyInitType( InitTypeData, ErrStat, ErrMsg ) IF (ALLOCATED(InitTypeData%M)) THEN DEALLOCATE(InitTypeData%M) ENDIF -IF (ALLOCATED(InitTypeData%F)) THEN - DEALLOCATE(InitTypeData%F) -ENDIF -IF (ALLOCATED(InitTypeData%FG)) THEN - DEALLOCATE(InitTypeData%FG) -ENDIF IF (ALLOCATED(InitTypeData%ElemProps)) THEN DEALLOCATE(InitTypeData%ElemProps) ENDIF -IF (ALLOCATED(InitTypeData%BCs)) THEN - DEALLOCATE(InitTypeData%BCs) -ENDIF -IF (ALLOCATED(InitTypeData%IntFc)) THEN - DEALLOCATE(InitTypeData%IntFc) -ENDIF IF (ALLOCATED(InitTypeData%MemberNodes)) THEN DEALLOCATE(InitTypeData%MemberNodes) ENDIF @@ -2954,9 +3496,10 @@ SUBROUTINE SD_PackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Re_BufSz = Re_BufSz + 1 ! g Db_BufSz = Db_BufSz + 1 ! DT Int_BufSz = Int_BufSz + 1 ! NJoints - Int_BufSz = Int_BufSz + 1 ! NPropSets - Int_BufSz = Int_BufSz + 1 ! NXPropSets - Int_BufSz = Int_BufSz + 1 ! NInterf + Int_BufSz = Int_BufSz + 1 ! NPropSetsX + Int_BufSz = Int_BufSz + 1 ! NPropSetsB + Int_BufSz = Int_BufSz + 1 ! NPropSetsC + Int_BufSz = Int_BufSz + 1 ! NPropSetsR Int_BufSz = Int_BufSz + 1 ! NCMass Int_BufSz = Int_BufSz + 1 ! NCOSMs Int_BufSz = Int_BufSz + 1 ! FEMMod @@ -2967,15 +3510,25 @@ SUBROUTINE SD_PackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + 2*2 ! Joints upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Joints) ! Joints END IF - Int_BufSz = Int_BufSz + 1 ! PropSets allocated yes/no - IF ( ALLOCATED(InData%PropSets) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! PropSets upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%PropSets) ! PropSets + Int_BufSz = Int_BufSz + 1 ! PropSetsB allocated yes/no + IF ( ALLOCATED(InData%PropSetsB) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! PropSetsB upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PropSetsB) ! PropSetsB + END IF + Int_BufSz = Int_BufSz + 1 ! PropSetsC allocated yes/no + IF ( ALLOCATED(InData%PropSetsC) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! PropSetsC upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PropSetsC) ! PropSetsC END IF - Int_BufSz = Int_BufSz + 1 ! XPropSets allocated yes/no - IF ( ALLOCATED(InData%XPropSets) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! XPropSets upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%XPropSets) ! XPropSets + Int_BufSz = Int_BufSz + 1 ! PropSetsR allocated yes/no + IF ( ALLOCATED(InData%PropSetsR) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! PropSetsR upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PropSetsR) ! PropSetsR + END IF + Int_BufSz = Int_BufSz + 1 ! PropSetsX allocated yes/no + IF ( ALLOCATED(InData%PropSetsX) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! PropSetsX upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PropSetsX) ! PropSetsX END IF Int_BufSz = Int_BufSz + 1 ! COSMs allocated yes/no IF ( ALLOCATED(InData%COSMs) ) THEN @@ -2992,16 +3545,14 @@ SUBROUTINE SD_PackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + 2*1 ! JDampings upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%JDampings) ! JDampings END IF + Int_BufSz = Int_BufSz + 1 ! GuyanDampMod + Re_BufSz = Re_BufSz + SIZE(InData%RayleighDamp) ! RayleighDamp + Re_BufSz = Re_BufSz + SIZE(InData%GuyanDampMat) ! GuyanDampMat Int_BufSz = Int_BufSz + 1 ! Members allocated yes/no IF ( ALLOCATED(InData%Members) ) THEN Int_BufSz = Int_BufSz + 2*2 ! Members upper/lower bounds for each dimension Int_BufSz = Int_BufSz + SIZE(InData%Members) ! Members END IF - Int_BufSz = Int_BufSz + 1 ! Interf allocated yes/no - IF ( ALLOCATED(InData%Interf) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! Interf upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%Interf) ! Interf - END IF Int_BufSz = Int_BufSz + 1 ! SSOutList allocated yes/no IF ( ALLOCATED(InData%SSOutList) ) THEN Int_BufSz = Int_BufSz + 2*1 ! SSOutList upper/lower bounds for each dimension @@ -3009,55 +3560,75 @@ SUBROUTINE SD_PackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END IF Int_BufSz = Int_BufSz + 1 ! OutCOSM Int_BufSz = Int_BufSz + 1 ! TabDelim - Int_BufSz = Int_BufSz + 1 ! NNode + Int_BufSz = Int_BufSz + 1 ! SSIK allocated yes/no + IF ( ALLOCATED(InData%SSIK) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! SSIK upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%SSIK) ! SSIK + END IF + Int_BufSz = Int_BufSz + 1 ! SSIM allocated yes/no + IF ( ALLOCATED(InData%SSIM) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! SSIM upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%SSIM) ! SSIM + END IF + Int_BufSz = Int_BufSz + 1 ! SSIfile allocated yes/no + IF ( ALLOCATED(InData%SSIfile) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! SSIfile upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%SSIfile)*LEN(InData%SSIfile) ! SSIfile + END IF + Int_BufSz = Int_BufSz + 1 ! Soil_K allocated yes/no + IF ( ALLOCATED(InData%Soil_K) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! Soil_K upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Soil_K) ! Soil_K + END IF + Int_BufSz = Int_BufSz + 1 ! Soil_Points allocated yes/no + IF ( ALLOCATED(InData%Soil_Points) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Soil_Points upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Soil_Points) ! Soil_Points + END IF + Int_BufSz = Int_BufSz + 1 ! Soil_Nodes allocated yes/no + IF ( ALLOCATED(InData%Soil_Nodes) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Soil_Nodes upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%Soil_Nodes) ! Soil_Nodes + END IF Int_BufSz = Int_BufSz + 1 ! NElem - Int_BufSz = Int_BufSz + 1 ! NProp - Int_BufSz = Int_BufSz + 1 ! TDOF + Int_BufSz = Int_BufSz + 1 ! NPropB + Int_BufSz = Int_BufSz + 1 ! NPropC + Int_BufSz = Int_BufSz + 1 ! NPropR Int_BufSz = Int_BufSz + 1 ! Nodes allocated yes/no IF ( ALLOCATED(InData%Nodes) ) THEN Int_BufSz = Int_BufSz + 2*2 ! Nodes upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Nodes) ! Nodes END IF - Int_BufSz = Int_BufSz + 1 ! Props allocated yes/no - IF ( ALLOCATED(InData%Props) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! Props upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Props) ! Props + Int_BufSz = Int_BufSz + 1 ! PropsB allocated yes/no + IF ( ALLOCATED(InData%PropsB) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! PropsB upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PropsB) ! PropsB + END IF + Int_BufSz = Int_BufSz + 1 ! PropsC allocated yes/no + IF ( ALLOCATED(InData%PropsC) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! PropsC upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PropsC) ! PropsC + END IF + Int_BufSz = Int_BufSz + 1 ! PropsR allocated yes/no + IF ( ALLOCATED(InData%PropsR) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! PropsR upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PropsR) ! PropsR END IF Int_BufSz = Int_BufSz + 1 ! K allocated yes/no IF ( ALLOCATED(InData%K) ) THEN Int_BufSz = Int_BufSz + 2*2 ! K upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%K) ! K + Db_BufSz = Db_BufSz + SIZE(InData%K) ! K END IF Int_BufSz = Int_BufSz + 1 ! M allocated yes/no IF ( ALLOCATED(InData%M) ) THEN Int_BufSz = Int_BufSz + 2*2 ! M upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%M) ! M - END IF - Int_BufSz = Int_BufSz + 1 ! F allocated yes/no - IF ( ALLOCATED(InData%F) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! F upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%F) ! F - END IF - Int_BufSz = Int_BufSz + 1 ! FG allocated yes/no - IF ( ALLOCATED(InData%FG) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! FG upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%FG) ! FG + Db_BufSz = Db_BufSz + SIZE(InData%M) ! M END IF Int_BufSz = Int_BufSz + 1 ! ElemProps allocated yes/no IF ( ALLOCATED(InData%ElemProps) ) THEN Int_BufSz = Int_BufSz + 2*2 ! ElemProps upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%ElemProps) ! ElemProps END IF - Int_BufSz = Int_BufSz + 1 ! BCs allocated yes/no - IF ( ALLOCATED(InData%BCs) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! BCs upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%BCs) ! BCs - END IF - Int_BufSz = Int_BufSz + 1 ! IntFc allocated yes/no - IF ( ALLOCATED(InData%IntFc) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! IntFc upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%IntFc) ! IntFc - END IF Int_BufSz = Int_BufSz + 1 ! MemberNodes allocated yes/no IF ( ALLOCATED(InData%MemberNodes) ) THEN Int_BufSz = Int_BufSz + 2*2 ! MemberNodes upper/lower bounds for each dimension @@ -3117,11 +3688,13 @@ SUBROUTINE SD_PackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Db_Xferred = Db_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NJoints Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NPropSets + IntKiBuf(Int_Xferred) = InData%NPropSetsX Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NXPropSets + IntKiBuf(Int_Xferred) = InData%NPropSetsB Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NInterf + IntKiBuf(Int_Xferred) = InData%NPropSetsC + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NPropSetsR Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NCMass Int_Xferred = Int_Xferred + 1 @@ -3153,42 +3726,82 @@ SUBROUTINE SD_PackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%PropSets) ) THEN + IF ( .NOT. ALLOCATED(InData%PropSetsB) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PropSetsB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropSetsB,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PropSetsB,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropSetsB,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%PropSetsB,2), UBOUND(InData%PropSetsB,2) + DO i1 = LBOUND(InData%PropSetsB,1), UBOUND(InData%PropSetsB,1) + ReKiBuf(Re_Xferred) = InData%PropSetsB(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PropSetsC) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PropSetsC,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropSetsC,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PropSetsC,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropSetsC,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%PropSetsC,2), UBOUND(InData%PropSetsC,2) + DO i1 = LBOUND(InData%PropSetsC,1), UBOUND(InData%PropSetsC,1) + ReKiBuf(Re_Xferred) = InData%PropSetsC(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PropSetsR) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PropSets,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropSets,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PropSetsR,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropSetsR,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PropSets,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropSets,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PropSetsR,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropSetsR,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%PropSets,2), UBOUND(InData%PropSets,2) - DO i1 = LBOUND(InData%PropSets,1), UBOUND(InData%PropSets,1) - ReKiBuf(Re_Xferred) = InData%PropSets(i1,i2) + DO i2 = LBOUND(InData%PropSetsR,2), UBOUND(InData%PropSetsR,2) + DO i1 = LBOUND(InData%PropSetsR,1), UBOUND(InData%PropSetsR,1) + ReKiBuf(Re_Xferred) = InData%PropSetsR(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%XPropSets) ) THEN + IF ( .NOT. ALLOCATED(InData%PropSetsX) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%XPropSets,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%XPropSets,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PropSetsX,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropSetsX,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%XPropSets,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%XPropSets,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PropSetsX,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropSetsX,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%XPropSets,2), UBOUND(InData%XPropSets,2) - DO i1 = LBOUND(InData%XPropSets,1), UBOUND(InData%XPropSets,1) - ReKiBuf(Re_Xferred) = InData%XPropSets(i1,i2) + DO i2 = LBOUND(InData%PropSetsX,2), UBOUND(InData%PropSetsX,2) + DO i1 = LBOUND(InData%PropSetsX,1), UBOUND(InData%PropSetsX,1) + ReKiBuf(Re_Xferred) = InData%PropSetsX(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO @@ -3248,6 +3861,18 @@ SUBROUTINE SD_PackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Re_Xferred = Re_Xferred + 1 END DO END IF + IntKiBuf(Int_Xferred) = InData%GuyanDampMod + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%RayleighDamp,1), UBOUND(InData%RayleighDamp,1) + ReKiBuf(Re_Xferred) = InData%RayleighDamp(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i2 = LBOUND(InData%GuyanDampMat,2), UBOUND(InData%GuyanDampMat,2) + DO i1 = LBOUND(InData%GuyanDampMat,1), UBOUND(InData%GuyanDampMat,1) + ReKiBuf(Re_Xferred) = InData%GuyanDampMat(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO IF ( .NOT. ALLOCATED(InData%Members) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -3268,54 +3893,151 @@ SUBROUTINE SD_PackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%Interf) ) THEN + IF ( .NOT. ALLOCATED(InData%SSOutList) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Interf,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Interf,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Interf,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Interf,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%SSOutList,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SSOutList,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%Interf,2), UBOUND(InData%Interf,2) - DO i1 = LBOUND(InData%Interf,1), UBOUND(InData%Interf,1) - IntKiBuf(Int_Xferred) = InData%Interf(i1,i2) + DO i1 = LBOUND(InData%SSOutList,1), UBOUND(InData%SSOutList,1) + DO I = 1, LEN(InData%SSOutList) + IntKiBuf(Int_Xferred) = ICHAR(InData%SSOutList(i1)(I:I), IntKi) Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IntKiBuf(Int_Xferred) = TRANSFER(InData%OutCOSM, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%TabDelim, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%SSIK) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%SSIK,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SSIK,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%SSIK,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SSIK,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%SSIK,2), UBOUND(InData%SSIK,2) + DO i1 = LBOUND(InData%SSIK,1), UBOUND(InData%SSIK,1) + DbKiBuf(Db_Xferred) = InData%SSIK(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%SSOutList) ) THEN + IF ( .NOT. ALLOCATED(InData%SSIM) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%SSOutList,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SSOutList,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%SSIM,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SSIM,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%SSIM,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SSIM,2) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%SSOutList,1), UBOUND(InData%SSOutList,1) - DO I = 1, LEN(InData%SSOutList) - IntKiBuf(Int_Xferred) = ICHAR(InData%SSOutList(i1)(I:I), IntKi) + DO i2 = LBOUND(InData%SSIM,2), UBOUND(InData%SSIM,2) + DO i1 = LBOUND(InData%SSIM,1), UBOUND(InData%SSIM,1) + DbKiBuf(Db_Xferred) = InData%SSIM(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%SSIfile) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%SSIfile,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SSIfile,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%SSIfile,1), UBOUND(InData%SSIfile,1) + DO I = 1, LEN(InData%SSIfile) + IntKiBuf(Int_Xferred) = ICHAR(InData%SSIfile(i1)(I:I), IntKi) Int_Xferred = Int_Xferred + 1 END DO ! I END DO END IF - IntKiBuf(Int_Xferred) = TRANSFER(InData%OutCOSM, IntKiBuf(1)) + IF ( .NOT. ALLOCATED(InData%Soil_K) ) THEN + IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%TabDelim, IntKiBuf(1)) + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Soil_K,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Soil_K,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Soil_K,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Soil_K,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Soil_K,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Soil_K,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%Soil_K,3), UBOUND(InData%Soil_K,3) + DO i2 = LBOUND(InData%Soil_K,2), UBOUND(InData%Soil_K,2) + DO i1 = LBOUND(InData%Soil_K,1), UBOUND(InData%Soil_K,1) + ReKiBuf(Re_Xferred) = InData%Soil_K(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Soil_Points) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Soil_Points,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Soil_Points,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Soil_Points,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Soil_Points,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Soil_Points,2), UBOUND(InData%Soil_Points,2) + DO i1 = LBOUND(InData%Soil_Points,1), UBOUND(InData%Soil_Points,1) + ReKiBuf(Re_Xferred) = InData%Soil_Points(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Soil_Nodes) ) THEN + IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NNode + ELSE + IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Soil_Nodes,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Soil_Nodes,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Soil_Nodes,1), UBOUND(InData%Soil_Nodes,1) + IntKiBuf(Int_Xferred) = InData%Soil_Nodes(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF IntKiBuf(Int_Xferred) = InData%NElem Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NProp + IntKiBuf(Int_Xferred) = InData%NPropB + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NPropC Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%TDOF + IntKiBuf(Int_Xferred) = InData%NPropR Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%Nodes) ) THEN IntKiBuf( Int_Xferred ) = 0 @@ -3337,94 +4059,104 @@ SUBROUTINE SD_PackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%Props) ) THEN + IF ( .NOT. ALLOCATED(InData%PropsB) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Props,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Props,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PropsB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropsB,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Props,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Props,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PropsB,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropsB,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%Props,2), UBOUND(InData%Props,2) - DO i1 = LBOUND(InData%Props,1), UBOUND(InData%Props,1) - ReKiBuf(Re_Xferred) = InData%Props(i1,i2) + DO i2 = LBOUND(InData%PropsB,2), UBOUND(InData%PropsB,2) + DO i1 = LBOUND(InData%PropsB,1), UBOUND(InData%PropsB,1) + ReKiBuf(Re_Xferred) = InData%PropsB(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%K) ) THEN + IF ( .NOT. ALLOCATED(InData%PropsC) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%K,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%K,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PropsC,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropsC,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%K,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%K,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PropsC,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropsC,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%K,2), UBOUND(InData%K,2) - DO i1 = LBOUND(InData%K,1), UBOUND(InData%K,1) - ReKiBuf(Re_Xferred) = InData%K(i1,i2) + DO i2 = LBOUND(InData%PropsC,2), UBOUND(InData%PropsC,2) + DO i1 = LBOUND(InData%PropsC,1), UBOUND(InData%PropsC,1) + ReKiBuf(Re_Xferred) = InData%PropsC(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%M) ) THEN + IF ( .NOT. ALLOCATED(InData%PropsR) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%M,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%M,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PropsR,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropsR,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%M,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%M,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PropsR,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PropsR,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%M,2), UBOUND(InData%M,2) - DO i1 = LBOUND(InData%M,1), UBOUND(InData%M,1) - ReKiBuf(Re_Xferred) = InData%M(i1,i2) + DO i2 = LBOUND(InData%PropsR,2), UBOUND(InData%PropsR,2) + DO i1 = LBOUND(InData%PropsR,1), UBOUND(InData%PropsR,1) + ReKiBuf(Re_Xferred) = InData%PropsR(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%F) ) THEN + IF ( .NOT. ALLOCATED(InData%K) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%F,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%K,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%K,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%K,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%K,2) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%F,1), UBOUND(InData%F,1) - ReKiBuf(Re_Xferred) = InData%F(i1) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(InData%K,2), UBOUND(InData%K,2) + DO i1 = LBOUND(InData%K,1), UBOUND(InData%K,1) + DbKiBuf(Db_Xferred) = InData%K(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%FG) ) THEN + IF ( .NOT. ALLOCATED(InData%M) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FG,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FG,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%M,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%M,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%M,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%M,2) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%FG,1), UBOUND(InData%FG,1) - ReKiBuf(Re_Xferred) = InData%FG(i1) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(InData%M,2), UBOUND(InData%M,2) + DO i1 = LBOUND(InData%M,1), UBOUND(InData%M,1) + DbKiBuf(Db_Xferred) = InData%M(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO END DO END IF IF ( .NOT. ALLOCATED(InData%ElemProps) ) THEN @@ -3447,87 +4179,47 @@ SUBROUTINE SD_PackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%BCs) ) THEN + IF ( .NOT. ALLOCATED(InData%MemberNodes) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BCs,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BCs,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%MemberNodes,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MemberNodes,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BCs,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BCs,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%MemberNodes,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MemberNodes,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%BCs,2), UBOUND(InData%BCs,2) - DO i1 = LBOUND(InData%BCs,1), UBOUND(InData%BCs,1) - IntKiBuf(Int_Xferred) = InData%BCs(i1,i2) + DO i2 = LBOUND(InData%MemberNodes,2), UBOUND(InData%MemberNodes,2) + DO i1 = LBOUND(InData%MemberNodes,1), UBOUND(InData%MemberNodes,1) + IntKiBuf(Int_Xferred) = InData%MemberNodes(i1,i2) Int_Xferred = Int_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%IntFc) ) THEN + IF ( .NOT. ALLOCATED(InData%NodesConnN) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%IntFc,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IntFc,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%NodesConnN,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NodesConnN,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%IntFc,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IntFc,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%NodesConnN,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NodesConnN,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%IntFc,2), UBOUND(InData%IntFc,2) - DO i1 = LBOUND(InData%IntFc,1), UBOUND(InData%IntFc,1) - IntKiBuf(Int_Xferred) = InData%IntFc(i1,i2) + DO i2 = LBOUND(InData%NodesConnN,2), UBOUND(InData%NodesConnN,2) + DO i1 = LBOUND(InData%NodesConnN,1), UBOUND(InData%NodesConnN,1) + IntKiBuf(Int_Xferred) = InData%NodesConnN(i1,i2) Int_Xferred = Int_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%MemberNodes) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MemberNodes,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MemberNodes,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MemberNodes,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MemberNodes,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%MemberNodes,2), UBOUND(InData%MemberNodes,2) - DO i1 = LBOUND(InData%MemberNodes,1), UBOUND(InData%MemberNodes,1) - IntKiBuf(Int_Xferred) = InData%MemberNodes(i1,i2) - Int_Xferred = Int_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%NodesConnN) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%NodesConnN,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NodesConnN,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%NodesConnN,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NodesConnN,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%NodesConnN,2), UBOUND(InData%NodesConnN,2) - DO i1 = LBOUND(InData%NodesConnN,1), UBOUND(InData%NodesConnN,1) - IntKiBuf(Int_Xferred) = InData%NodesConnN(i1,i2) - Int_Xferred = Int_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%NodesConnE) ) THEN + IF ( .NOT. ALLOCATED(InData%NodesConnE) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE @@ -3566,6 +4258,7 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackInitType' @@ -3597,11 +4290,13 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM Db_Xferred = Db_Xferred + 1 OutData%NJoints = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%NPropSets = IntKiBuf(Int_Xferred) + OutData%NPropSetsX = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NPropSetsB = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%NXPropSets = IntKiBuf(Int_Xferred) + OutData%NPropSetsC = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%NInterf = IntKiBuf(Int_Xferred) + OutData%NPropSetsR = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%NCMass = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 @@ -3636,7 +4331,53 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PropSets not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PropSetsB not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PropSetsB)) DEALLOCATE(OutData%PropSetsB) + ALLOCATE(OutData%PropSetsB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PropSetsB.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%PropSetsB,2), UBOUND(OutData%PropSetsB,2) + DO i1 = LBOUND(OutData%PropSetsB,1), UBOUND(OutData%PropSetsB,1) + OutData%PropSetsB(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PropSetsC not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PropSetsC)) DEALLOCATE(OutData%PropSetsC) + ALLOCATE(OutData%PropSetsC(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PropSetsC.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%PropSetsC,2), UBOUND(OutData%PropSetsC,2) + DO i1 = LBOUND(OutData%PropSetsC,1), UBOUND(OutData%PropSetsC,1) + OutData%PropSetsC(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PropSetsR not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -3646,20 +4387,20 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%PropSets)) DEALLOCATE(OutData%PropSets) - ALLOCATE(OutData%PropSets(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%PropSetsR)) DEALLOCATE(OutData%PropSetsR) + ALLOCATE(OutData%PropSetsR(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PropSets.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PropSetsR.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%PropSets,2), UBOUND(OutData%PropSets,2) - DO i1 = LBOUND(OutData%PropSets,1), UBOUND(OutData%PropSets,1) - OutData%PropSets(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%PropSetsR,2), UBOUND(OutData%PropSetsR,2) + DO i1 = LBOUND(OutData%PropSetsR,1), UBOUND(OutData%PropSetsR,1) + OutData%PropSetsR(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! XPropSets not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PropSetsX not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -3669,15 +4410,15 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%XPropSets)) DEALLOCATE(OutData%XPropSets) - ALLOCATE(OutData%XPropSets(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%PropSetsX)) DEALLOCATE(OutData%PropSetsX) + ALLOCATE(OutData%PropSetsX(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%XPropSets.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PropSetsX.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%XPropSets,2), UBOUND(OutData%XPropSets,2) - DO i1 = LBOUND(OutData%XPropSets,1), UBOUND(OutData%XPropSets,1) - OutData%XPropSets(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%PropSetsX,2), UBOUND(OutData%PropSetsX,2) + DO i1 = LBOUND(OutData%PropSetsX,1), UBOUND(OutData%PropSetsX,1) + OutData%PropSetsX(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO @@ -3746,6 +4487,24 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM Re_Xferred = Re_Xferred + 1 END DO END IF + OutData%GuyanDampMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%RayleighDamp,1) + i1_u = UBOUND(OutData%RayleighDamp,1) + DO i1 = LBOUND(OutData%RayleighDamp,1), UBOUND(OutData%RayleighDamp,1) + OutData%RayleighDamp(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%GuyanDampMat,1) + i1_u = UBOUND(OutData%GuyanDampMat,1) + i2_l = LBOUND(OutData%GuyanDampMat,2) + i2_u = UBOUND(OutData%GuyanDampMat,2) + DO i2 = LBOUND(OutData%GuyanDampMat,2), UBOUND(OutData%GuyanDampMat,2) + DO i1 = LBOUND(OutData%GuyanDampMat,1), UBOUND(OutData%GuyanDampMat,1) + OutData%GuyanDampMat(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Members not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -3769,29 +4528,6 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Interf not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Interf)) DEALLOCATE(OutData%Interf) - ALLOCATE(OutData%Interf(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Interf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%Interf,2), UBOUND(OutData%Interf,2) - DO i1 = LBOUND(OutData%Interf,1), UBOUND(OutData%Interf,1) - OutData%Interf(i1,i2) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! SSOutList not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -3816,15 +4552,73 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM Int_Xferred = Int_Xferred + 1 OutData%TabDelim = TRANSFER(IntKiBuf(Int_Xferred), OutData%TabDelim) Int_Xferred = Int_Xferred + 1 - OutData%NNode = IntKiBuf(Int_Xferred) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! SSIK not allocated Int_Xferred = Int_Xferred + 1 - OutData%NElem = IntKiBuf(Int_Xferred) + ELSE Int_Xferred = Int_Xferred + 1 - OutData%NProp = IntKiBuf(Int_Xferred) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%SSIK)) DEALLOCATE(OutData%SSIK) + ALLOCATE(OutData%SSIK(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%SSIK.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%SSIK,2), UBOUND(OutData%SSIK,2) + DO i1 = LBOUND(OutData%SSIK,1), UBOUND(OutData%SSIK,1) + OutData%SSIK(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! SSIM not allocated Int_Xferred = Int_Xferred + 1 - OutData%TDOF = IntKiBuf(Int_Xferred) + ELSE Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Nodes not allocated + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%SSIM)) DEALLOCATE(OutData%SSIM) + ALLOCATE(OutData%SSIM(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%SSIM.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%SSIM,2), UBOUND(OutData%SSIM,2) + DO i1 = LBOUND(OutData%SSIM,1), UBOUND(OutData%SSIM,1) + OutData%SSIM(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! SSIfile not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%SSIfile)) DEALLOCATE(OutData%SSIfile) + ALLOCATE(OutData%SSIfile(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%SSIfile.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%SSIfile,1), UBOUND(OutData%SSIfile,1) + DO I = 1, LEN(OutData%SSIfile) + OutData%SSIfile(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Soil_K not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -3834,20 +4628,25 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Nodes)) DEALLOCATE(OutData%Nodes) - ALLOCATE(OutData%Nodes(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Soil_K)) DEALLOCATE(OutData%Soil_K) + ALLOCATE(OutData%Soil_K(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Nodes.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Soil_K.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%Nodes,2), UBOUND(OutData%Nodes,2) - DO i1 = LBOUND(OutData%Nodes,1), UBOUND(OutData%Nodes,1) - OutData%Nodes(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(OutData%Soil_K,3), UBOUND(OutData%Soil_K,3) + DO i2 = LBOUND(OutData%Soil_K,2), UBOUND(OutData%Soil_K,2) + DO i1 = LBOUND(OutData%Soil_K,1), UBOUND(OutData%Soil_K,1) + OutData%Soil_K(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Props not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Soil_Points not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -3857,20 +4656,46 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Props)) DEALLOCATE(OutData%Props) - ALLOCATE(OutData%Props(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Soil_Points)) DEALLOCATE(OutData%Soil_Points) + ALLOCATE(OutData%Soil_Points(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Props.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Soil_Points.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%Props,2), UBOUND(OutData%Props,2) - DO i1 = LBOUND(OutData%Props,1), UBOUND(OutData%Props,1) - OutData%Props(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%Soil_Points,2), UBOUND(OutData%Soil_Points,2) + DO i1 = LBOUND(OutData%Soil_Points,1), UBOUND(OutData%Soil_Points,1) + OutData%Soil_Points(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! K not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Soil_Nodes not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Soil_Nodes)) DEALLOCATE(OutData%Soil_Nodes) + ALLOCATE(OutData%Soil_Nodes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Soil_Nodes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Soil_Nodes,1), UBOUND(OutData%Soil_Nodes,1) + OutData%Soil_Nodes(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + OutData%NElem = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NPropB = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NPropC = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NPropR = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Nodes not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -3880,20 +4705,20 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%K)) DEALLOCATE(OutData%K) - ALLOCATE(OutData%K(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Nodes)) DEALLOCATE(OutData%Nodes) + ALLOCATE(OutData%Nodes(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%K.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Nodes.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%K,2), UBOUND(OutData%K,2) - DO i1 = LBOUND(OutData%K,1), UBOUND(OutData%K,1) - OutData%K(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%Nodes,2), UBOUND(OutData%Nodes,2) + DO i1 = LBOUND(OutData%Nodes,1), UBOUND(OutData%Nodes,1) + OutData%Nodes(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! M not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PropsB not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -3903,56 +4728,66 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%M)) DEALLOCATE(OutData%M) - ALLOCATE(OutData%M(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%PropsB)) DEALLOCATE(OutData%PropsB) + ALLOCATE(OutData%PropsB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%M.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PropsB.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%M,2), UBOUND(OutData%M,2) - DO i1 = LBOUND(OutData%M,1), UBOUND(OutData%M,1) - OutData%M(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%PropsB,2), UBOUND(OutData%PropsB,2) + DO i1 = LBOUND(OutData%PropsB,1), UBOUND(OutData%PropsB,1) + OutData%PropsB(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PropsC not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%F)) DEALLOCATE(OutData%F) - ALLOCATE(OutData%F(i1_l:i1_u),STAT=ErrStat2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PropsC)) DEALLOCATE(OutData%PropsC) + ALLOCATE(OutData%PropsC(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PropsC.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%F,1), UBOUND(OutData%F,1) - OutData%F(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(OutData%PropsC,2), UBOUND(OutData%PropsC,2) + DO i1 = LBOUND(OutData%PropsC,1), UBOUND(OutData%PropsC,1) + OutData%PropsC(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FG not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PropsR not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%FG)) DEALLOCATE(OutData%FG) - ALLOCATE(OutData%FG(i1_l:i1_u),STAT=ErrStat2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PropsR)) DEALLOCATE(OutData%PropsR) + ALLOCATE(OutData%PropsR(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FG.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PropsR.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%FG,1), UBOUND(OutData%FG,1) - OutData%FG(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(OutData%PropsR,2), UBOUND(OutData%PropsR,2) + DO i1 = LBOUND(OutData%PropsR,1), UBOUND(OutData%PropsR,1) + OutData%PropsR(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ElemProps not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! K not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -3962,20 +4797,20 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%ElemProps)) DEALLOCATE(OutData%ElemProps) - ALLOCATE(OutData%ElemProps(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%K)) DEALLOCATE(OutData%K) + ALLOCATE(OutData%K(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ElemProps.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%K.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%ElemProps,2), UBOUND(OutData%ElemProps,2) - DO i1 = LBOUND(OutData%ElemProps,1), UBOUND(OutData%ElemProps,1) - OutData%ElemProps(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(OutData%K,2), UBOUND(OutData%K,2) + DO i1 = LBOUND(OutData%K,1), UBOUND(OutData%K,1) + OutData%K(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BCs not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! M not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -3985,20 +4820,20 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BCs)) DEALLOCATE(OutData%BCs) - ALLOCATE(OutData%BCs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%M)) DEALLOCATE(OutData%M) + ALLOCATE(OutData%M(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BCs.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%M.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%BCs,2), UBOUND(OutData%BCs,2) - DO i1 = LBOUND(OutData%BCs,1), UBOUND(OutData%BCs,1) - OutData%BCs(i1,i2) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + DO i2 = LBOUND(OutData%M,2), UBOUND(OutData%M,2) + DO i1 = LBOUND(OutData%M,1), UBOUND(OutData%M,1) + OutData%M(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IntFc not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ElemProps not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -4008,16 +4843,16 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%IntFc)) DEALLOCATE(OutData%IntFc) - ALLOCATE(OutData%IntFc(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%ElemProps)) DEALLOCATE(OutData%ElemProps) + ALLOCATE(OutData%ElemProps(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IntFc.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ElemProps.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%IntFc,2), UBOUND(OutData%IntFc,2) - DO i1 = LBOUND(OutData%IntFc,1), UBOUND(OutData%IntFc,1) - OutData%IntFc(i1,i2) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + DO i2 = LBOUND(OutData%ElemProps,2), UBOUND(OutData%ElemProps,2) + DO i1 = LBOUND(OutData%ElemProps,1), UBOUND(OutData%ElemProps,1) + OutData%ElemProps(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END DO END DO END IF @@ -4190,12 +5025,12 @@ SUBROUTINE SD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 1 ! qm allocated yes/no IF ( ALLOCATED(InData%qm) ) THEN Int_BufSz = Int_BufSz + 2*1 ! qm upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%qm) ! qm + Db_BufSz = Db_BufSz + SIZE(InData%qm) ! qm END IF Int_BufSz = Int_BufSz + 1 ! qmdot allocated yes/no IF ( ALLOCATED(InData%qmdot) ) THEN Int_BufSz = Int_BufSz + 2*1 ! qmdot upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%qmdot) ! qmdot + Db_BufSz = Db_BufSz + SIZE(InData%qmdot) ! qmdot END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -4235,8 +5070,8 @@ SUBROUTINE SD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_Xferred = Int_Xferred + 2 DO i1 = LBOUND(InData%qm,1), UBOUND(InData%qm,1) - ReKiBuf(Re_Xferred) = InData%qm(i1) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%qm(i1) + Db_Xferred = Db_Xferred + 1 END DO END IF IF ( .NOT. ALLOCATED(InData%qmdot) ) THEN @@ -4250,8 +5085,8 @@ SUBROUTINE SD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_Xferred = Int_Xferred + 2 DO i1 = LBOUND(InData%qmdot,1), UBOUND(InData%qmdot,1) - ReKiBuf(Re_Xferred) = InData%qmdot(i1) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%qmdot(i1) + Db_Xferred = Db_Xferred + 1 END DO END IF END SUBROUTINE SD_PackContState @@ -4297,8 +5132,8 @@ SUBROUTINE SD_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err RETURN END IF DO i1 = LBOUND(OutData%qm,1), UBOUND(OutData%qm,1) - OutData%qm(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%qm(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 END DO END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! qmdot not allocated @@ -4315,8 +5150,8 @@ SUBROUTINE SD_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err RETURN END IF DO i1 = LBOUND(OutData%qmdot,1), UBOUND(OutData%qmdot,1) - OutData%qmdot(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%qmdot(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 END DO END IF END SUBROUTINE SD_UnPackContState @@ -4871,17 +5706,17 @@ SUBROUTINE SD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) DstMiscData%u_TP = SrcMiscData%u_TP DstMiscData%udot_TP = SrcMiscData%udot_TP DstMiscData%udotdot_TP = SrcMiscData%udotdot_TP -IF (ALLOCATED(SrcMiscData%UFL)) THEN - i1_l = LBOUND(SrcMiscData%UFL,1) - i1_u = UBOUND(SrcMiscData%UFL,1) - IF (.NOT. ALLOCATED(DstMiscData%UFL)) THEN - ALLOCATE(DstMiscData%UFL(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMiscData%F_L)) THEN + i1_l = LBOUND(SrcMiscData%F_L,1) + i1_u = UBOUND(SrcMiscData%F_L,1) + IF (.NOT. ALLOCATED(DstMiscData%F_L)) THEN + ALLOCATE(DstMiscData%F_L(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%UFL.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%F_L.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%UFL = SrcMiscData%UFL + DstMiscData%F_L = SrcMiscData%F_L ENDIF IF (ALLOCATED(SrcMiscData%UR_bar)) THEN i1_l = LBOUND(SrcMiscData%UR_bar,1) @@ -4955,36 +5790,168 @@ SUBROUTINE SD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) END IF DstMiscData%UL_dotdot = SrcMiscData%UL_dotdot ENDIF -IF (ALLOCATED(SrcMiscData%SDWrOutput)) THEN - i1_l = LBOUND(SrcMiscData%SDWrOutput,1) - i1_u = UBOUND(SrcMiscData%SDWrOutput,1) - IF (.NOT. ALLOCATED(DstMiscData%SDWrOutput)) THEN - ALLOCATE(DstMiscData%SDWrOutput(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMiscData%DU_full)) THEN + i1_l = LBOUND(SrcMiscData%DU_full,1) + i1_u = UBOUND(SrcMiscData%DU_full,1) + IF (.NOT. ALLOCATED(DstMiscData%DU_full)) THEN + ALLOCATE(DstMiscData%DU_full(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%SDWrOutput.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%DU_full.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%SDWrOutput = SrcMiscData%SDWrOutput + DstMiscData%DU_full = SrcMiscData%DU_full ENDIF - DstMiscData%LastOutTime = SrcMiscData%LastOutTime - DstMiscData%Decimat = SrcMiscData%Decimat - END SUBROUTINE SD_CopyMisc - - SUBROUTINE SD_DestroyMisc( MiscData, ErrStat, ErrMsg ) - TYPE(SD_MiscVarType), INTENT(INOUT) :: MiscData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyMisc' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(MiscData%qmdotdot)) THEN - DEALLOCATE(MiscData%qmdotdot) +IF (ALLOCATED(SrcMiscData%U_full)) THEN + i1_l = LBOUND(SrcMiscData%U_full,1) + i1_u = UBOUND(SrcMiscData%U_full,1) + IF (.NOT. ALLOCATED(DstMiscData%U_full)) THEN + ALLOCATE(DstMiscData%U_full(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%U_full.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%U_full = SrcMiscData%U_full +ENDIF +IF (ALLOCATED(SrcMiscData%U_full_dot)) THEN + i1_l = LBOUND(SrcMiscData%U_full_dot,1) + i1_u = UBOUND(SrcMiscData%U_full_dot,1) + IF (.NOT. ALLOCATED(DstMiscData%U_full_dot)) THEN + ALLOCATE(DstMiscData%U_full_dot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%U_full_dot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%U_full_dot = SrcMiscData%U_full_dot +ENDIF +IF (ALLOCATED(SrcMiscData%U_full_dotdot)) THEN + i1_l = LBOUND(SrcMiscData%U_full_dotdot,1) + i1_u = UBOUND(SrcMiscData%U_full_dotdot,1) + IF (.NOT. ALLOCATED(DstMiscData%U_full_dotdot)) THEN + ALLOCATE(DstMiscData%U_full_dotdot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%U_full_dotdot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%U_full_dotdot = SrcMiscData%U_full_dotdot +ENDIF +IF (ALLOCATED(SrcMiscData%U_full_elast)) THEN + i1_l = LBOUND(SrcMiscData%U_full_elast,1) + i1_u = UBOUND(SrcMiscData%U_full_elast,1) + IF (.NOT. ALLOCATED(DstMiscData%U_full_elast)) THEN + ALLOCATE(DstMiscData%U_full_elast(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%U_full_elast.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%U_full_elast = SrcMiscData%U_full_elast +ENDIF +IF (ALLOCATED(SrcMiscData%U_red)) THEN + i1_l = LBOUND(SrcMiscData%U_red,1) + i1_u = UBOUND(SrcMiscData%U_red,1) + IF (.NOT. ALLOCATED(DstMiscData%U_red)) THEN + ALLOCATE(DstMiscData%U_red(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%U_red.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%U_red = SrcMiscData%U_red +ENDIF +IF (ALLOCATED(SrcMiscData%U_red_dot)) THEN + i1_l = LBOUND(SrcMiscData%U_red_dot,1) + i1_u = UBOUND(SrcMiscData%U_red_dot,1) + IF (.NOT. ALLOCATED(DstMiscData%U_red_dot)) THEN + ALLOCATE(DstMiscData%U_red_dot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%U_red_dot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%U_red_dot = SrcMiscData%U_red_dot +ENDIF +IF (ALLOCATED(SrcMiscData%U_red_dotdot)) THEN + i1_l = LBOUND(SrcMiscData%U_red_dotdot,1) + i1_u = UBOUND(SrcMiscData%U_red_dotdot,1) + IF (.NOT. ALLOCATED(DstMiscData%U_red_dotdot)) THEN + ALLOCATE(DstMiscData%U_red_dotdot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%U_red_dotdot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%U_red_dotdot = SrcMiscData%U_red_dotdot +ENDIF +IF (ALLOCATED(SrcMiscData%FC_unit)) THEN + i1_l = LBOUND(SrcMiscData%FC_unit,1) + i1_u = UBOUND(SrcMiscData%FC_unit,1) + IF (.NOT. ALLOCATED(DstMiscData%FC_unit)) THEN + ALLOCATE(DstMiscData%FC_unit(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%FC_unit.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%FC_unit = SrcMiscData%FC_unit +ENDIF +IF (ALLOCATED(SrcMiscData%SDWrOutput)) THEN + i1_l = LBOUND(SrcMiscData%SDWrOutput,1) + i1_u = UBOUND(SrcMiscData%SDWrOutput,1) + IF (.NOT. ALLOCATED(DstMiscData%SDWrOutput)) THEN + ALLOCATE(DstMiscData%SDWrOutput(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%SDWrOutput.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%SDWrOutput = SrcMiscData%SDWrOutput +ENDIF + DstMiscData%LastOutTime = SrcMiscData%LastOutTime + DstMiscData%Decimat = SrcMiscData%Decimat +IF (ALLOCATED(SrcMiscData%Fext)) THEN + i1_l = LBOUND(SrcMiscData%Fext,1) + i1_u = UBOUND(SrcMiscData%Fext,1) + IF (.NOT. ALLOCATED(DstMiscData%Fext)) THEN + ALLOCATE(DstMiscData%Fext(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%Fext.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%Fext = SrcMiscData%Fext +ENDIF +IF (ALLOCATED(SrcMiscData%Fext_red)) THEN + i1_l = LBOUND(SrcMiscData%Fext_red,1) + i1_u = UBOUND(SrcMiscData%Fext_red,1) + IF (.NOT. ALLOCATED(DstMiscData%Fext_red)) THEN + ALLOCATE(DstMiscData%Fext_red(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%Fext_red.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%Fext_red = SrcMiscData%Fext_red +ENDIF + END SUBROUTINE SD_CopyMisc + + SUBROUTINE SD_DestroyMisc( MiscData, ErrStat, ErrMsg ) + TYPE(SD_MiscVarType), INTENT(INOUT) :: MiscData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyMisc' + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(MiscData%qmdotdot)) THEN + DEALLOCATE(MiscData%qmdotdot) ENDIF -IF (ALLOCATED(MiscData%UFL)) THEN - DEALLOCATE(MiscData%UFL) +IF (ALLOCATED(MiscData%F_L)) THEN + DEALLOCATE(MiscData%F_L) ENDIF IF (ALLOCATED(MiscData%UR_bar)) THEN DEALLOCATE(MiscData%UR_bar) @@ -5004,8 +5971,41 @@ SUBROUTINE SD_DestroyMisc( MiscData, ErrStat, ErrMsg ) IF (ALLOCATED(MiscData%UL_dotdot)) THEN DEALLOCATE(MiscData%UL_dotdot) ENDIF +IF (ALLOCATED(MiscData%DU_full)) THEN + DEALLOCATE(MiscData%DU_full) +ENDIF +IF (ALLOCATED(MiscData%U_full)) THEN + DEALLOCATE(MiscData%U_full) +ENDIF +IF (ALLOCATED(MiscData%U_full_dot)) THEN + DEALLOCATE(MiscData%U_full_dot) +ENDIF +IF (ALLOCATED(MiscData%U_full_dotdot)) THEN + DEALLOCATE(MiscData%U_full_dotdot) +ENDIF +IF (ALLOCATED(MiscData%U_full_elast)) THEN + DEALLOCATE(MiscData%U_full_elast) +ENDIF +IF (ALLOCATED(MiscData%U_red)) THEN + DEALLOCATE(MiscData%U_red) +ENDIF +IF (ALLOCATED(MiscData%U_red_dot)) THEN + DEALLOCATE(MiscData%U_red_dot) +ENDIF +IF (ALLOCATED(MiscData%U_red_dotdot)) THEN + DEALLOCATE(MiscData%U_red_dotdot) +ENDIF +IF (ALLOCATED(MiscData%FC_unit)) THEN + DEALLOCATE(MiscData%FC_unit) +ENDIF IF (ALLOCATED(MiscData%SDWrOutput)) THEN DEALLOCATE(MiscData%SDWrOutput) +ENDIF +IF (ALLOCATED(MiscData%Fext)) THEN + DEALLOCATE(MiscData%Fext) +ENDIF +IF (ALLOCATED(MiscData%Fext_red)) THEN + DEALLOCATE(MiscData%Fext_red) ENDIF END SUBROUTINE SD_DestroyMisc @@ -5052,10 +6052,10 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Re_BufSz = Re_BufSz + SIZE(InData%u_TP) ! u_TP Re_BufSz = Re_BufSz + SIZE(InData%udot_TP) ! udot_TP Re_BufSz = Re_BufSz + SIZE(InData%udotdot_TP) ! udotdot_TP - Int_BufSz = Int_BufSz + 1 ! UFL allocated yes/no - IF ( ALLOCATED(InData%UFL) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! UFL upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%UFL) ! UFL + Int_BufSz = Int_BufSz + 1 ! F_L allocated yes/no + IF ( ALLOCATED(InData%F_L) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! F_L upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_L) ! F_L END IF Int_BufSz = Int_BufSz + 1 ! UR_bar allocated yes/no IF ( ALLOCATED(InData%UR_bar) ) THEN @@ -5087,6 +6087,51 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Int_BufSz = Int_BufSz + 2*1 ! UL_dotdot upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%UL_dotdot) ! UL_dotdot END IF + Int_BufSz = Int_BufSz + 1 ! DU_full allocated yes/no + IF ( ALLOCATED(InData%DU_full) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! DU_full upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%DU_full) ! DU_full + END IF + Int_BufSz = Int_BufSz + 1 ! U_full allocated yes/no + IF ( ALLOCATED(InData%U_full) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! U_full upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%U_full) ! U_full + END IF + Int_BufSz = Int_BufSz + 1 ! U_full_dot allocated yes/no + IF ( ALLOCATED(InData%U_full_dot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! U_full_dot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%U_full_dot) ! U_full_dot + END IF + Int_BufSz = Int_BufSz + 1 ! U_full_dotdot allocated yes/no + IF ( ALLOCATED(InData%U_full_dotdot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! U_full_dotdot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%U_full_dotdot) ! U_full_dotdot + END IF + Int_BufSz = Int_BufSz + 1 ! U_full_elast allocated yes/no + IF ( ALLOCATED(InData%U_full_elast) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! U_full_elast upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%U_full_elast) ! U_full_elast + END IF + Int_BufSz = Int_BufSz + 1 ! U_red allocated yes/no + IF ( ALLOCATED(InData%U_red) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! U_red upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%U_red) ! U_red + END IF + Int_BufSz = Int_BufSz + 1 ! U_red_dot allocated yes/no + IF ( ALLOCATED(InData%U_red_dot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! U_red_dot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%U_red_dot) ! U_red_dot + END IF + Int_BufSz = Int_BufSz + 1 ! U_red_dotdot allocated yes/no + IF ( ALLOCATED(InData%U_red_dotdot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! U_red_dotdot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%U_red_dotdot) ! U_red_dotdot + END IF + Int_BufSz = Int_BufSz + 1 ! FC_unit allocated yes/no + IF ( ALLOCATED(InData%FC_unit) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! FC_unit upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%FC_unit) ! FC_unit + END IF Int_BufSz = Int_BufSz + 1 ! SDWrOutput allocated yes/no IF ( ALLOCATED(InData%SDWrOutput) ) THEN Int_BufSz = Int_BufSz + 2*1 ! SDWrOutput upper/lower bounds for each dimension @@ -5094,6 +6139,16 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz END IF Db_BufSz = Db_BufSz + 1 ! LastOutTime Int_BufSz = Int_BufSz + 1 ! Decimat + Int_BufSz = Int_BufSz + 1 ! Fext allocated yes/no + IF ( ALLOCATED(InData%Fext) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Fext upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Fext) ! Fext + END IF + Int_BufSz = Int_BufSz + 1 ! Fext_red allocated yes/no + IF ( ALLOCATED(InData%Fext_red) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Fext_red upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Fext_red) ! Fext_red + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -5148,18 +6203,18 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz ReKiBuf(Re_Xferred) = InData%udotdot_TP(i1) Re_Xferred = Re_Xferred + 1 END DO - IF ( .NOT. ALLOCATED(InData%UFL) ) THEN + IF ( .NOT. ALLOCATED(InData%F_L) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%UFL,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%UFL,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%F_L,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_L,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%UFL,1), UBOUND(InData%UFL,1) - ReKiBuf(Re_Xferred) = InData%UFL(i1) + DO i1 = LBOUND(InData%F_L,1), UBOUND(InData%F_L,1) + ReKiBuf(Re_Xferred) = InData%F_L(i1) Re_Xferred = Re_Xferred + 1 END DO END IF @@ -5253,6 +6308,141 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%DU_full) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%DU_full,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DU_full,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%DU_full,1), UBOUND(InData%DU_full,1) + ReKiBuf(Re_Xferred) = InData%DU_full(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%U_full) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%U_full,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%U_full,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%U_full,1), UBOUND(InData%U_full,1) + ReKiBuf(Re_Xferred) = InData%U_full(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%U_full_dot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%U_full_dot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%U_full_dot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%U_full_dot,1), UBOUND(InData%U_full_dot,1) + ReKiBuf(Re_Xferred) = InData%U_full_dot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%U_full_dotdot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%U_full_dotdot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%U_full_dotdot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%U_full_dotdot,1), UBOUND(InData%U_full_dotdot,1) + ReKiBuf(Re_Xferred) = InData%U_full_dotdot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%U_full_elast) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%U_full_elast,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%U_full_elast,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%U_full_elast,1), UBOUND(InData%U_full_elast,1) + ReKiBuf(Re_Xferred) = InData%U_full_elast(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%U_red) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%U_red,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%U_red,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%U_red,1), UBOUND(InData%U_red,1) + ReKiBuf(Re_Xferred) = InData%U_red(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%U_red_dot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%U_red_dot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%U_red_dot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%U_red_dot,1), UBOUND(InData%U_red_dot,1) + ReKiBuf(Re_Xferred) = InData%U_red_dot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%U_red_dotdot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%U_red_dotdot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%U_red_dotdot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%U_red_dotdot,1), UBOUND(InData%U_red_dotdot,1) + ReKiBuf(Re_Xferred) = InData%U_red_dotdot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%FC_unit) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FC_unit,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FC_unit,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%FC_unit,1), UBOUND(InData%FC_unit,1) + ReKiBuf(Re_Xferred) = InData%FC_unit(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF IF ( .NOT. ALLOCATED(InData%SDWrOutput) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -5272,6 +6462,36 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Db_Xferred = Db_Xferred + 1 IntKiBuf(Int_Xferred) = InData%Decimat Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%Fext) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Fext,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Fext,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Fext,1), UBOUND(InData%Fext,1) + ReKiBuf(Re_Xferred) = InData%Fext(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Fext_red) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Fext_red,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Fext_red,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Fext_red,1), UBOUND(InData%Fext_red,1) + ReKiBuf(Re_Xferred) = InData%Fext_red(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE SD_PackMisc SUBROUTINE SD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -5337,21 +6557,21 @@ SUBROUTINE SD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) OutData%udotdot_TP(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! UFL not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_L not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%UFL)) DEALLOCATE(OutData%UFL) - ALLOCATE(OutData%UFL(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%F_L)) DEALLOCATE(OutData%F_L) + ALLOCATE(OutData%F_L(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%UFL.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_L.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%UFL,1), UBOUND(OutData%UFL,1) - OutData%UFL(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%F_L,1), UBOUND(OutData%F_L,1) + OutData%F_L(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF @@ -5463,77 +6683,441 @@ SUBROUTINE SD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! SDWrOutput not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! DU_full not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%SDWrOutput)) DEALLOCATE(OutData%SDWrOutput) - ALLOCATE(OutData%SDWrOutput(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%DU_full)) DEALLOCATE(OutData%DU_full) + ALLOCATE(OutData%DU_full(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%SDWrOutput.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%DU_full.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%SDWrOutput,1), UBOUND(OutData%SDWrOutput,1) - OutData%SDWrOutput(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%DU_full,1), UBOUND(OutData%DU_full,1) + OutData%DU_full(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - OutData%LastOutTime = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 - OutData%Decimat = IntKiBuf(Int_Xferred) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! U_full not allocated Int_Xferred = Int_Xferred + 1 - END SUBROUTINE SD_UnPackMisc - - SUBROUTINE SD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(SD_ParameterType), INTENT(IN) :: SrcParamData - TYPE(SD_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" - DstParamData%SDDeltaT = SrcParamData%SDDeltaT - DstParamData%SttcSolve = SrcParamData%SttcSolve -IF (ALLOCATED(SrcParamData%NOmegaM2)) THEN - i1_l = LBOUND(SrcParamData%NOmegaM2,1) - i1_u = UBOUND(SrcParamData%NOmegaM2,1) - IF (.NOT. ALLOCATED(DstParamData%NOmegaM2)) THEN - ALLOCATE(DstParamData%NOmegaM2(i1_l:i1_u),STAT=ErrStat2) + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%U_full)) DEALLOCATE(OutData%U_full) + ALLOCATE(OutData%U_full(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%NOmegaM2.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%U_full.', ErrStat, ErrMsg,RoutineName) + RETURN END IF + DO i1 = LBOUND(OutData%U_full,1), UBOUND(OutData%U_full,1) + OutData%U_full(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END IF - DstParamData%NOmegaM2 = SrcParamData%NOmegaM2 -ENDIF -IF (ALLOCATED(SrcParamData%N2OmegaMJDamp)) THEN - i1_l = LBOUND(SrcParamData%N2OmegaMJDamp,1) - i1_u = UBOUND(SrcParamData%N2OmegaMJDamp,1) - IF (.NOT. ALLOCATED(DstParamData%N2OmegaMJDamp)) THEN - ALLOCATE(DstParamData%N2OmegaMJDamp(i1_l:i1_u),STAT=ErrStat2) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! U_full_dot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%U_full_dot)) DEALLOCATE(OutData%U_full_dot) + ALLOCATE(OutData%U_full_dot(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%N2OmegaMJDamp.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%U_full_dot.', ErrStat, ErrMsg,RoutineName) + RETURN END IF + DO i1 = LBOUND(OutData%U_full_dot,1), UBOUND(OutData%U_full_dot,1) + OutData%U_full_dot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END IF - DstParamData%N2OmegaMJDamp = SrcParamData%N2OmegaMJDamp -ENDIF -IF (ALLOCATED(SrcParamData%MMB)) THEN - i1_l = LBOUND(SrcParamData%MMB,1) - i1_u = UBOUND(SrcParamData%MMB,1) - i2_l = LBOUND(SrcParamData%MMB,2) - i2_u = UBOUND(SrcParamData%MMB,2) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! U_full_dotdot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%U_full_dotdot)) DEALLOCATE(OutData%U_full_dotdot) + ALLOCATE(OutData%U_full_dotdot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%U_full_dotdot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%U_full_dotdot,1), UBOUND(OutData%U_full_dotdot,1) + OutData%U_full_dotdot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! U_full_elast not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%U_full_elast)) DEALLOCATE(OutData%U_full_elast) + ALLOCATE(OutData%U_full_elast(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%U_full_elast.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%U_full_elast,1), UBOUND(OutData%U_full_elast,1) + OutData%U_full_elast(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! U_red not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%U_red)) DEALLOCATE(OutData%U_red) + ALLOCATE(OutData%U_red(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%U_red.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%U_red,1), UBOUND(OutData%U_red,1) + OutData%U_red(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! U_red_dot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%U_red_dot)) DEALLOCATE(OutData%U_red_dot) + ALLOCATE(OutData%U_red_dot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%U_red_dot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%U_red_dot,1), UBOUND(OutData%U_red_dot,1) + OutData%U_red_dot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! U_red_dotdot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%U_red_dotdot)) DEALLOCATE(OutData%U_red_dotdot) + ALLOCATE(OutData%U_red_dotdot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%U_red_dotdot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%U_red_dotdot,1), UBOUND(OutData%U_red_dotdot,1) + OutData%U_red_dotdot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FC_unit not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%FC_unit)) DEALLOCATE(OutData%FC_unit) + ALLOCATE(OutData%FC_unit(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FC_unit.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%FC_unit,1), UBOUND(OutData%FC_unit,1) + OutData%FC_unit(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! SDWrOutput not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%SDWrOutput)) DEALLOCATE(OutData%SDWrOutput) + ALLOCATE(OutData%SDWrOutput(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%SDWrOutput.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%SDWrOutput,1), UBOUND(OutData%SDWrOutput,1) + OutData%SDWrOutput(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + OutData%LastOutTime = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%Decimat = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Fext not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Fext)) DEALLOCATE(OutData%Fext) + ALLOCATE(OutData%Fext(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Fext.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Fext,1), UBOUND(OutData%Fext,1) + OutData%Fext(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Fext_red not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Fext_red)) DEALLOCATE(OutData%Fext_red) + ALLOCATE(OutData%Fext_red(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Fext_red.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Fext_red,1), UBOUND(OutData%Fext_red,1) + OutData%Fext_red(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + END SUBROUTINE SD_UnPackMisc + + SUBROUTINE SD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) + TYPE(SD_ParameterType), INTENT(IN) :: SrcParamData + TYPE(SD_ParameterType), INTENT(INOUT) :: DstParamData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyParam' +! + ErrStat = ErrID_None + ErrMsg = "" + DstParamData%SDDeltaT = SrcParamData%SDDeltaT + DstParamData%IntMethod = SrcParamData%IntMethod + DstParamData%nDOF = SrcParamData%nDOF + DstParamData%nDOF_red = SrcParamData%nDOF_red + DstParamData%Nmembers = SrcParamData%Nmembers +IF (ALLOCATED(SrcParamData%Elems)) THEN + i1_l = LBOUND(SrcParamData%Elems,1) + i1_u = UBOUND(SrcParamData%Elems,1) + i2_l = LBOUND(SrcParamData%Elems,2) + i2_u = UBOUND(SrcParamData%Elems,2) + IF (.NOT. ALLOCATED(DstParamData%Elems)) THEN + ALLOCATE(DstParamData%Elems(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%Elems.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%Elems = SrcParamData%Elems +ENDIF +IF (ALLOCATED(SrcParamData%ElemProps)) THEN + i1_l = LBOUND(SrcParamData%ElemProps,1) + i1_u = UBOUND(SrcParamData%ElemProps,1) + IF (.NOT. ALLOCATED(DstParamData%ElemProps)) THEN + ALLOCATE(DstParamData%ElemProps(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%ElemProps.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcParamData%ElemProps,1), UBOUND(SrcParamData%ElemProps,1) + CALL SD_Copyelemproptype( SrcParamData%ElemProps(i1), DstParamData%ElemProps(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcParamData%FG)) THEN + i1_l = LBOUND(SrcParamData%FG,1) + i1_u = UBOUND(SrcParamData%FG,1) + IF (.NOT. ALLOCATED(DstParamData%FG)) THEN + ALLOCATE(DstParamData%FG(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%FG.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%FG = SrcParamData%FG +ENDIF +IF (ALLOCATED(SrcParamData%DP0)) THEN + i1_l = LBOUND(SrcParamData%DP0,1) + i1_u = UBOUND(SrcParamData%DP0,1) + i2_l = LBOUND(SrcParamData%DP0,2) + i2_u = UBOUND(SrcParamData%DP0,2) + IF (.NOT. ALLOCATED(DstParamData%DP0)) THEN + ALLOCATE(DstParamData%DP0(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%DP0.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%DP0 = SrcParamData%DP0 +ENDIF + DstParamData%reduced = SrcParamData%reduced +IF (ALLOCATED(SrcParamData%T_red)) THEN + i1_l = LBOUND(SrcParamData%T_red,1) + i1_u = UBOUND(SrcParamData%T_red,1) + i2_l = LBOUND(SrcParamData%T_red,2) + i2_u = UBOUND(SrcParamData%T_red,2) + IF (.NOT. ALLOCATED(DstParamData%T_red)) THEN + ALLOCATE(DstParamData%T_red(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%T_red.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%T_red = SrcParamData%T_red +ENDIF +IF (ALLOCATED(SrcParamData%T_red_T)) THEN + i1_l = LBOUND(SrcParamData%T_red_T,1) + i1_u = UBOUND(SrcParamData%T_red_T,1) + i2_l = LBOUND(SrcParamData%T_red_T,2) + i2_u = UBOUND(SrcParamData%T_red_T,2) + IF (.NOT. ALLOCATED(DstParamData%T_red_T)) THEN + ALLOCATE(DstParamData%T_red_T(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%T_red_T.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%T_red_T = SrcParamData%T_red_T +ENDIF +IF (ALLOCATED(SrcParamData%NodesDOF)) THEN + i1_l = LBOUND(SrcParamData%NodesDOF,1) + i1_u = UBOUND(SrcParamData%NodesDOF,1) + IF (.NOT. ALLOCATED(DstParamData%NodesDOF)) THEN + ALLOCATE(DstParamData%NodesDOF(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%NodesDOF.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcParamData%NodesDOF,1), UBOUND(SrcParamData%NodesDOF,1) + CALL SD_Copyilist( SrcParamData%NodesDOF(i1), DstParamData%NodesDOF(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcParamData%NodesDOFred)) THEN + i1_l = LBOUND(SrcParamData%NodesDOFred,1) + i1_u = UBOUND(SrcParamData%NodesDOFred,1) + IF (.NOT. ALLOCATED(DstParamData%NodesDOFred)) THEN + ALLOCATE(DstParamData%NodesDOFred(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%NodesDOFred.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcParamData%NodesDOFred,1), UBOUND(SrcParamData%NodesDOFred,1) + CALL SD_Copyilist( SrcParamData%NodesDOFred(i1), DstParamData%NodesDOFred(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcParamData%ElemsDOF)) THEN + i1_l = LBOUND(SrcParamData%ElemsDOF,1) + i1_u = UBOUND(SrcParamData%ElemsDOF,1) + i2_l = LBOUND(SrcParamData%ElemsDOF,2) + i2_u = UBOUND(SrcParamData%ElemsDOF,2) + IF (.NOT. ALLOCATED(DstParamData%ElemsDOF)) THEN + ALLOCATE(DstParamData%ElemsDOF(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%ElemsDOF.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%ElemsDOF = SrcParamData%ElemsDOF +ENDIF +IF (ALLOCATED(SrcParamData%DOFred2Nodes)) THEN + i1_l = LBOUND(SrcParamData%DOFred2Nodes,1) + i1_u = UBOUND(SrcParamData%DOFred2Nodes,1) + i2_l = LBOUND(SrcParamData%DOFred2Nodes,2) + i2_u = UBOUND(SrcParamData%DOFred2Nodes,2) + IF (.NOT. ALLOCATED(DstParamData%DOFred2Nodes)) THEN + ALLOCATE(DstParamData%DOFred2Nodes(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%DOFred2Nodes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%DOFred2Nodes = SrcParamData%DOFred2Nodes +ENDIF +IF (ALLOCATED(SrcParamData%CtrlElem2Channel)) THEN + i1_l = LBOUND(SrcParamData%CtrlElem2Channel,1) + i1_u = UBOUND(SrcParamData%CtrlElem2Channel,1) + i2_l = LBOUND(SrcParamData%CtrlElem2Channel,2) + i2_u = UBOUND(SrcParamData%CtrlElem2Channel,2) + IF (.NOT. ALLOCATED(DstParamData%CtrlElem2Channel)) THEN + ALLOCATE(DstParamData%CtrlElem2Channel(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%CtrlElem2Channel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%CtrlElem2Channel = SrcParamData%CtrlElem2Channel +ENDIF + DstParamData%nDOFM = SrcParamData%nDOFM + DstParamData%SttcSolve = SrcParamData%SttcSolve + DstParamData%GuyanLoadCorrection = SrcParamData%GuyanLoadCorrection + DstParamData%Floating = SrcParamData%Floating +IF (ALLOCATED(SrcParamData%KMMDiag)) THEN + i1_l = LBOUND(SrcParamData%KMMDiag,1) + i1_u = UBOUND(SrcParamData%KMMDiag,1) + IF (.NOT. ALLOCATED(DstParamData%KMMDiag)) THEN + ALLOCATE(DstParamData%KMMDiag(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%KMMDiag.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%KMMDiag = SrcParamData%KMMDiag +ENDIF +IF (ALLOCATED(SrcParamData%CMMDiag)) THEN + i1_l = LBOUND(SrcParamData%CMMDiag,1) + i1_u = UBOUND(SrcParamData%CMMDiag,1) + IF (.NOT. ALLOCATED(DstParamData%CMMDiag)) THEN + ALLOCATE(DstParamData%CMMDiag(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%CMMDiag.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%CMMDiag = SrcParamData%CMMDiag +ENDIF +IF (ALLOCATED(SrcParamData%MMB)) THEN + i1_l = LBOUND(SrcParamData%MMB,1) + i1_u = UBOUND(SrcParamData%MMB,1) + i2_l = LBOUND(SrcParamData%MMB,2) + i2_u = UBOUND(SrcParamData%MMB,2) IF (.NOT. ALLOCATED(DstParamData%MMB)) THEN ALLOCATE(DstParamData%MMB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN @@ -5543,17 +7127,19 @@ SUBROUTINE SD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF DstParamData%MMB = SrcParamData%MMB ENDIF -IF (ALLOCATED(SrcParamData%FX)) THEN - i1_l = LBOUND(SrcParamData%FX,1) - i1_u = UBOUND(SrcParamData%FX,1) - IF (.NOT. ALLOCATED(DstParamData%FX)) THEN - ALLOCATE(DstParamData%FX(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%MBmmB)) THEN + i1_l = LBOUND(SrcParamData%MBmmB,1) + i1_u = UBOUND(SrcParamData%MBmmB,1) + i2_l = LBOUND(SrcParamData%MBmmB,2) + i2_u = UBOUND(SrcParamData%MBmmB,2) + IF (.NOT. ALLOCATED(DstParamData%MBmmB)) THEN + ALLOCATE(DstParamData%MBmmB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%FX.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%MBmmB.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%FX = SrcParamData%FX + DstParamData%MBmmB = SrcParamData%MBmmB ENDIF IF (ALLOCATED(SrcParamData%C1_11)) THEN i1_l = LBOUND(SrcParamData%C1_11,1) @@ -5583,45 +7169,33 @@ SUBROUTINE SD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF DstParamData%C1_12 = SrcParamData%C1_12 ENDIF -IF (ALLOCATED(SrcParamData%D1_13)) THEN - i1_l = LBOUND(SrcParamData%D1_13,1) - i1_u = UBOUND(SrcParamData%D1_13,1) - i2_l = LBOUND(SrcParamData%D1_13,2) - i2_u = UBOUND(SrcParamData%D1_13,2) - IF (.NOT. ALLOCATED(DstParamData%D1_13)) THEN - ALLOCATE(DstParamData%D1_13(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%D1_13.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%D1_13 = SrcParamData%D1_13 -ENDIF -IF (ALLOCATED(SrcParamData%D1_14)) THEN - i1_l = LBOUND(SrcParamData%D1_14,1) - i1_u = UBOUND(SrcParamData%D1_14,1) - i2_l = LBOUND(SrcParamData%D1_14,2) - i2_u = UBOUND(SrcParamData%D1_14,2) - IF (.NOT. ALLOCATED(DstParamData%D1_14)) THEN - ALLOCATE(DstParamData%D1_14(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%D1_141)) THEN + i1_l = LBOUND(SrcParamData%D1_141,1) + i1_u = UBOUND(SrcParamData%D1_141,1) + i2_l = LBOUND(SrcParamData%D1_141,2) + i2_u = UBOUND(SrcParamData%D1_141,2) + IF (.NOT. ALLOCATED(DstParamData%D1_141)) THEN + ALLOCATE(DstParamData%D1_141(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%D1_14.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%D1_141.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%D1_14 = SrcParamData%D1_14 + DstParamData%D1_141 = SrcParamData%D1_141 ENDIF -IF (ALLOCATED(SrcParamData%FY)) THEN - i1_l = LBOUND(SrcParamData%FY,1) - i1_u = UBOUND(SrcParamData%FY,1) - IF (.NOT. ALLOCATED(DstParamData%FY)) THEN - ALLOCATE(DstParamData%FY(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%D1_142)) THEN + i1_l = LBOUND(SrcParamData%D1_142,1) + i1_u = UBOUND(SrcParamData%D1_142,1) + i2_l = LBOUND(SrcParamData%D1_142,2) + i2_u = UBOUND(SrcParamData%D1_142,2) + IF (.NOT. ALLOCATED(DstParamData%D1_142)) THEN + ALLOCATE(DstParamData%D1_142(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%FY.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%D1_142.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%FY = SrcParamData%FY + DstParamData%D1_142 = SrcParamData%D1_142 ENDIF IF (ALLOCATED(SrcParamData%PhiM)) THEN i1_l = LBOUND(SrcParamData%PhiM,1) @@ -5707,18 +7281,6 @@ SUBROUTINE SD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF DstParamData%D2_64 = SrcParamData%D2_64 ENDIF -IF (ALLOCATED(SrcParamData%F2_61)) THEN - i1_l = LBOUND(SrcParamData%F2_61,1) - i1_u = UBOUND(SrcParamData%F2_61,1) - IF (.NOT. ALLOCATED(DstParamData%F2_61)) THEN - ALLOCATE(DstParamData%F2_61(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%F2_61.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%F2_61 = SrcParamData%F2_61 -ENDIF IF (ALLOCATED(SrcParamData%MBB)) THEN i1_l = LBOUND(SrcParamData%MBB,1) i1_u = UBOUND(SrcParamData%MBB,1) @@ -5747,6 +7309,34 @@ SUBROUTINE SD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF DstParamData%KBB = SrcParamData%KBB ENDIF +IF (ALLOCATED(SrcParamData%CBB)) THEN + i1_l = LBOUND(SrcParamData%CBB,1) + i1_u = UBOUND(SrcParamData%CBB,1) + i2_l = LBOUND(SrcParamData%CBB,2) + i2_u = UBOUND(SrcParamData%CBB,2) + IF (.NOT. ALLOCATED(DstParamData%CBB)) THEN + ALLOCATE(DstParamData%CBB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%CBB.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%CBB = SrcParamData%CBB +ENDIF +IF (ALLOCATED(SrcParamData%CMM)) THEN + i1_l = LBOUND(SrcParamData%CMM,1) + i1_u = UBOUND(SrcParamData%CMM,1) + i2_l = LBOUND(SrcParamData%CMM,2) + i2_u = UBOUND(SrcParamData%CMM,2) + IF (.NOT. ALLOCATED(DstParamData%CMM)) THEN + ALLOCATE(DstParamData%CMM(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%CMM.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%CMM = SrcParamData%CMM +ENDIF IF (ALLOCATED(SrcParamData%MBM)) THEN i1_l = LBOUND(SrcParamData%MBM,1) i1_u = UBOUND(SrcParamData%MBM,1) @@ -5789,17 +7379,19 @@ SUBROUTINE SD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF DstParamData%PhiLInvOmgL2 = SrcParamData%PhiLInvOmgL2 ENDIF -IF (ALLOCATED(SrcParamData%FGL)) THEN - i1_l = LBOUND(SrcParamData%FGL,1) - i1_u = UBOUND(SrcParamData%FGL,1) - IF (.NOT. ALLOCATED(DstParamData%FGL)) THEN - ALLOCATE(DstParamData%FGL(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%KLLm1)) THEN + i1_l = LBOUND(SrcParamData%KLLm1,1) + i1_u = UBOUND(SrcParamData%KLLm1,1) + i2_l = LBOUND(SrcParamData%KLLm1,2) + i2_u = UBOUND(SrcParamData%KLLm1,2) + IF (.NOT. ALLOCATED(DstParamData%KLLm1)) THEN + ALLOCATE(DstParamData%KLLm1(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%FGL.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%KLLm1.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%FGL = SrcParamData%FGL + DstParamData%KLLm1 = SrcParamData%KLLm1 ENDIF IF (ALLOCATED(SrcParamData%AM2Jac)) THEN i1_l = LBOUND(SrcParamData%AM2Jac,1) @@ -5855,107 +7447,207 @@ SUBROUTINE SD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF DstParamData%TIreact = SrcParamData%TIreact ENDIF - DstParamData%NModes = SrcParamData%NModes -IF (ALLOCATED(SrcParamData%Elems)) THEN - i1_l = LBOUND(SrcParamData%Elems,1) - i1_u = UBOUND(SrcParamData%Elems,1) - i2_l = LBOUND(SrcParamData%Elems,2) - i2_u = UBOUND(SrcParamData%Elems,2) - IF (.NOT. ALLOCATED(DstParamData%Elems)) THEN - ALLOCATE(DstParamData%Elems(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + DstParamData%nNodes = SrcParamData%nNodes + DstParamData%nNodes_I = SrcParamData%nNodes_I + DstParamData%nNodes_L = SrcParamData%nNodes_L + DstParamData%nNodes_C = SrcParamData%nNodes_C +IF (ALLOCATED(SrcParamData%Nodes_I)) THEN + i1_l = LBOUND(SrcParamData%Nodes_I,1) + i1_u = UBOUND(SrcParamData%Nodes_I,1) + i2_l = LBOUND(SrcParamData%Nodes_I,2) + i2_u = UBOUND(SrcParamData%Nodes_I,2) + IF (.NOT. ALLOCATED(DstParamData%Nodes_I)) THEN + ALLOCATE(DstParamData%Nodes_I(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%Nodes_I.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%Nodes_I = SrcParamData%Nodes_I +ENDIF +IF (ALLOCATED(SrcParamData%Nodes_L)) THEN + i1_l = LBOUND(SrcParamData%Nodes_L,1) + i1_u = UBOUND(SrcParamData%Nodes_L,1) + i2_l = LBOUND(SrcParamData%Nodes_L,2) + i2_u = UBOUND(SrcParamData%Nodes_L,2) + IF (.NOT. ALLOCATED(DstParamData%Nodes_L)) THEN + ALLOCATE(DstParamData%Nodes_L(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%Elems.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%Nodes_L.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%Elems = SrcParamData%Elems + DstParamData%Nodes_L = SrcParamData%Nodes_L ENDIF - DstParamData%qmL = SrcParamData%qmL - DstParamData%DofL = SrcParamData%DofL - DstParamData%NNodes_I = SrcParamData%NNodes_I - DstParamData%NNodes_L = SrcParamData%NNodes_L - DstParamData%NNodes_RbarL = SrcParamData%NNodes_RbarL - DstParamData%DofI = SrcParamData%DofI - DstParamData%DofR = SrcParamData%DofR - DstParamData%DofC = SrcParamData%DofC - DstParamData%NReact = SrcParamData%NReact -IF (ALLOCATED(SrcParamData%Reacts)) THEN - i1_l = LBOUND(SrcParamData%Reacts,1) - i1_u = UBOUND(SrcParamData%Reacts,1) - i2_l = LBOUND(SrcParamData%Reacts,2) - i2_u = UBOUND(SrcParamData%Reacts,2) - IF (.NOT. ALLOCATED(DstParamData%Reacts)) THEN - ALLOCATE(DstParamData%Reacts(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%Nodes_C)) THEN + i1_l = LBOUND(SrcParamData%Nodes_C,1) + i1_u = UBOUND(SrcParamData%Nodes_C,1) + i2_l = LBOUND(SrcParamData%Nodes_C,2) + i2_u = UBOUND(SrcParamData%Nodes_C,2) + IF (.NOT. ALLOCATED(DstParamData%Nodes_C)) THEN + ALLOCATE(DstParamData%Nodes_C(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%Reacts.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%Nodes_C.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%Reacts = SrcParamData%Reacts + DstParamData%Nodes_C = SrcParamData%Nodes_C +ENDIF + DstParamData%nDOFI__ = SrcParamData%nDOFI__ + DstParamData%nDOFI_Rb = SrcParamData%nDOFI_Rb + DstParamData%nDOFI_F = SrcParamData%nDOFI_F + DstParamData%nDOFL_L = SrcParamData%nDOFL_L + DstParamData%nDOFC__ = SrcParamData%nDOFC__ + DstParamData%nDOFC_Rb = SrcParamData%nDOFC_Rb + DstParamData%nDOFC_L = SrcParamData%nDOFC_L + DstParamData%nDOFC_F = SrcParamData%nDOFC_F + DstParamData%nDOFR__ = SrcParamData%nDOFR__ + DstParamData%nDOF__Rb = SrcParamData%nDOF__Rb + DstParamData%nDOF__L = SrcParamData%nDOF__L + DstParamData%nDOF__F = SrcParamData%nDOF__F +IF (ALLOCATED(SrcParamData%IDI__)) THEN + i1_l = LBOUND(SrcParamData%IDI__,1) + i1_u = UBOUND(SrcParamData%IDI__,1) + IF (.NOT. ALLOCATED(DstParamData%IDI__)) THEN + ALLOCATE(DstParamData%IDI__(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%IDI__.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%IDI__ = SrcParamData%IDI__ ENDIF - DstParamData%Nmembers = SrcParamData%Nmembers - DstParamData%URbarL = SrcParamData%URbarL - DstParamData%IntMethod = SrcParamData%IntMethod - DstParamData%NAvgEls = SrcParamData%NAvgEls -IF (ALLOCATED(SrcParamData%IDI)) THEN - i1_l = LBOUND(SrcParamData%IDI,1) - i1_u = UBOUND(SrcParamData%IDI,1) - IF (.NOT. ALLOCATED(DstParamData%IDI)) THEN - ALLOCATE(DstParamData%IDI(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%IDI_Rb)) THEN + i1_l = LBOUND(SrcParamData%IDI_Rb,1) + i1_u = UBOUND(SrcParamData%IDI_Rb,1) + IF (.NOT. ALLOCATED(DstParamData%IDI_Rb)) THEN + ALLOCATE(DstParamData%IDI_Rb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%IDI_Rb.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%IDI_Rb = SrcParamData%IDI_Rb +ENDIF +IF (ALLOCATED(SrcParamData%IDI_F)) THEN + i1_l = LBOUND(SrcParamData%IDI_F,1) + i1_u = UBOUND(SrcParamData%IDI_F,1) + IF (.NOT. ALLOCATED(DstParamData%IDI_F)) THEN + ALLOCATE(DstParamData%IDI_F(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%IDI_F.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%IDI_F = SrcParamData%IDI_F +ENDIF +IF (ALLOCATED(SrcParamData%IDL_L)) THEN + i1_l = LBOUND(SrcParamData%IDL_L,1) + i1_u = UBOUND(SrcParamData%IDL_L,1) + IF (.NOT. ALLOCATED(DstParamData%IDL_L)) THEN + ALLOCATE(DstParamData%IDL_L(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%IDL_L.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%IDL_L = SrcParamData%IDL_L +ENDIF +IF (ALLOCATED(SrcParamData%IDC__)) THEN + i1_l = LBOUND(SrcParamData%IDC__,1) + i1_u = UBOUND(SrcParamData%IDC__,1) + IF (.NOT. ALLOCATED(DstParamData%IDC__)) THEN + ALLOCATE(DstParamData%IDC__(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%IDI.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%IDC__.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%IDI = SrcParamData%IDI + DstParamData%IDC__ = SrcParamData%IDC__ ENDIF -IF (ALLOCATED(SrcParamData%IDR)) THEN - i1_l = LBOUND(SrcParamData%IDR,1) - i1_u = UBOUND(SrcParamData%IDR,1) - IF (.NOT. ALLOCATED(DstParamData%IDR)) THEN - ALLOCATE(DstParamData%IDR(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%IDC_Rb)) THEN + i1_l = LBOUND(SrcParamData%IDC_Rb,1) + i1_u = UBOUND(SrcParamData%IDC_Rb,1) + IF (.NOT. ALLOCATED(DstParamData%IDC_Rb)) THEN + ALLOCATE(DstParamData%IDC_Rb(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%IDR.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%IDC_Rb.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%IDR = SrcParamData%IDR + DstParamData%IDC_Rb = SrcParamData%IDC_Rb ENDIF -IF (ALLOCATED(SrcParamData%IDL)) THEN - i1_l = LBOUND(SrcParamData%IDL,1) - i1_u = UBOUND(SrcParamData%IDL,1) - IF (.NOT. ALLOCATED(DstParamData%IDL)) THEN - ALLOCATE(DstParamData%IDL(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%IDC_L)) THEN + i1_l = LBOUND(SrcParamData%IDC_L,1) + i1_u = UBOUND(SrcParamData%IDC_L,1) + IF (.NOT. ALLOCATED(DstParamData%IDC_L)) THEN + ALLOCATE(DstParamData%IDC_L(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%IDL.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%IDC_L.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%IDL = SrcParamData%IDL + DstParamData%IDC_L = SrcParamData%IDC_L ENDIF -IF (ALLOCATED(SrcParamData%IDC)) THEN - i1_l = LBOUND(SrcParamData%IDC,1) - i1_u = UBOUND(SrcParamData%IDC,1) - IF (.NOT. ALLOCATED(DstParamData%IDC)) THEN - ALLOCATE(DstParamData%IDC(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%IDC_F)) THEN + i1_l = LBOUND(SrcParamData%IDC_F,1) + i1_u = UBOUND(SrcParamData%IDC_F,1) + IF (.NOT. ALLOCATED(DstParamData%IDC_F)) THEN + ALLOCATE(DstParamData%IDC_F(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%IDC.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%IDC_F.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%IDC = SrcParamData%IDC + DstParamData%IDC_F = SrcParamData%IDC_F ENDIF -IF (ALLOCATED(SrcParamData%IDY)) THEN - i1_l = LBOUND(SrcParamData%IDY,1) - i1_u = UBOUND(SrcParamData%IDY,1) - IF (.NOT. ALLOCATED(DstParamData%IDY)) THEN - ALLOCATE(DstParamData%IDY(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%IDR__)) THEN + i1_l = LBOUND(SrcParamData%IDR__,1) + i1_u = UBOUND(SrcParamData%IDR__,1) + IF (.NOT. ALLOCATED(DstParamData%IDR__)) THEN + ALLOCATE(DstParamData%IDR__(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%IDY.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%IDR__.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%IDY = SrcParamData%IDY + DstParamData%IDR__ = SrcParamData%IDR__ +ENDIF +IF (ALLOCATED(SrcParamData%ID__Rb)) THEN + i1_l = LBOUND(SrcParamData%ID__Rb,1) + i1_u = UBOUND(SrcParamData%ID__Rb,1) + IF (.NOT. ALLOCATED(DstParamData%ID__Rb)) THEN + ALLOCATE(DstParamData%ID__Rb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%ID__Rb.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%ID__Rb = SrcParamData%ID__Rb +ENDIF +IF (ALLOCATED(SrcParamData%ID__L)) THEN + i1_l = LBOUND(SrcParamData%ID__L,1) + i1_u = UBOUND(SrcParamData%ID__L,1) + IF (.NOT. ALLOCATED(DstParamData%ID__L)) THEN + ALLOCATE(DstParamData%ID__L(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%ID__L.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%ID__L = SrcParamData%ID__L +ENDIF +IF (ALLOCATED(SrcParamData%ID__F)) THEN + i1_l = LBOUND(SrcParamData%ID__F,1) + i1_u = UBOUND(SrcParamData%ID__F,1) + IF (.NOT. ALLOCATED(DstParamData%ID__F)) THEN + ALLOCATE(DstParamData%ID__F(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%ID__F.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%ID__F = SrcParamData%ID__F ENDIF DstParamData%NMOutputs = SrcParamData%NMOutputs DstParamData%NumOuts = SrcParamData%NumOuts @@ -6012,22 +7704,6 @@ SUBROUTINE SD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcParamData%ElemProps)) THEN - i1_l = LBOUND(SrcParamData%ElemProps,1) - i1_u = UBOUND(SrcParamData%ElemProps,1) - IF (.NOT. ALLOCATED(DstParamData%ElemProps)) THEN - ALLOCATE(DstParamData%ElemProps(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%ElemProps.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcParamData%ElemProps,1), UBOUND(SrcParamData%ElemProps,1) - CALL SD_Copyelemproptype( SrcParamData%ElemProps(i1), DstParamData%ElemProps(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF IF (ALLOCATED(SrcParamData%OutParam)) THEN i1_l = LBOUND(SrcParamData%OutParam,1) i1_u = UBOUND(SrcParamData%OutParam,1) @@ -6049,6 +7725,36 @@ SUBROUTINE SD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) DstParamData%OutAllInt = SrcParamData%OutAllInt DstParamData%OutAllDims = SrcParamData%OutAllDims DstParamData%OutDec = SrcParamData%OutDec +IF (ALLOCATED(SrcParamData%Jac_u_indx)) THEN + i1_l = LBOUND(SrcParamData%Jac_u_indx,1) + i1_u = UBOUND(SrcParamData%Jac_u_indx,1) + i2_l = LBOUND(SrcParamData%Jac_u_indx,2) + i2_u = UBOUND(SrcParamData%Jac_u_indx,2) + IF (.NOT. ALLOCATED(DstParamData%Jac_u_indx)) THEN + ALLOCATE(DstParamData%Jac_u_indx(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%Jac_u_indx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%Jac_u_indx = SrcParamData%Jac_u_indx +ENDIF +IF (ALLOCATED(SrcParamData%du)) THEN + i1_l = LBOUND(SrcParamData%du,1) + i1_u = UBOUND(SrcParamData%du,1) + IF (.NOT. ALLOCATED(DstParamData%du)) THEN + ALLOCATE(DstParamData%du(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%du.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%du = SrcParamData%du +ENDIF + DstParamData%dx = SrcParamData%dx + DstParamData%Jac_ny = SrcParamData%Jac_ny + DstParamData%Jac_nx = SrcParamData%Jac_nx + DstParamData%RotStates = SrcParamData%RotStates END SUBROUTINE SD_CopyParam SUBROUTINE SD_DestroyParam( ParamData, ErrStat, ErrMsg ) @@ -6060,17 +7766,59 @@ SUBROUTINE SD_DestroyParam( ParamData, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(ParamData%NOmegaM2)) THEN - DEALLOCATE(ParamData%NOmegaM2) +IF (ALLOCATED(ParamData%Elems)) THEN + DEALLOCATE(ParamData%Elems) +ENDIF +IF (ALLOCATED(ParamData%ElemProps)) THEN +DO i1 = LBOUND(ParamData%ElemProps,1), UBOUND(ParamData%ElemProps,1) + CALL SD_Destroyelemproptype( ParamData%ElemProps(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(ParamData%ElemProps) ENDIF -IF (ALLOCATED(ParamData%N2OmegaMJDamp)) THEN - DEALLOCATE(ParamData%N2OmegaMJDamp) +IF (ALLOCATED(ParamData%FG)) THEN + DEALLOCATE(ParamData%FG) +ENDIF +IF (ALLOCATED(ParamData%DP0)) THEN + DEALLOCATE(ParamData%DP0) +ENDIF +IF (ALLOCATED(ParamData%T_red)) THEN + DEALLOCATE(ParamData%T_red) +ENDIF +IF (ALLOCATED(ParamData%T_red_T)) THEN + DEALLOCATE(ParamData%T_red_T) +ENDIF +IF (ALLOCATED(ParamData%NodesDOF)) THEN +DO i1 = LBOUND(ParamData%NodesDOF,1), UBOUND(ParamData%NodesDOF,1) + CALL SD_Destroyilist( ParamData%NodesDOF(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(ParamData%NodesDOF) +ENDIF +IF (ALLOCATED(ParamData%NodesDOFred)) THEN +DO i1 = LBOUND(ParamData%NodesDOFred,1), UBOUND(ParamData%NodesDOFred,1) + CALL SD_Destroyilist( ParamData%NodesDOFred(i1), ErrStat, ErrMsg ) +ENDDO + DEALLOCATE(ParamData%NodesDOFred) +ENDIF +IF (ALLOCATED(ParamData%ElemsDOF)) THEN + DEALLOCATE(ParamData%ElemsDOF) +ENDIF +IF (ALLOCATED(ParamData%DOFred2Nodes)) THEN + DEALLOCATE(ParamData%DOFred2Nodes) +ENDIF +IF (ALLOCATED(ParamData%CtrlElem2Channel)) THEN + DEALLOCATE(ParamData%CtrlElem2Channel) +ENDIF +IF (ALLOCATED(ParamData%KMMDiag)) THEN + DEALLOCATE(ParamData%KMMDiag) +ENDIF +IF (ALLOCATED(ParamData%CMMDiag)) THEN + DEALLOCATE(ParamData%CMMDiag) ENDIF IF (ALLOCATED(ParamData%MMB)) THEN DEALLOCATE(ParamData%MMB) ENDIF -IF (ALLOCATED(ParamData%FX)) THEN - DEALLOCATE(ParamData%FX) +IF (ALLOCATED(ParamData%MBmmB)) THEN + DEALLOCATE(ParamData%MBmmB) ENDIF IF (ALLOCATED(ParamData%C1_11)) THEN DEALLOCATE(ParamData%C1_11) @@ -6078,14 +7826,11 @@ SUBROUTINE SD_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%C1_12)) THEN DEALLOCATE(ParamData%C1_12) ENDIF -IF (ALLOCATED(ParamData%D1_13)) THEN - DEALLOCATE(ParamData%D1_13) +IF (ALLOCATED(ParamData%D1_141)) THEN + DEALLOCATE(ParamData%D1_141) ENDIF -IF (ALLOCATED(ParamData%D1_14)) THEN - DEALLOCATE(ParamData%D1_14) -ENDIF -IF (ALLOCATED(ParamData%FY)) THEN - DEALLOCATE(ParamData%FY) +IF (ALLOCATED(ParamData%D1_142)) THEN + DEALLOCATE(ParamData%D1_142) ENDIF IF (ALLOCATED(ParamData%PhiM)) THEN DEALLOCATE(ParamData%PhiM) @@ -6105,15 +7850,18 @@ SUBROUTINE SD_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%D2_64)) THEN DEALLOCATE(ParamData%D2_64) ENDIF -IF (ALLOCATED(ParamData%F2_61)) THEN - DEALLOCATE(ParamData%F2_61) -ENDIF IF (ALLOCATED(ParamData%MBB)) THEN DEALLOCATE(ParamData%MBB) ENDIF IF (ALLOCATED(ParamData%KBB)) THEN DEALLOCATE(ParamData%KBB) ENDIF +IF (ALLOCATED(ParamData%CBB)) THEN + DEALLOCATE(ParamData%CBB) +ENDIF +IF (ALLOCATED(ParamData%CMM)) THEN + DEALLOCATE(ParamData%CMM) +ENDIF IF (ALLOCATED(ParamData%MBM)) THEN DEALLOCATE(ParamData%MBM) ENDIF @@ -6123,8 +7871,8 @@ SUBROUTINE SD_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%PhiLInvOmgL2)) THEN DEALLOCATE(ParamData%PhiLInvOmgL2) ENDIF -IF (ALLOCATED(ParamData%FGL)) THEN - DEALLOCATE(ParamData%FGL) +IF (ALLOCATED(ParamData%KLLm1)) THEN + DEALLOCATE(ParamData%KLLm1) ENDIF IF (ALLOCATED(ParamData%AM2Jac)) THEN DEALLOCATE(ParamData%AM2Jac) @@ -6138,26 +7886,50 @@ SUBROUTINE SD_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%TIreact)) THEN DEALLOCATE(ParamData%TIreact) ENDIF -IF (ALLOCATED(ParamData%Elems)) THEN - DEALLOCATE(ParamData%Elems) +IF (ALLOCATED(ParamData%Nodes_I)) THEN + DEALLOCATE(ParamData%Nodes_I) +ENDIF +IF (ALLOCATED(ParamData%Nodes_L)) THEN + DEALLOCATE(ParamData%Nodes_L) +ENDIF +IF (ALLOCATED(ParamData%Nodes_C)) THEN + DEALLOCATE(ParamData%Nodes_C) +ENDIF +IF (ALLOCATED(ParamData%IDI__)) THEN + DEALLOCATE(ParamData%IDI__) +ENDIF +IF (ALLOCATED(ParamData%IDI_Rb)) THEN + DEALLOCATE(ParamData%IDI_Rb) +ENDIF +IF (ALLOCATED(ParamData%IDI_F)) THEN + DEALLOCATE(ParamData%IDI_F) +ENDIF +IF (ALLOCATED(ParamData%IDL_L)) THEN + DEALLOCATE(ParamData%IDL_L) ENDIF -IF (ALLOCATED(ParamData%Reacts)) THEN - DEALLOCATE(ParamData%Reacts) +IF (ALLOCATED(ParamData%IDC__)) THEN + DEALLOCATE(ParamData%IDC__) ENDIF -IF (ALLOCATED(ParamData%IDI)) THEN - DEALLOCATE(ParamData%IDI) +IF (ALLOCATED(ParamData%IDC_Rb)) THEN + DEALLOCATE(ParamData%IDC_Rb) ENDIF -IF (ALLOCATED(ParamData%IDR)) THEN - DEALLOCATE(ParamData%IDR) +IF (ALLOCATED(ParamData%IDC_L)) THEN + DEALLOCATE(ParamData%IDC_L) ENDIF -IF (ALLOCATED(ParamData%IDL)) THEN - DEALLOCATE(ParamData%IDL) +IF (ALLOCATED(ParamData%IDC_F)) THEN + DEALLOCATE(ParamData%IDC_F) ENDIF -IF (ALLOCATED(ParamData%IDC)) THEN - DEALLOCATE(ParamData%IDC) +IF (ALLOCATED(ParamData%IDR__)) THEN + DEALLOCATE(ParamData%IDR__) ENDIF -IF (ALLOCATED(ParamData%IDY)) THEN - DEALLOCATE(ParamData%IDY) +IF (ALLOCATED(ParamData%ID__Rb)) THEN + DEALLOCATE(ParamData%ID__Rb) +ENDIF +IF (ALLOCATED(ParamData%ID__L)) THEN + DEALLOCATE(ParamData%ID__L) +ENDIF +IF (ALLOCATED(ParamData%ID__F)) THEN + DEALLOCATE(ParamData%ID__F) ENDIF IF (ALLOCATED(ParamData%MoutLst)) THEN DO i1 = LBOUND(ParamData%MoutLst,1), UBOUND(ParamData%MoutLst,1) @@ -6177,17 +7949,17 @@ SUBROUTINE SD_DestroyParam( ParamData, ErrStat, ErrMsg ) ENDDO DEALLOCATE(ParamData%MoutLst3) ENDIF -IF (ALLOCATED(ParamData%ElemProps)) THEN -DO i1 = LBOUND(ParamData%ElemProps,1), UBOUND(ParamData%ElemProps,1) - CALL SD_Destroyelemproptype( ParamData%ElemProps(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(ParamData%ElemProps) -ENDIF IF (ALLOCATED(ParamData%OutParam)) THEN DO i1 = LBOUND(ParamData%OutParam,1), UBOUND(ParamData%OutParam,1) CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat, ErrMsg ) ENDDO DEALLOCATE(ParamData%OutParam) +ENDIF +IF (ALLOCATED(ParamData%Jac_u_indx)) THEN + DEALLOCATE(ParamData%Jac_u_indx) +ENDIF +IF (ALLOCATED(ParamData%du)) THEN + DEALLOCATE(ParamData%du) ENDIF END SUBROUTINE SD_DestroyParam @@ -6227,26 +7999,144 @@ SUBROUTINE SD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Db_BufSz = 0 Int_BufSz = 0 Db_BufSz = Db_BufSz + 1 ! SDDeltaT - Int_BufSz = Int_BufSz + 1 ! SttcSolve - Int_BufSz = Int_BufSz + 1 ! NOmegaM2 allocated yes/no - IF ( ALLOCATED(InData%NOmegaM2) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! NOmegaM2 upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%NOmegaM2) ! NOmegaM2 + Int_BufSz = Int_BufSz + 1 ! IntMethod + Int_BufSz = Int_BufSz + 1 ! nDOF + Int_BufSz = Int_BufSz + 1 ! nDOF_red + Int_BufSz = Int_BufSz + 1 ! Nmembers + Int_BufSz = Int_BufSz + 1 ! Elems allocated yes/no + IF ( ALLOCATED(InData%Elems) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Elems upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%Elems) ! Elems + END IF + Int_BufSz = Int_BufSz + 1 ! ElemProps allocated yes/no + IF ( ALLOCATED(InData%ElemProps) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ElemProps upper/lower bounds for each dimension + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%ElemProps,1), UBOUND(InData%ElemProps,1) + Int_BufSz = Int_BufSz + 3 ! ElemProps: size of buffers for each call to pack subtype + CALL SD_Packelemproptype( Re_Buf, Db_Buf, Int_Buf, InData%ElemProps(i1), ErrStat2, ErrMsg2, .TRUE. ) ! ElemProps + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! ElemProps + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! ElemProps + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! ElemProps + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! FG allocated yes/no + IF ( ALLOCATED(InData%FG) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! FG upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%FG) ! FG + END IF + Int_BufSz = Int_BufSz + 1 ! DP0 allocated yes/no + IF ( ALLOCATED(InData%DP0) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! DP0 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%DP0) ! DP0 + END IF + Int_BufSz = Int_BufSz + 1 ! reduced + Int_BufSz = Int_BufSz + 1 ! T_red allocated yes/no + IF ( ALLOCATED(InData%T_red) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! T_red upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%T_red) ! T_red + END IF + Int_BufSz = Int_BufSz + 1 ! T_red_T allocated yes/no + IF ( ALLOCATED(InData%T_red_T) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! T_red_T upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%T_red_T) ! T_red_T + END IF + Int_BufSz = Int_BufSz + 1 ! NodesDOF allocated yes/no + IF ( ALLOCATED(InData%NodesDOF) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! NodesDOF upper/lower bounds for each dimension + DO i1 = LBOUND(InData%NodesDOF,1), UBOUND(InData%NodesDOF,1) + Int_BufSz = Int_BufSz + 3 ! NodesDOF: size of buffers for each call to pack subtype + CALL SD_Packilist( Re_Buf, Db_Buf, Int_Buf, InData%NodesDOF(i1), ErrStat2, ErrMsg2, .TRUE. ) ! NodesDOF + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! NodesDOF + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! NodesDOF + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! NodesDOF + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! NodesDOFred allocated yes/no + IF ( ALLOCATED(InData%NodesDOFred) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! NodesDOFred upper/lower bounds for each dimension + DO i1 = LBOUND(InData%NodesDOFred,1), UBOUND(InData%NodesDOFred,1) + Int_BufSz = Int_BufSz + 3 ! NodesDOFred: size of buffers for each call to pack subtype + CALL SD_Packilist( Re_Buf, Db_Buf, Int_Buf, InData%NodesDOFred(i1), ErrStat2, ErrMsg2, .TRUE. ) ! NodesDOFred + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! NodesDOFred + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! NodesDOFred + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! NodesDOFred + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO END IF - Int_BufSz = Int_BufSz + 1 ! N2OmegaMJDamp allocated yes/no - IF ( ALLOCATED(InData%N2OmegaMJDamp) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! N2OmegaMJDamp upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%N2OmegaMJDamp) ! N2OmegaMJDamp + Int_BufSz = Int_BufSz + 1 ! ElemsDOF allocated yes/no + IF ( ALLOCATED(InData%ElemsDOF) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! ElemsDOF upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%ElemsDOF) ! ElemsDOF + END IF + Int_BufSz = Int_BufSz + 1 ! DOFred2Nodes allocated yes/no + IF ( ALLOCATED(InData%DOFred2Nodes) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! DOFred2Nodes upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%DOFred2Nodes) ! DOFred2Nodes + END IF + Int_BufSz = Int_BufSz + 1 ! CtrlElem2Channel allocated yes/no + IF ( ALLOCATED(InData%CtrlElem2Channel) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! CtrlElem2Channel upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%CtrlElem2Channel) ! CtrlElem2Channel + END IF + Int_BufSz = Int_BufSz + 1 ! nDOFM + Int_BufSz = Int_BufSz + 1 ! SttcSolve + Int_BufSz = Int_BufSz + 1 ! GuyanLoadCorrection + Int_BufSz = Int_BufSz + 1 ! Floating + Int_BufSz = Int_BufSz + 1 ! KMMDiag allocated yes/no + IF ( ALLOCATED(InData%KMMDiag) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! KMMDiag upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%KMMDiag) ! KMMDiag + END IF + Int_BufSz = Int_BufSz + 1 ! CMMDiag allocated yes/no + IF ( ALLOCATED(InData%CMMDiag) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! CMMDiag upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%CMMDiag) ! CMMDiag END IF Int_BufSz = Int_BufSz + 1 ! MMB allocated yes/no IF ( ALLOCATED(InData%MMB) ) THEN Int_BufSz = Int_BufSz + 2*2 ! MMB upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%MMB) ! MMB END IF - Int_BufSz = Int_BufSz + 1 ! FX allocated yes/no - IF ( ALLOCATED(InData%FX) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! FX upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%FX) ! FX + Int_BufSz = Int_BufSz + 1 ! MBmmB allocated yes/no + IF ( ALLOCATED(InData%MBmmB) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! MBmmB upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%MBmmB) ! MBmmB END IF Int_BufSz = Int_BufSz + 1 ! C1_11 allocated yes/no IF ( ALLOCATED(InData%C1_11) ) THEN @@ -6258,20 +8148,15 @@ SUBROUTINE SD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + 2*2 ! C1_12 upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%C1_12) ! C1_12 END IF - Int_BufSz = Int_BufSz + 1 ! D1_13 allocated yes/no - IF ( ALLOCATED(InData%D1_13) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! D1_13 upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D1_13) ! D1_13 + Int_BufSz = Int_BufSz + 1 ! D1_141 allocated yes/no + IF ( ALLOCATED(InData%D1_141) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! D1_141 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%D1_141) ! D1_141 END IF - Int_BufSz = Int_BufSz + 1 ! D1_14 allocated yes/no - IF ( ALLOCATED(InData%D1_14) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! D1_14 upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%D1_14) ! D1_14 - END IF - Int_BufSz = Int_BufSz + 1 ! FY allocated yes/no - IF ( ALLOCATED(InData%FY) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! FY upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%FY) ! FY + Int_BufSz = Int_BufSz + 1 ! D1_142 allocated yes/no + IF ( ALLOCATED(InData%D1_142) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! D1_142 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%D1_142) ! D1_142 END IF Int_BufSz = Int_BufSz + 1 ! PhiM allocated yes/no IF ( ALLOCATED(InData%PhiM) ) THEN @@ -6303,11 +8188,6 @@ SUBROUTINE SD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + 2*2 ! D2_64 upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%D2_64) ! D2_64 END IF - Int_BufSz = Int_BufSz + 1 ! F2_61 allocated yes/no - IF ( ALLOCATED(InData%F2_61) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! F2_61 upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%F2_61) ! F2_61 - END IF Int_BufSz = Int_BufSz + 1 ! MBB allocated yes/no IF ( ALLOCATED(InData%MBB) ) THEN Int_BufSz = Int_BufSz + 2*2 ! MBB upper/lower bounds for each dimension @@ -6318,6 +8198,16 @@ SUBROUTINE SD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + 2*2 ! KBB upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%KBB) ! KBB END IF + Int_BufSz = Int_BufSz + 1 ! CBB allocated yes/no + IF ( ALLOCATED(InData%CBB) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! CBB upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%CBB) ! CBB + END IF + Int_BufSz = Int_BufSz + 1 ! CMM allocated yes/no + IF ( ALLOCATED(InData%CMM) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! CMM upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%CMM) ! CMM + END IF Int_BufSz = Int_BufSz + 1 ! MBM allocated yes/no IF ( ALLOCATED(InData%MBM) ) THEN Int_BufSz = Int_BufSz + 2*2 ! MBM upper/lower bounds for each dimension @@ -6333,10 +8223,10 @@ SUBROUTINE SD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + 2*2 ! PhiLInvOmgL2 upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%PhiLInvOmgL2) ! PhiLInvOmgL2 END IF - Int_BufSz = Int_BufSz + 1 ! FGL allocated yes/no - IF ( ALLOCATED(InData%FGL) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! FGL upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%FGL) ! FGL + Int_BufSz = Int_BufSz + 1 ! KLLm1 allocated yes/no + IF ( ALLOCATED(InData%KLLm1) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! KLLm1 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%KLLm1) ! KLLm1 END IF Int_BufSz = Int_BufSz + 1 ! AM2Jac allocated yes/no IF ( ALLOCATED(InData%AM2Jac) ) THEN @@ -6358,54 +8248,96 @@ SUBROUTINE SD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + 2*2 ! TIreact upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%TIreact) ! TIreact END IF - Int_BufSz = Int_BufSz + 1 ! NModes - Int_BufSz = Int_BufSz + 1 ! Elems allocated yes/no - IF ( ALLOCATED(InData%Elems) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! Elems upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%Elems) ! Elems - END IF - Int_BufSz = Int_BufSz + 1 ! qmL - Int_BufSz = Int_BufSz + 1 ! DofL - Int_BufSz = Int_BufSz + 1 ! NNodes_I - Int_BufSz = Int_BufSz + 1 ! NNodes_L - Int_BufSz = Int_BufSz + 1 ! NNodes_RbarL - Int_BufSz = Int_BufSz + 1 ! DofI - Int_BufSz = Int_BufSz + 1 ! DofR - Int_BufSz = Int_BufSz + 1 ! DofC - Int_BufSz = Int_BufSz + 1 ! NReact - Int_BufSz = Int_BufSz + 1 ! Reacts allocated yes/no - IF ( ALLOCATED(InData%Reacts) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! Reacts upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%Reacts) ! Reacts - END IF - Int_BufSz = Int_BufSz + 1 ! Nmembers - Int_BufSz = Int_BufSz + 1 ! URbarL - Int_BufSz = Int_BufSz + 1 ! IntMethod - Int_BufSz = Int_BufSz + 1 ! NAvgEls - Int_BufSz = Int_BufSz + 1 ! IDI allocated yes/no - IF ( ALLOCATED(InData%IDI) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! IDI upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%IDI) ! IDI - END IF - Int_BufSz = Int_BufSz + 1 ! IDR allocated yes/no - IF ( ALLOCATED(InData%IDR) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! IDR upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%IDR) ! IDR - END IF - Int_BufSz = Int_BufSz + 1 ! IDL allocated yes/no - IF ( ALLOCATED(InData%IDL) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! IDL upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%IDL) ! IDL - END IF - Int_BufSz = Int_BufSz + 1 ! IDC allocated yes/no - IF ( ALLOCATED(InData%IDC) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! IDC upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%IDC) ! IDC - END IF - Int_BufSz = Int_BufSz + 1 ! IDY allocated yes/no - IF ( ALLOCATED(InData%IDY) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! IDY upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%IDY) ! IDY + Int_BufSz = Int_BufSz + 1 ! nNodes + Int_BufSz = Int_BufSz + 1 ! nNodes_I + Int_BufSz = Int_BufSz + 1 ! nNodes_L + Int_BufSz = Int_BufSz + 1 ! nNodes_C + Int_BufSz = Int_BufSz + 1 ! Nodes_I allocated yes/no + IF ( ALLOCATED(InData%Nodes_I) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Nodes_I upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%Nodes_I) ! Nodes_I + END IF + Int_BufSz = Int_BufSz + 1 ! Nodes_L allocated yes/no + IF ( ALLOCATED(InData%Nodes_L) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Nodes_L upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%Nodes_L) ! Nodes_L + END IF + Int_BufSz = Int_BufSz + 1 ! Nodes_C allocated yes/no + IF ( ALLOCATED(InData%Nodes_C) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Nodes_C upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%Nodes_C) ! Nodes_C + END IF + Int_BufSz = Int_BufSz + 1 ! nDOFI__ + Int_BufSz = Int_BufSz + 1 ! nDOFI_Rb + Int_BufSz = Int_BufSz + 1 ! nDOFI_F + Int_BufSz = Int_BufSz + 1 ! nDOFL_L + Int_BufSz = Int_BufSz + 1 ! nDOFC__ + Int_BufSz = Int_BufSz + 1 ! nDOFC_Rb + Int_BufSz = Int_BufSz + 1 ! nDOFC_L + Int_BufSz = Int_BufSz + 1 ! nDOFC_F + Int_BufSz = Int_BufSz + 1 ! nDOFR__ + Int_BufSz = Int_BufSz + 1 ! nDOF__Rb + Int_BufSz = Int_BufSz + 1 ! nDOF__L + Int_BufSz = Int_BufSz + 1 ! nDOF__F + Int_BufSz = Int_BufSz + 1 ! IDI__ allocated yes/no + IF ( ALLOCATED(InData%IDI__) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! IDI__ upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%IDI__) ! IDI__ + END IF + Int_BufSz = Int_BufSz + 1 ! IDI_Rb allocated yes/no + IF ( ALLOCATED(InData%IDI_Rb) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! IDI_Rb upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%IDI_Rb) ! IDI_Rb + END IF + Int_BufSz = Int_BufSz + 1 ! IDI_F allocated yes/no + IF ( ALLOCATED(InData%IDI_F) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! IDI_F upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%IDI_F) ! IDI_F + END IF + Int_BufSz = Int_BufSz + 1 ! IDL_L allocated yes/no + IF ( ALLOCATED(InData%IDL_L) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! IDL_L upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%IDL_L) ! IDL_L + END IF + Int_BufSz = Int_BufSz + 1 ! IDC__ allocated yes/no + IF ( ALLOCATED(InData%IDC__) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! IDC__ upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%IDC__) ! IDC__ + END IF + Int_BufSz = Int_BufSz + 1 ! IDC_Rb allocated yes/no + IF ( ALLOCATED(InData%IDC_Rb) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! IDC_Rb upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%IDC_Rb) ! IDC_Rb + END IF + Int_BufSz = Int_BufSz + 1 ! IDC_L allocated yes/no + IF ( ALLOCATED(InData%IDC_L) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! IDC_L upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%IDC_L) ! IDC_L + END IF + Int_BufSz = Int_BufSz + 1 ! IDC_F allocated yes/no + IF ( ALLOCATED(InData%IDC_F) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! IDC_F upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%IDC_F) ! IDC_F + END IF + Int_BufSz = Int_BufSz + 1 ! IDR__ allocated yes/no + IF ( ALLOCATED(InData%IDR__) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! IDR__ upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%IDR__) ! IDR__ + END IF + Int_BufSz = Int_BufSz + 1 ! ID__Rb allocated yes/no + IF ( ALLOCATED(InData%ID__Rb) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ID__Rb upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%ID__Rb) ! ID__Rb + END IF + Int_BufSz = Int_BufSz + 1 ! ID__L allocated yes/no + IF ( ALLOCATED(InData%ID__L) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ID__L upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%ID__L) ! ID__L + END IF + Int_BufSz = Int_BufSz + 1 ! ID__F allocated yes/no + IF ( ALLOCATED(InData%ID__F) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ID__F upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%ID__F) ! ID__F END IF Int_BufSz = Int_BufSz + 1 ! NMOutputs Int_BufSz = Int_BufSz + 1 ! NumOuts @@ -6417,7 +8349,6 @@ SUBROUTINE SD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + 1 ! MoutLst allocated yes/no IF ( ALLOCATED(InData%MoutLst) ) THEN Int_BufSz = Int_BufSz + 2*1 ! MoutLst upper/lower bounds for each dimension - ! Allocate buffers for subtypes, if any (we'll get sizes from these) DO i1 = LBOUND(InData%MoutLst,1), UBOUND(InData%MoutLst,1) Int_BufSz = Int_BufSz + 3 ! MoutLst: size of buffers for each call to pack subtype CALL SD_Packmeshauxdatatype( Re_Buf, Db_Buf, Int_Buf, InData%MoutLst(i1), ErrStat2, ErrMsg2, .TRUE. ) ! MoutLst @@ -6470,1032 +8401,1833 @@ SUBROUTINE SD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! MoutLst3 - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! MoutLst3 - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! MoutLst3 - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO + IF(ALLOCATED(Re_Buf)) THEN ! MoutLst3 + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! MoutLst3 + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! MoutLst3 + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! OutParam allocated yes/no + IF ( ALLOCATED(InData%OutParam) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! OutParam upper/lower bounds for each dimension + DO i1 = LBOUND(InData%OutParam,1), UBOUND(InData%OutParam,1) + Int_BufSz = Int_BufSz + 3 ! OutParam: size of buffers for each call to pack subtype + CALL NWTC_Library_Packoutparmtype( Re_Buf, Db_Buf, Int_Buf, InData%OutParam(i1), ErrStat2, ErrMsg2, .TRUE. ) ! OutParam + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! OutParam + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! OutParam + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! OutParam + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! OutAll + Int_BufSz = Int_BufSz + 1 ! OutReact + Int_BufSz = Int_BufSz + 1 ! OutAllInt + Int_BufSz = Int_BufSz + 1 ! OutAllDims + Int_BufSz = Int_BufSz + 1 ! OutDec + Int_BufSz = Int_BufSz + 1 ! Jac_u_indx allocated yes/no + IF ( ALLOCATED(InData%Jac_u_indx) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Jac_u_indx upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%Jac_u_indx) ! Jac_u_indx + END IF + Int_BufSz = Int_BufSz + 1 ! du allocated yes/no + IF ( ALLOCATED(InData%du) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! du upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%du) ! du + END IF + Db_BufSz = Db_BufSz + SIZE(InData%dx) ! dx + Int_BufSz = Int_BufSz + 1 ! Jac_ny + Int_BufSz = Int_BufSz + 1 ! Jac_nx + Int_BufSz = Int_BufSz + 1 ! RotStates + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DbKiBuf(Db_Xferred) = InData%SDDeltaT + Db_Xferred = Db_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%IntMethod + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nDOF + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nDOF_red + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%Nmembers + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%Elems) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Elems,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Elems,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Elems,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Elems,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Elems,2), UBOUND(InData%Elems,2) + DO i1 = LBOUND(InData%Elems,1), UBOUND(InData%Elems,1) + IntKiBuf(Int_Xferred) = InData%Elems(i1,i2) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%ElemProps) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ElemProps,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ElemProps,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ElemProps,1), UBOUND(InData%ElemProps,1) + CALL SD_Packelemproptype( Re_Buf, Db_Buf, Int_Buf, InData%ElemProps(i1), ErrStat2, ErrMsg2, OnlySize ) ! ElemProps + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO + END IF + IF ( .NOT. ALLOCATED(InData%FG) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FG,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FG,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%FG,1), UBOUND(InData%FG,1) + DbKiBuf(Db_Xferred) = InData%FG(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%DP0) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%DP0,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DP0,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%DP0,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DP0,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%DP0,2), UBOUND(InData%DP0,2) + DO i1 = LBOUND(InData%DP0,1), UBOUND(InData%DP0,1) + ReKiBuf(Re_Xferred) = InData%DP0(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IntKiBuf(Int_Xferred) = TRANSFER(InData%reduced, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%T_red) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%T_red,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%T_red,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%T_red,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%T_red,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%T_red,2), UBOUND(InData%T_red,2) + DO i1 = LBOUND(InData%T_red,1), UBOUND(InData%T_red,1) + DbKiBuf(Db_Xferred) = InData%T_red(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%T_red_T) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%T_red_T,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%T_red_T,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%T_red_T,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%T_red_T,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%T_red_T,2), UBOUND(InData%T_red_T,2) + DO i1 = LBOUND(InData%T_red_T,1), UBOUND(InData%T_red_T,1) + DbKiBuf(Db_Xferred) = InData%T_red_T(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%NodesDOF) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%NodesDOF,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NodesDOF,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%NodesDOF,1), UBOUND(InData%NodesDOF,1) + CALL SD_Packilist( Re_Buf, Db_Buf, Int_Buf, InData%NodesDOF(i1), ErrStat2, ErrMsg2, OnlySize ) ! NodesDOF + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO + END IF + IF ( .NOT. ALLOCATED(InData%NodesDOFred) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%NodesDOFred,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NodesDOFred,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%NodesDOFred,1), UBOUND(InData%NodesDOFred,1) + CALL SD_Packilist( Re_Buf, Db_Buf, Int_Buf, InData%NodesDOFred(i1), ErrStat2, ErrMsg2, OnlySize ) ! NodesDOFred + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO + END IF + IF ( .NOT. ALLOCATED(InData%ElemsDOF) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ElemsDOF,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ElemsDOF,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ElemsDOF,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ElemsDOF,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%ElemsDOF,2), UBOUND(InData%ElemsDOF,2) + DO i1 = LBOUND(InData%ElemsDOF,1), UBOUND(InData%ElemsDOF,1) + IntKiBuf(Int_Xferred) = InData%ElemsDOF(i1,i2) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%DOFred2Nodes) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%DOFred2Nodes,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DOFred2Nodes,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%DOFred2Nodes,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DOFred2Nodes,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%DOFred2Nodes,2), UBOUND(InData%DOFred2Nodes,2) + DO i1 = LBOUND(InData%DOFred2Nodes,1), UBOUND(InData%DOFred2Nodes,1) + IntKiBuf(Int_Xferred) = InData%DOFred2Nodes(i1,i2) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%CtrlElem2Channel) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CtrlElem2Channel,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CtrlElem2Channel,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CtrlElem2Channel,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CtrlElem2Channel,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%CtrlElem2Channel,2), UBOUND(InData%CtrlElem2Channel,2) + DO i1 = LBOUND(InData%CtrlElem2Channel,1), UBOUND(InData%CtrlElem2Channel,1) + IntKiBuf(Int_Xferred) = InData%CtrlElem2Channel(i1,i2) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IntKiBuf(Int_Xferred) = InData%nDOFM + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%SttcSolve + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%GuyanLoadCorrection, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%Floating, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%KMMDiag) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%KMMDiag,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KMMDiag,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%KMMDiag,1), UBOUND(InData%KMMDiag,1) + ReKiBuf(Re_Xferred) = InData%KMMDiag(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%CMMDiag) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CMMDiag,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CMMDiag,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%CMMDiag,1), UBOUND(InData%CMMDiag,1) + ReKiBuf(Re_Xferred) = InData%CMMDiag(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MMB) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MMB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MMB,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MMB,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MMB,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%MMB,2), UBOUND(InData%MMB,2) + DO i1 = LBOUND(InData%MMB,1), UBOUND(InData%MMB,1) + ReKiBuf(Re_Xferred) = InData%MMB(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MBmmB) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MBmmB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBmmB,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MBmmB,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBmmB,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%MBmmB,2), UBOUND(InData%MBmmB,2) + DO i1 = LBOUND(InData%MBmmB,1), UBOUND(InData%MBmmB,1) + ReKiBuf(Re_Xferred) = InData%MBmmB(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%C1_11) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%C1_11,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C1_11,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%C1_11,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C1_11,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%C1_11,2), UBOUND(InData%C1_11,2) + DO i1 = LBOUND(InData%C1_11,1), UBOUND(InData%C1_11,1) + ReKiBuf(Re_Xferred) = InData%C1_11(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%C1_12) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%C1_12,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C1_12,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%C1_12,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C1_12,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%C1_12,2), UBOUND(InData%C1_12,2) + DO i1 = LBOUND(InData%C1_12,1), UBOUND(InData%C1_12,1) + ReKiBuf(Re_Xferred) = InData%C1_12(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%D1_141) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%D1_141,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D1_141,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%D1_141,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D1_141,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%D1_141,2), UBOUND(InData%D1_141,2) + DO i1 = LBOUND(InData%D1_141,1), UBOUND(InData%D1_141,1) + ReKiBuf(Re_Xferred) = InData%D1_141(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%D1_142) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%D1_142,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D1_142,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%D1_142,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D1_142,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%D1_142,2), UBOUND(InData%D1_142,2) + DO i1 = LBOUND(InData%D1_142,1), UBOUND(InData%D1_142,1) + ReKiBuf(Re_Xferred) = InData%D1_142(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PhiM) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiM,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiM,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiM,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiM,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%PhiM,2), UBOUND(InData%PhiM,2) + DO i1 = LBOUND(InData%PhiM,1), UBOUND(InData%PhiM,1) + ReKiBuf(Re_Xferred) = InData%PhiM(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%C2_61) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%C2_61,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C2_61,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%C2_61,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C2_61,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%C2_61,2), UBOUND(InData%C2_61,2) + DO i1 = LBOUND(InData%C2_61,1), UBOUND(InData%C2_61,1) + ReKiBuf(Re_Xferred) = InData%C2_61(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%C2_62) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%C2_62,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C2_62,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%C2_62,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C2_62,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%C2_62,2), UBOUND(InData%C2_62,2) + DO i1 = LBOUND(InData%C2_62,1), UBOUND(InData%C2_62,1) + ReKiBuf(Re_Xferred) = InData%C2_62(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PhiRb_TI) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiRb_TI,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiRb_TI,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiRb_TI,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiRb_TI,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%PhiRb_TI,2), UBOUND(InData%PhiRb_TI,2) + DO i1 = LBOUND(InData%PhiRb_TI,1), UBOUND(InData%PhiRb_TI,1) + ReKiBuf(Re_Xferred) = InData%PhiRb_TI(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF - Int_BufSz = Int_BufSz + 1 ! ElemProps allocated yes/no - IF ( ALLOCATED(InData%ElemProps) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! ElemProps upper/lower bounds for each dimension - DO i1 = LBOUND(InData%ElemProps,1), UBOUND(InData%ElemProps,1) - Int_BufSz = Int_BufSz + 3 ! ElemProps: size of buffers for each call to pack subtype - CALL SD_Packelemproptype( Re_Buf, Db_Buf, Int_Buf, InData%ElemProps(i1), ErrStat2, ErrMsg2, .TRUE. ) ! ElemProps - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + IF ( .NOT. ALLOCATED(InData%D2_63) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%D2_63,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D2_63,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%D2_63,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D2_63,2) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf)) THEN ! ElemProps - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! ElemProps - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! ElemProps - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO + DO i2 = LBOUND(InData%D2_63,2), UBOUND(InData%D2_63,2) + DO i1 = LBOUND(InData%D2_63,1), UBOUND(InData%D2_63,1) + ReKiBuf(Re_Xferred) = InData%D2_63(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF - Int_BufSz = Int_BufSz + 1 ! OutParam allocated yes/no - IF ( ALLOCATED(InData%OutParam) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! OutParam upper/lower bounds for each dimension - DO i1 = LBOUND(InData%OutParam,1), UBOUND(InData%OutParam,1) - Int_BufSz = Int_BufSz + 3 ! OutParam: size of buffers for each call to pack subtype - CALL NWTC_Library_Packoutparmtype( Re_Buf, Db_Buf, Int_Buf, InData%OutParam(i1), ErrStat2, ErrMsg2, .TRUE. ) ! OutParam - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + IF ( .NOT. ALLOCATED(InData%D2_64) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%D2_64,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D2_64,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%D2_64,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D2_64,2) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf)) THEN ! OutParam - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! OutParam - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! OutParam - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO + DO i2 = LBOUND(InData%D2_64,2), UBOUND(InData%D2_64,2) + DO i1 = LBOUND(InData%D2_64,1), UBOUND(InData%D2_64,1) + ReKiBuf(Re_Xferred) = InData%D2_64(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF - Int_BufSz = Int_BufSz + 1 ! OutAll - Int_BufSz = Int_BufSz + 1 ! OutReact - Int_BufSz = Int_BufSz + 1 ! OutAllInt - Int_BufSz = Int_BufSz + 1 ! OutAllDims - Int_BufSz = Int_BufSz + 1 ! OutDec - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + IF ( .NOT. ALLOCATED(InData%MBB) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MBB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBB,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MBB,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBB,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%MBB,2), UBOUND(InData%MBB,2) + DO i1 = LBOUND(InData%MBB,1), UBOUND(InData%MBB,1) + ReKiBuf(Re_Xferred) = InData%MBB(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + IF ( .NOT. ALLOCATED(InData%KBB) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%KBB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KBB,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%KBB,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KBB,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%KBB,2), UBOUND(InData%KBB,2) + DO i1 = LBOUND(InData%KBB,1), UBOUND(InData%KBB,1) + ReKiBuf(Re_Xferred) = InData%KBB(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + IF ( .NOT. ALLOCATED(InData%CBB) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CBB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CBB,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CBB,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CBB,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%CBB,2), UBOUND(InData%CBB,2) + DO i1 = LBOUND(InData%CBB,1), UBOUND(InData%CBB,1) + ReKiBuf(Re_Xferred) = InData%CBB(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + IF ( .NOT. ALLOCATED(InData%CMM) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CMM,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CMM,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CMM,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CMM,2) + Int_Xferred = Int_Xferred + 2 - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 + DO i2 = LBOUND(InData%CMM,2), UBOUND(InData%CMM,2) + DO i1 = LBOUND(InData%CMM,1), UBOUND(InData%CMM,1) + ReKiBuf(Re_Xferred) = InData%CMM(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MBM) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MBM,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBM,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MBM,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBM,2) + Int_Xferred = Int_Xferred + 2 - DbKiBuf(Db_Xferred) = InData%SDDeltaT - Db_Xferred = Db_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%SttcSolve, IntKiBuf(1)) + DO i2 = LBOUND(InData%MBM,2), UBOUND(InData%MBM,2) + DO i1 = LBOUND(InData%MBM,1), UBOUND(InData%MBM,1) + ReKiBuf(Re_Xferred) = InData%MBM(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PhiL_T) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%NOmegaM2) ) THEN + IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiL_T,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiL_T,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiL_T,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiL_T,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%PhiL_T,2), UBOUND(InData%PhiL_T,2) + DO i1 = LBOUND(InData%PhiL_T,1), UBOUND(InData%PhiL_T,1) + ReKiBuf(Re_Xferred) = InData%PhiL_T(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PhiLInvOmgL2) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%NOmegaM2,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NOmegaM2,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiLInvOmgL2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiLInvOmgL2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiLInvOmgL2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiLInvOmgL2,2) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%NOmegaM2,1), UBOUND(InData%NOmegaM2,1) - ReKiBuf(Re_Xferred) = InData%NOmegaM2(i1) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(InData%PhiLInvOmgL2,2), UBOUND(InData%PhiLInvOmgL2,2) + DO i1 = LBOUND(InData%PhiLInvOmgL2,1), UBOUND(InData%PhiLInvOmgL2,1) + ReKiBuf(Re_Xferred) = InData%PhiLInvOmgL2(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%N2OmegaMJDamp) ) THEN + IF ( .NOT. ALLOCATED(InData%KLLm1) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%N2OmegaMJDamp,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%N2OmegaMJDamp,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%KLLm1,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KLLm1,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%KLLm1,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KLLm1,2) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%N2OmegaMJDamp,1), UBOUND(InData%N2OmegaMJDamp,1) - ReKiBuf(Re_Xferred) = InData%N2OmegaMJDamp(i1) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(InData%KLLm1,2), UBOUND(InData%KLLm1,2) + DO i1 = LBOUND(InData%KLLm1,1), UBOUND(InData%KLLm1,1) + ReKiBuf(Re_Xferred) = InData%KLLm1(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%MMB) ) THEN + IF ( .NOT. ALLOCATED(InData%AM2Jac) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MMB,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MMB,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%AM2Jac,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AM2Jac,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MMB,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MMB,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%AM2Jac,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AM2Jac,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%MMB,2), UBOUND(InData%MMB,2) - DO i1 = LBOUND(InData%MMB,1), UBOUND(InData%MMB,1) - ReKiBuf(Re_Xferred) = InData%MMB(i1,i2) + DO i2 = LBOUND(InData%AM2Jac,2), UBOUND(InData%AM2Jac,2) + DO i1 = LBOUND(InData%AM2Jac,1), UBOUND(InData%AM2Jac,1) + ReKiBuf(Re_Xferred) = InData%AM2Jac(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%FX) ) THEN + IF ( .NOT. ALLOCATED(InData%AM2JacPiv) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FX,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FX,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%AM2JacPiv,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AM2JacPiv,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%FX,1), UBOUND(InData%FX,1) - ReKiBuf(Re_Xferred) = InData%FX(i1) - Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%AM2JacPiv,1), UBOUND(InData%AM2JacPiv,1) + IntKiBuf(Int_Xferred) = InData%AM2JacPiv(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%C1_11) ) THEN + IF ( .NOT. ALLOCATED(InData%TI) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%C1_11,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C1_11,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%TI,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TI,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%C1_11,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C1_11,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%TI,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TI,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%C1_11,2), UBOUND(InData%C1_11,2) - DO i1 = LBOUND(InData%C1_11,1), UBOUND(InData%C1_11,1) - ReKiBuf(Re_Xferred) = InData%C1_11(i1,i2) + DO i2 = LBOUND(InData%TI,2), UBOUND(InData%TI,2) + DO i1 = LBOUND(InData%TI,1), UBOUND(InData%TI,1) + ReKiBuf(Re_Xferred) = InData%TI(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%C1_12) ) THEN + IF ( .NOT. ALLOCATED(InData%TIreact) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%C1_12,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C1_12,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%TIreact,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TIreact,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%C1_12,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C1_12,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%TIreact,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TIreact,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%C1_12,2), UBOUND(InData%C1_12,2) - DO i1 = LBOUND(InData%C1_12,1), UBOUND(InData%C1_12,1) - ReKiBuf(Re_Xferred) = InData%C1_12(i1,i2) + DO i2 = LBOUND(InData%TIreact,2), UBOUND(InData%TIreact,2) + DO i1 = LBOUND(InData%TIreact,1), UBOUND(InData%TIreact,1) + ReKiBuf(Re_Xferred) = InData%TIreact(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%D1_13) ) THEN + IntKiBuf(Int_Xferred) = InData%nNodes + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nNodes_I + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nNodes_L + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nNodes_C + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%Nodes_I) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D1_13,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D1_13,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Nodes_I,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Nodes_I,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D1_13,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D1_13,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Nodes_I,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Nodes_I,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%D1_13,2), UBOUND(InData%D1_13,2) - DO i1 = LBOUND(InData%D1_13,1), UBOUND(InData%D1_13,1) - ReKiBuf(Re_Xferred) = InData%D1_13(i1,i2) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(InData%Nodes_I,2), UBOUND(InData%Nodes_I,2) + DO i1 = LBOUND(InData%Nodes_I,1), UBOUND(InData%Nodes_I,1) + IntKiBuf(Int_Xferred) = InData%Nodes_I(i1,i2) + Int_Xferred = Int_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%D1_14) ) THEN + IF ( .NOT. ALLOCATED(InData%Nodes_L) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D1_14,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D1_14,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Nodes_L,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Nodes_L,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D1_14,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D1_14,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Nodes_L,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Nodes_L,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%D1_14,2), UBOUND(InData%D1_14,2) - DO i1 = LBOUND(InData%D1_14,1), UBOUND(InData%D1_14,1) - ReKiBuf(Re_Xferred) = InData%D1_14(i1,i2) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(InData%Nodes_L,2), UBOUND(InData%Nodes_L,2) + DO i1 = LBOUND(InData%Nodes_L,1), UBOUND(InData%Nodes_L,1) + IntKiBuf(Int_Xferred) = InData%Nodes_L(i1,i2) + Int_Xferred = Int_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%FY) ) THEN + IF ( .NOT. ALLOCATED(InData%Nodes_C) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FY,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FY,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Nodes_C,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Nodes_C,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Nodes_C,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Nodes_C,2) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%FY,1), UBOUND(InData%FY,1) - ReKiBuf(Re_Xferred) = InData%FY(i1) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(InData%Nodes_C,2), UBOUND(InData%Nodes_C,2) + DO i1 = LBOUND(InData%Nodes_C,1), UBOUND(InData%Nodes_C,1) + IntKiBuf(Int_Xferred) = InData%Nodes_C(i1,i2) + Int_Xferred = Int_Xferred + 1 + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%PhiM) ) THEN + IntKiBuf(Int_Xferred) = InData%nDOFI__ + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nDOFI_Rb + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nDOFI_F + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nDOFL_L + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nDOFC__ + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nDOFC_Rb + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nDOFC_L + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nDOFC_F + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nDOFR__ + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nDOF__Rb + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nDOF__L + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nDOF__F + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%IDI__) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiM,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiM,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiM,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiM,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%IDI__,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IDI__,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%PhiM,2), UBOUND(InData%PhiM,2) - DO i1 = LBOUND(InData%PhiM,1), UBOUND(InData%PhiM,1) - ReKiBuf(Re_Xferred) = InData%PhiM(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(InData%IDI__,1), UBOUND(InData%IDI__,1) + IntKiBuf(Int_Xferred) = InData%IDI__(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%C2_61) ) THEN + IF ( .NOT. ALLOCATED(InData%IDI_Rb) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%C2_61,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C2_61,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%C2_61,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C2_61,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%IDI_Rb,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IDI_Rb,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%C2_61,2), UBOUND(InData%C2_61,2) - DO i1 = LBOUND(InData%C2_61,1), UBOUND(InData%C2_61,1) - ReKiBuf(Re_Xferred) = InData%C2_61(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(InData%IDI_Rb,1), UBOUND(InData%IDI_Rb,1) + IntKiBuf(Int_Xferred) = InData%IDI_Rb(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%C2_62) ) THEN + IF ( .NOT. ALLOCATED(InData%IDI_F) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%C2_62,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C2_62,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%C2_62,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%C2_62,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%IDI_F,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IDI_F,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%C2_62,2), UBOUND(InData%C2_62,2) - DO i1 = LBOUND(InData%C2_62,1), UBOUND(InData%C2_62,1) - ReKiBuf(Re_Xferred) = InData%C2_62(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(InData%IDI_F,1), UBOUND(InData%IDI_F,1) + IntKiBuf(Int_Xferred) = InData%IDI_F(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%PhiRb_TI) ) THEN + IF ( .NOT. ALLOCATED(InData%IDL_L) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiRb_TI,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiRb_TI,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiRb_TI,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiRb_TI,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%IDL_L,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IDL_L,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%PhiRb_TI,2), UBOUND(InData%PhiRb_TI,2) - DO i1 = LBOUND(InData%PhiRb_TI,1), UBOUND(InData%PhiRb_TI,1) - ReKiBuf(Re_Xferred) = InData%PhiRb_TI(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(InData%IDL_L,1), UBOUND(InData%IDL_L,1) + IntKiBuf(Int_Xferred) = InData%IDL_L(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%D2_63) ) THEN + IF ( .NOT. ALLOCATED(InData%IDC__) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D2_63,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D2_63,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D2_63,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D2_63,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%IDC__,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IDC__,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%D2_63,2), UBOUND(InData%D2_63,2) - DO i1 = LBOUND(InData%D2_63,1), UBOUND(InData%D2_63,1) - ReKiBuf(Re_Xferred) = InData%D2_63(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(InData%IDC__,1), UBOUND(InData%IDC__,1) + IntKiBuf(Int_Xferred) = InData%IDC__(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%D2_64) ) THEN + IF ( .NOT. ALLOCATED(InData%IDC_Rb) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D2_64,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D2_64,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%D2_64,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%D2_64,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%IDC_Rb,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IDC_Rb,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%D2_64,2), UBOUND(InData%D2_64,2) - DO i1 = LBOUND(InData%D2_64,1), UBOUND(InData%D2_64,1) - ReKiBuf(Re_Xferred) = InData%D2_64(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(InData%IDC_Rb,1), UBOUND(InData%IDC_Rb,1) + IntKiBuf(Int_Xferred) = InData%IDC_Rb(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%F2_61) ) THEN + IF ( .NOT. ALLOCATED(InData%IDC_L) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%F2_61,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F2_61,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%IDC_L,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IDC_L,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%F2_61,1), UBOUND(InData%F2_61,1) - ReKiBuf(Re_Xferred) = InData%F2_61(i1) - Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%IDC_L,1), UBOUND(InData%IDC_L,1) + IntKiBuf(Int_Xferred) = InData%IDC_L(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%MBB) ) THEN + IF ( .NOT. ALLOCATED(InData%IDC_F) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MBB,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBB,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MBB,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBB,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%IDC_F,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IDC_F,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%MBB,2), UBOUND(InData%MBB,2) - DO i1 = LBOUND(InData%MBB,1), UBOUND(InData%MBB,1) - ReKiBuf(Re_Xferred) = InData%MBB(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(InData%IDC_F,1), UBOUND(InData%IDC_F,1) + IntKiBuf(Int_Xferred) = InData%IDC_F(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%KBB) ) THEN + IF ( .NOT. ALLOCATED(InData%IDR__) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%KBB,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KBB,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%KBB,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KBB,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%IDR__,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IDR__,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%KBB,2), UBOUND(InData%KBB,2) - DO i1 = LBOUND(InData%KBB,1), UBOUND(InData%KBB,1) - ReKiBuf(Re_Xferred) = InData%KBB(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(InData%IDR__,1), UBOUND(InData%IDR__,1) + IntKiBuf(Int_Xferred) = InData%IDR__(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%MBM) ) THEN + IF ( .NOT. ALLOCATED(InData%ID__Rb) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MBM,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBM,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MBM,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MBM,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%ID__Rb,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ID__Rb,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%MBM,2), UBOUND(InData%MBM,2) - DO i1 = LBOUND(InData%MBM,1), UBOUND(InData%MBM,1) - ReKiBuf(Re_Xferred) = InData%MBM(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(InData%ID__Rb,1), UBOUND(InData%ID__Rb,1) + IntKiBuf(Int_Xferred) = InData%ID__Rb(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%PhiL_T) ) THEN + IF ( .NOT. ALLOCATED(InData%ID__L) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiL_T,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiL_T,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiL_T,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiL_T,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%ID__L,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ID__L,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%PhiL_T,2), UBOUND(InData%PhiL_T,2) - DO i1 = LBOUND(InData%PhiL_T,1), UBOUND(InData%PhiL_T,1) - ReKiBuf(Re_Xferred) = InData%PhiL_T(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(InData%ID__L,1), UBOUND(InData%ID__L,1) + IntKiBuf(Int_Xferred) = InData%ID__L(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%PhiLInvOmgL2) ) THEN + IF ( .NOT. ALLOCATED(InData%ID__F) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiLInvOmgL2,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiLInvOmgL2,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PhiLInvOmgL2,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PhiLInvOmgL2,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%ID__F,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ID__F,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%PhiLInvOmgL2,2), UBOUND(InData%PhiLInvOmgL2,2) - DO i1 = LBOUND(InData%PhiLInvOmgL2,1), UBOUND(InData%PhiLInvOmgL2,1) - ReKiBuf(Re_Xferred) = InData%PhiLInvOmgL2(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(InData%ID__F,1), UBOUND(InData%ID__F,1) + IntKiBuf(Int_Xferred) = InData%ID__F(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%FGL) ) THEN + IntKiBuf(Int_Xferred) = InData%NMOutputs + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumOuts + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%OutSwtch + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%UnJckF + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(InData%Delim) + IntKiBuf(Int_Xferred) = ICHAR(InData%Delim(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DO I = 1, LEN(InData%OutFmt) + IntKiBuf(Int_Xferred) = ICHAR(InData%OutFmt(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DO I = 1, LEN(InData%OutSFmt) + IntKiBuf(Int_Xferred) = ICHAR(InData%OutSFmt(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IF ( .NOT. ALLOCATED(InData%MoutLst) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FGL,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FGL,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%MoutLst,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MoutLst,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%FGL,1), UBOUND(InData%FGL,1) - ReKiBuf(Re_Xferred) = InData%FGL(i1) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(InData%MoutLst,1), UBOUND(InData%MoutLst,1) + CALL SD_Packmeshauxdatatype( Re_Buf, Db_Buf, Int_Buf, InData%MoutLst(i1), ErrStat2, ErrMsg2, OnlySize ) ! MoutLst + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO END IF - IF ( .NOT. ALLOCATED(InData%AM2Jac) ) THEN + IF ( .NOT. ALLOCATED(InData%MoutLst2) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%AM2Jac,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AM2Jac,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%AM2Jac,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AM2Jac,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%MoutLst2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MoutLst2,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%AM2Jac,2), UBOUND(InData%AM2Jac,2) - DO i1 = LBOUND(InData%AM2Jac,1), UBOUND(InData%AM2Jac,1) - ReKiBuf(Re_Xferred) = InData%AM2Jac(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + DO i1 = LBOUND(InData%MoutLst2,1), UBOUND(InData%MoutLst2,1) + CALL SD_Packmeshauxdatatype( Re_Buf, Db_Buf, Int_Buf, InData%MoutLst2(i1), ErrStat2, ErrMsg2, OnlySize ) ! MoutLst2 + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO END IF - IF ( .NOT. ALLOCATED(InData%AM2JacPiv) ) THEN + IF ( .NOT. ALLOCATED(InData%MoutLst3) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%AM2JacPiv,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AM2JacPiv,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%MoutLst3,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MoutLst3,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%AM2JacPiv,1), UBOUND(InData%AM2JacPiv,1) - IntKiBuf(Int_Xferred) = InData%AM2JacPiv(i1) - Int_Xferred = Int_Xferred + 1 - END DO + DO i1 = LBOUND(InData%MoutLst3,1), UBOUND(InData%MoutLst3,1) + CALL SD_Packmeshauxdatatype( Re_Buf, Db_Buf, Int_Buf, InData%MoutLst3(i1), ErrStat2, ErrMsg2, OnlySize ) ! MoutLst3 + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO END IF - IF ( .NOT. ALLOCATED(InData%TI) ) THEN + IF ( .NOT. ALLOCATED(InData%OutParam) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TI,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TI,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TI,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TI,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%OutParam,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%OutParam,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%TI,2), UBOUND(InData%TI,2) - DO i1 = LBOUND(InData%TI,1), UBOUND(InData%TI,1) - ReKiBuf(Re_Xferred) = InData%TI(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + DO i1 = LBOUND(InData%OutParam,1), UBOUND(InData%OutParam,1) + CALL NWTC_Library_Packoutparmtype( Re_Buf, Db_Buf, Int_Buf, InData%OutParam(i1), ErrStat2, ErrMsg2, OnlySize ) ! OutParam + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO END IF - IF ( .NOT. ALLOCATED(InData%TIreact) ) THEN + IntKiBuf(Int_Xferred) = TRANSFER(InData%OutAll, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%OutReact, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%OutAllInt + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%OutAllDims + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%OutDec + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%Jac_u_indx) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TIreact,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TIreact,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Jac_u_indx,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Jac_u_indx,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TIreact,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TIreact,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Jac_u_indx,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Jac_u_indx,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%TIreact,2), UBOUND(InData%TIreact,2) - DO i1 = LBOUND(InData%TIreact,1), UBOUND(InData%TIreact,1) - ReKiBuf(Re_Xferred) = InData%TIreact(i1,i2) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(InData%Jac_u_indx,2), UBOUND(InData%Jac_u_indx,2) + DO i1 = LBOUND(InData%Jac_u_indx,1), UBOUND(InData%Jac_u_indx,1) + IntKiBuf(Int_Xferred) = InData%Jac_u_indx(i1,i2) + Int_Xferred = Int_Xferred + 1 END DO END DO END IF - IntKiBuf(Int_Xferred) = InData%NModes - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%Elems) ) THEN + IF ( .NOT. ALLOCATED(InData%du) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Elems,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Elems,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Elems,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Elems,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%du,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%du,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%Elems,2), UBOUND(InData%Elems,2) - DO i1 = LBOUND(InData%Elems,1), UBOUND(InData%Elems,1) - IntKiBuf(Int_Xferred) = InData%Elems(i1,i2) - Int_Xferred = Int_Xferred + 1 - END DO + DO i1 = LBOUND(InData%du,1), UBOUND(InData%du,1) + DbKiBuf(Db_Xferred) = InData%du(i1) + Db_Xferred = Db_Xferred + 1 END DO END IF - IntKiBuf(Int_Xferred) = InData%qmL + DO i1 = LBOUND(InData%dx,1), UBOUND(InData%dx,1) + DbKiBuf(Db_Xferred) = InData%dx(i1) + Db_Xferred = Db_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%Jac_ny Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%DofL + IntKiBuf(Int_Xferred) = InData%Jac_nx Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NNodes_I + IntKiBuf(Int_Xferred) = TRANSFER(InData%RotStates, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NNodes_L + END SUBROUTINE SD_PackParam + + SUBROUTINE SD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(SD_ParameterType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackParam' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%SDDeltaT = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%IntMethod = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NNodes_RbarL + OutData%nDOF = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%DofI + OutData%nDOF_red = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%DofR + OutData%Nmembers = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%DofC + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Elems not allocated Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NReact + ELSE Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%Reacts) ) THEN - IntKiBuf( Int_Xferred ) = 0 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Elems)) DEALLOCATE(OutData%Elems) + ALLOCATE(OutData%Elems(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Elems.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Elems,2), UBOUND(OutData%Elems,2) + DO i1 = LBOUND(OutData%Elems,1), UBOUND(OutData%Elems,1) + OutData%Elems(i1,i2) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ElemProps not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Reacts,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Reacts,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Reacts,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Reacts,2) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ElemProps)) DEALLOCATE(OutData%ElemProps) + ALLOCATE(OutData%ElemProps(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ElemProps.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ElemProps,1), UBOUND(OutData%ElemProps,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL SD_Unpackelemproptype( Re_Buf, Db_Buf, Int_Buf, OutData%ElemProps(i1), ErrStat2, ErrMsg2 ) ! ElemProps + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN - DO i2 = LBOUND(InData%Reacts,2), UBOUND(InData%Reacts,2) - DO i1 = LBOUND(InData%Reacts,1), UBOUND(InData%Reacts,1) - IntKiBuf(Int_Xferred) = InData%Reacts(i1,i2) - Int_Xferred = Int_Xferred + 1 - END DO - END DO + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO END IF - IntKiBuf(Int_Xferred) = InData%Nmembers - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%URbarL - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%IntMethod - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NAvgEls - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%IDI) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FG not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%IDI,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IDI,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%IDI,1), UBOUND(InData%IDI,1) - IntKiBuf(Int_Xferred) = InData%IDI(i1) - Int_Xferred = Int_Xferred + 1 + IF (ALLOCATED(OutData%FG)) DEALLOCATE(OutData%FG) + ALLOCATE(OutData%FG(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FG.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%FG,1), UBOUND(OutData%FG,1) + OutData%FG(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%IDR) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! DP0 not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%IDR,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IDR,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%IDR,1), UBOUND(InData%IDR,1) - IntKiBuf(Int_Xferred) = InData%IDR(i1) - Int_Xferred = Int_Xferred + 1 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%DP0)) DEALLOCATE(OutData%DP0) + ALLOCATE(OutData%DP0(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%DP0.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%DP0,2), UBOUND(OutData%DP0,2) + DO i1 = LBOUND(OutData%DP0,1), UBOUND(OutData%DP0,1) + OutData%DP0(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%IDL) ) THEN - IntKiBuf( Int_Xferred ) = 0 + OutData%reduced = TRANSFER(IntKiBuf(Int_Xferred), OutData%reduced) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! T_red not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%IDL,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IDL,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%IDL,1), UBOUND(InData%IDL,1) - IntKiBuf(Int_Xferred) = InData%IDL(i1) - Int_Xferred = Int_Xferred + 1 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%T_red)) DEALLOCATE(OutData%T_red) + ALLOCATE(OutData%T_red(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%T_red.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%T_red,2), UBOUND(OutData%T_red,2) + DO i1 = LBOUND(OutData%T_red,1), UBOUND(OutData%T_red,1) + OutData%T_red(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%IDC) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! T_red_T not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%IDC,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IDC,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%IDC,1), UBOUND(InData%IDC,1) - IntKiBuf(Int_Xferred) = InData%IDC(i1) - Int_Xferred = Int_Xferred + 1 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%T_red_T)) DEALLOCATE(OutData%T_red_T) + ALLOCATE(OutData%T_red_T(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%T_red_T.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%T_red_T,2), UBOUND(OutData%T_red_T,2) + DO i1 = LBOUND(OutData%T_red_T,1), UBOUND(OutData%T_red_T,1) + OutData%T_red_T(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%IDY) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NodesDOF not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%IDY,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IDY,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%IDY,1), UBOUND(InData%IDY,1) - IntKiBuf(Int_Xferred) = InData%IDY(i1) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - IntKiBuf(Int_Xferred) = InData%NMOutputs - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NumOuts - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%OutSwtch - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%UnJckF - Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(InData%Delim) - IntKiBuf(Int_Xferred) = ICHAR(InData%Delim(I:I), IntKi) + IF (ALLOCATED(OutData%NodesDOF)) DEALLOCATE(OutData%NodesDOF) + ALLOCATE(OutData%NodesDOF(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%NodesDOF.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%NodesDOF,1), UBOUND(OutData%NodesDOF,1) + Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 - END DO ! I - DO I = 1, LEN(InData%OutFmt) - IntKiBuf(Int_Xferred) = ICHAR(InData%OutFmt(I:I), IntKi) + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 - END DO ! I - DO I = 1, LEN(InData%OutSFmt) - IntKiBuf(Int_Xferred) = ICHAR(InData%OutSFmt(I:I), IntKi) + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 - END DO ! I - IF ( .NOT. ALLOCATED(InData%MoutLst) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MoutLst,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MoutLst,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%MoutLst,1), UBOUND(InData%MoutLst,1) - CALL SD_Packmeshauxdatatype( Re_Buf, Db_Buf, Int_Buf, InData%MoutLst(i1), ErrStat2, ErrMsg2, OnlySize ) ! MoutLst - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END DO - END IF - IF ( .NOT. ALLOCATED(InData%MoutLst2) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MoutLst2,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MoutLst2,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%MoutLst2,1), UBOUND(InData%MoutLst2,1) - CALL SD_Packmeshauxdatatype( Re_Buf, Db_Buf, Int_Buf, InData%MoutLst2(i1), ErrStat2, ErrMsg2, OnlySize ) ! MoutLst2 - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END DO - END IF - IF ( .NOT. ALLOCATED(InData%MoutLst3) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MoutLst3,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MoutLst3,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%MoutLst3,1), UBOUND(InData%MoutLst3,1) - CALL SD_Packmeshauxdatatype( Re_Buf, Db_Buf, Int_Buf, InData%MoutLst3(i1), ErrStat2, ErrMsg2, OnlySize ) ! MoutLst3 - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL SD_Unpackilist( Re_Buf, Db_Buf, Int_Buf, OutData%NodesDOF(i1), ErrStat2, ErrMsg2 ) ! NodesDOF + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( .NOT. ALLOCATED(InData%ElemProps) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NodesDOFred not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%ElemProps,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ElemProps,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%ElemProps,1), UBOUND(InData%ElemProps,1) - CALL SD_Packelemproptype( Re_Buf, Db_Buf, Int_Buf, InData%ElemProps(i1), ErrStat2, ErrMsg2, OnlySize ) ! ElemProps + IF (ALLOCATED(OutData%NodesDOFred)) DEALLOCATE(OutData%NodesDOFred) + ALLOCATE(OutData%NodesDOFred(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%NodesDOFred.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%NodesDOFred,1), UBOUND(OutData%NodesDOFred,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL SD_Unpackilist( Re_Buf, Db_Buf, Int_Buf, OutData%NodesDOFred(i1), ErrStat2, ErrMsg2 ) ! NodesDOFred CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( .NOT. ALLOCATED(InData%OutParam) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ElemsDOF not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%OutParam,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%OutParam,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%OutParam,1), UBOUND(InData%OutParam,1) - CALL NWTC_Library_Packoutparmtype( Re_Buf, Db_Buf, Int_Buf, InData%OutParam(i1), ErrStat2, ErrMsg2, OnlySize ) ! OutParam - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END DO + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ElemsDOF)) DEALLOCATE(OutData%ElemsDOF) + ALLOCATE(OutData%ElemsDOF(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ElemsDOF.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%ElemsDOF,2), UBOUND(OutData%ElemsDOF,2) + DO i1 = LBOUND(OutData%ElemsDOF,1), UBOUND(OutData%ElemsDOF,1) + OutData%ElemsDOF(i1,i2) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END DO END IF - IntKiBuf(Int_Xferred) = TRANSFER(InData%OutAll, IntKiBuf(1)) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! DOFred2Nodes not allocated Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%OutReact, IntKiBuf(1)) + ELSE Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%OutAllInt + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%DOFred2Nodes)) DEALLOCATE(OutData%DOFred2Nodes) + ALLOCATE(OutData%DOFred2Nodes(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%DOFred2Nodes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%DOFred2Nodes,2), UBOUND(OutData%DOFred2Nodes,2) + DO i1 = LBOUND(OutData%DOFred2Nodes,1), UBOUND(OutData%DOFred2Nodes,1) + OutData%DOFred2Nodes(i1,i2) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CtrlElem2Channel not allocated Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%OutAllDims + ELSE Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%OutDec + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%CtrlElem2Channel)) DEALLOCATE(OutData%CtrlElem2Channel) + ALLOCATE(OutData%CtrlElem2Channel(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CtrlElem2Channel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%CtrlElem2Channel,2), UBOUND(OutData%CtrlElem2Channel,2) + DO i1 = LBOUND(OutData%CtrlElem2Channel,1), UBOUND(OutData%CtrlElem2Channel,1) + OutData%CtrlElem2Channel(i1,i2) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + OutData%nDOFM = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - END SUBROUTINE SD_PackParam - - SUBROUTINE SD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(SD_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackParam' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%SDDeltaT = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 - OutData%SttcSolve = TRANSFER(IntKiBuf(Int_Xferred), OutData%SttcSolve) + OutData%SttcSolve = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%GuyanLoadCorrection = TRANSFER(IntKiBuf(Int_Xferred), OutData%GuyanLoadCorrection) Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NOmegaM2 not allocated + OutData%Floating = TRANSFER(IntKiBuf(Int_Xferred), OutData%Floating) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! KMMDiag not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%NOmegaM2)) DEALLOCATE(OutData%NOmegaM2) - ALLOCATE(OutData%NOmegaM2(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%KMMDiag)) DEALLOCATE(OutData%KMMDiag) + ALLOCATE(OutData%KMMDiag(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%NOmegaM2.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%KMMDiag.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%NOmegaM2,1), UBOUND(OutData%NOmegaM2,1) - OutData%NOmegaM2(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%KMMDiag,1), UBOUND(OutData%KMMDiag,1) + OutData%KMMDiag(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! N2OmegaMJDamp not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CMMDiag not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%N2OmegaMJDamp)) DEALLOCATE(OutData%N2OmegaMJDamp) - ALLOCATE(OutData%N2OmegaMJDamp(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%CMMDiag)) DEALLOCATE(OutData%CMMDiag) + ALLOCATE(OutData%CMMDiag(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%N2OmegaMJDamp.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CMMDiag.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%N2OmegaMJDamp,1), UBOUND(OutData%N2OmegaMJDamp,1) - OutData%N2OmegaMJDamp(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%CMMDiag,1), UBOUND(OutData%CMMDiag,1) + OutData%CMMDiag(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF @@ -7522,22 +10254,27 @@ SUBROUTINE SD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FX not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MBmmB not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%FX)) DEALLOCATE(OutData%FX) - ALLOCATE(OutData%FX(i1_l:i1_u),STAT=ErrStat2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MBmmB)) DEALLOCATE(OutData%MBmmB) + ALLOCATE(OutData%MBmmB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FX.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MBmmB.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%FX,1), UBOUND(OutData%FX,1) - OutData%FX(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(OutData%MBmmB,2), UBOUND(OutData%MBmmB,2) + DO i1 = LBOUND(OutData%MBmmB,1), UBOUND(OutData%MBmmB,1) + OutData%MBmmB(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! C1_11 not allocated @@ -7586,7 +10323,7 @@ SUBROUTINE SD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D1_13 not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D1_141 not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -7596,20 +10333,20 @@ SUBROUTINE SD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D1_13)) DEALLOCATE(OutData%D1_13) - ALLOCATE(OutData%D1_13(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%D1_141)) DEALLOCATE(OutData%D1_141) + ALLOCATE(OutData%D1_141(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D1_13.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D1_141.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%D1_13,2), UBOUND(OutData%D1_13,2) - DO i1 = LBOUND(OutData%D1_13,1), UBOUND(OutData%D1_13,1) - OutData%D1_13(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%D1_141,2), UBOUND(OutData%D1_141,2) + DO i1 = LBOUND(OutData%D1_141,1), UBOUND(OutData%D1_141,1) + OutData%D1_141(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D1_14 not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D1_142 not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -7619,37 +10356,19 @@ SUBROUTINE SD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%D1_14)) DEALLOCATE(OutData%D1_14) - ALLOCATE(OutData%D1_14(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%D1_142)) DEALLOCATE(OutData%D1_142) + ALLOCATE(OutData%D1_142(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D1_14.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%D1_142.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%D1_14,2), UBOUND(OutData%D1_14,2) - DO i1 = LBOUND(OutData%D1_14,1), UBOUND(OutData%D1_14,1) - OutData%D1_14(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%D1_142,2), UBOUND(OutData%D1_142,2) + DO i1 = LBOUND(OutData%D1_142,1), UBOUND(OutData%D1_142,1) + OutData%D1_142(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FY not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%FY)) DEALLOCATE(OutData%FY) - ALLOCATE(OutData%FY(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FY.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%FY,1), UBOUND(OutData%FY,1) - OutData%FY(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PhiM not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -7788,25 +10507,30 @@ SUBROUTINE SD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F2_61 not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MBB not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%F2_61)) DEALLOCATE(OutData%F2_61) - ALLOCATE(OutData%F2_61(i1_l:i1_u),STAT=ErrStat2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MBB)) DEALLOCATE(OutData%MBB) + ALLOCATE(OutData%MBB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F2_61.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MBB.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%F2_61,1), UBOUND(OutData%F2_61,1) - OutData%F2_61(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(OutData%MBB,2), UBOUND(OutData%MBB,2) + DO i1 = LBOUND(OutData%MBB,1), UBOUND(OutData%MBB,1) + OutData%MBB(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MBB not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! KBB not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -7816,20 +10540,20 @@ SUBROUTINE SD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%MBB)) DEALLOCATE(OutData%MBB) - ALLOCATE(OutData%MBB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%KBB)) DEALLOCATE(OutData%KBB) + ALLOCATE(OutData%KBB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MBB.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%KBB.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%MBB,2), UBOUND(OutData%MBB,2) - DO i1 = LBOUND(OutData%MBB,1), UBOUND(OutData%MBB,1) - OutData%MBB(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%KBB,2), UBOUND(OutData%KBB,2) + DO i1 = LBOUND(OutData%KBB,1), UBOUND(OutData%KBB,1) + OutData%KBB(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! KBB not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CBB not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -7839,15 +10563,38 @@ SUBROUTINE SD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%KBB)) DEALLOCATE(OutData%KBB) - ALLOCATE(OutData%KBB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%CBB)) DEALLOCATE(OutData%CBB) + ALLOCATE(OutData%CBB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CBB.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%CBB,2), UBOUND(OutData%CBB,2) + DO i1 = LBOUND(OutData%CBB,1), UBOUND(OutData%CBB,1) + OutData%CBB(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CMM not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%CMM)) DEALLOCATE(OutData%CMM) + ALLOCATE(OutData%CMM(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%KBB.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CMM.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%KBB,2), UBOUND(OutData%KBB,2) - DO i1 = LBOUND(OutData%KBB,1), UBOUND(OutData%KBB,1) - OutData%KBB(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%CMM,2), UBOUND(OutData%CMM,2) + DO i1 = LBOUND(OutData%CMM,1), UBOUND(OutData%CMM,1) + OutData%CMM(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO @@ -7921,22 +10668,27 @@ SUBROUTINE SD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FGL not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! KLLm1 not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%FGL)) DEALLOCATE(OutData%FGL) - ALLOCATE(OutData%FGL(i1_l:i1_u),STAT=ErrStat2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%KLLm1)) DEALLOCATE(OutData%KLLm1) + ALLOCATE(OutData%KLLm1(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FGL.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%KLLm1.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%FGL,1), UBOUND(OutData%FGL,1) - OutData%FGL(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(OutData%KLLm1,2), UBOUND(OutData%KLLm1,2) + DO i1 = LBOUND(OutData%KLLm1,1), UBOUND(OutData%KLLm1,1) + OutData%KLLm1(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AM2Jac not allocated @@ -8026,9 +10778,15 @@ SUBROUTINE SD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF - OutData%NModes = IntKiBuf(Int_Xferred) + OutData%nNodes = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Elems not allocated + OutData%nNodes_I = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nNodes_L = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nNodes_C = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Nodes_I not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -8038,155 +10796,302 @@ SUBROUTINE SD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Elems)) DEALLOCATE(OutData%Elems) - ALLOCATE(OutData%Elems(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Nodes_I)) DEALLOCATE(OutData%Nodes_I) + ALLOCATE(OutData%Nodes_I(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Elems.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Nodes_I.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%Elems,2), UBOUND(OutData%Elems,2) - DO i1 = LBOUND(OutData%Elems,1), UBOUND(OutData%Elems,1) - OutData%Elems(i1,i2) = IntKiBuf(Int_Xferred) + DO i2 = LBOUND(OutData%Nodes_I,2), UBOUND(OutData%Nodes_I,2) + DO i1 = LBOUND(OutData%Nodes_I,1), UBOUND(OutData%Nodes_I,1) + OutData%Nodes_I(i1,i2) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Nodes_L not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Nodes_L)) DEALLOCATE(OutData%Nodes_L) + ALLOCATE(OutData%Nodes_L(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Nodes_L.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Nodes_L,2), UBOUND(OutData%Nodes_L,2) + DO i1 = LBOUND(OutData%Nodes_L,1), UBOUND(OutData%Nodes_L,1) + OutData%Nodes_L(i1,i2) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Nodes_C not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Nodes_C)) DEALLOCATE(OutData%Nodes_C) + ALLOCATE(OutData%Nodes_C(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Nodes_C.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Nodes_C,2), UBOUND(OutData%Nodes_C,2) + DO i1 = LBOUND(OutData%Nodes_C,1), UBOUND(OutData%Nodes_C,1) + OutData%Nodes_C(i1,i2) = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 END DO END DO END IF - OutData%qmL = IntKiBuf(Int_Xferred) + OutData%nDOFI__ = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nDOFI_Rb = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nDOFI_F = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nDOFL_L = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%DofL = IntKiBuf(Int_Xferred) + OutData%nDOFC__ = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%NNodes_I = IntKiBuf(Int_Xferred) + OutData%nDOFC_Rb = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%NNodes_L = IntKiBuf(Int_Xferred) + OutData%nDOFC_L = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%NNodes_RbarL = IntKiBuf(Int_Xferred) + OutData%nDOFC_F = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%DofI = IntKiBuf(Int_Xferred) + OutData%nDOFR__ = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%DofR = IntKiBuf(Int_Xferred) + OutData%nDOF__Rb = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%DofC = IntKiBuf(Int_Xferred) + OutData%nDOF__L = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%NReact = IntKiBuf(Int_Xferred) + OutData%nDOF__F = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Reacts not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IDI__ not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) + IF (ALLOCATED(OutData%IDI__)) DEALLOCATE(OutData%IDI__) + ALLOCATE(OutData%IDI__(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IDI__.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%IDI__,1), UBOUND(OutData%IDI__,1) + OutData%IDI__(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IDI_Rb not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Reacts)) DEALLOCATE(OutData%Reacts) - ALLOCATE(OutData%Reacts(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%IDI_Rb)) DEALLOCATE(OutData%IDI_Rb) + ALLOCATE(OutData%IDI_Rb(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Reacts.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IDI_Rb.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%Reacts,2), UBOUND(OutData%Reacts,2) - DO i1 = LBOUND(OutData%Reacts,1), UBOUND(OutData%Reacts,1) - OutData%Reacts(i1,i2) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO + DO i1 = LBOUND(OutData%IDI_Rb,1), UBOUND(OutData%IDI_Rb,1) + OutData%IDI_Rb(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 END DO END IF - OutData%Nmembers = IntKiBuf(Int_Xferred) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IDI_F not allocated Int_Xferred = Int_Xferred + 1 - OutData%URbarL = IntKiBuf(Int_Xferred) + ELSE Int_Xferred = Int_Xferred + 1 - OutData%IntMethod = IntKiBuf(Int_Xferred) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%IDI_F)) DEALLOCATE(OutData%IDI_F) + ALLOCATE(OutData%IDI_F(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IDI_F.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%IDI_F,1), UBOUND(OutData%IDI_F,1) + OutData%IDI_F(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IDL_L not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%IDL_L)) DEALLOCATE(OutData%IDL_L) + ALLOCATE(OutData%IDL_L(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IDL_L.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%IDL_L,1), UBOUND(OutData%IDL_L,1) + OutData%IDL_L(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IDC__ not allocated Int_Xferred = Int_Xferred + 1 - OutData%NAvgEls = IntKiBuf(Int_Xferred) + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%IDC__)) DEALLOCATE(OutData%IDC__) + ALLOCATE(OutData%IDC__(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IDC__.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%IDC__,1), UBOUND(OutData%IDC__,1) + OutData%IDC__(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IDC_Rb not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%IDC_Rb)) DEALLOCATE(OutData%IDC_Rb) + ALLOCATE(OutData%IDC_Rb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IDC_Rb.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%IDC_Rb,1), UBOUND(OutData%IDC_Rb,1) + OutData%IDC_Rb(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IDC_L not allocated + Int_Xferred = Int_Xferred + 1 + ELSE Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IDI not allocated + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%IDC_L)) DEALLOCATE(OutData%IDC_L) + ALLOCATE(OutData%IDC_L(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IDC_L.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%IDC_L,1), UBOUND(OutData%IDC_L,1) + OutData%IDC_L(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IDC_F not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%IDI)) DEALLOCATE(OutData%IDI) - ALLOCATE(OutData%IDI(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%IDC_F)) DEALLOCATE(OutData%IDC_F) + ALLOCATE(OutData%IDC_F(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IDI.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IDC_F.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%IDI,1), UBOUND(OutData%IDI,1) - OutData%IDI(i1) = IntKiBuf(Int_Xferred) + DO i1 = LBOUND(OutData%IDC_F,1), UBOUND(OutData%IDC_F,1) + OutData%IDC_F(i1) = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IDR not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IDR__ not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%IDR)) DEALLOCATE(OutData%IDR) - ALLOCATE(OutData%IDR(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%IDR__)) DEALLOCATE(OutData%IDR__) + ALLOCATE(OutData%IDR__(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IDR.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IDR__.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%IDR,1), UBOUND(OutData%IDR,1) - OutData%IDR(i1) = IntKiBuf(Int_Xferred) + DO i1 = LBOUND(OutData%IDR__,1), UBOUND(OutData%IDR__,1) + OutData%IDR__(i1) = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IDL not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ID__Rb not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%IDL)) DEALLOCATE(OutData%IDL) - ALLOCATE(OutData%IDL(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%ID__Rb)) DEALLOCATE(OutData%ID__Rb) + ALLOCATE(OutData%ID__Rb(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IDL.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ID__Rb.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%IDL,1), UBOUND(OutData%IDL,1) - OutData%IDL(i1) = IntKiBuf(Int_Xferred) + DO i1 = LBOUND(OutData%ID__Rb,1), UBOUND(OutData%ID__Rb,1) + OutData%ID__Rb(i1) = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IDC not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ID__L not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%IDC)) DEALLOCATE(OutData%IDC) - ALLOCATE(OutData%IDC(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%ID__L)) DEALLOCATE(OutData%ID__L) + ALLOCATE(OutData%ID__L(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IDC.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ID__L.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%IDC,1), UBOUND(OutData%IDC,1) - OutData%IDC(i1) = IntKiBuf(Int_Xferred) + DO i1 = LBOUND(OutData%ID__L,1), UBOUND(OutData%ID__L,1) + OutData%ID__L(i1) = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IDY not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ID__F not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%IDY)) DEALLOCATE(OutData%IDY) - ALLOCATE(OutData%IDY(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%ID__F)) DEALLOCATE(OutData%ID__F) + ALLOCATE(OutData%ID__F(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IDY.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ID__F.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%IDY,1), UBOUND(OutData%IDY,1) - OutData%IDY(i1) = IntKiBuf(Int_Xferred) + DO i1 = LBOUND(OutData%ID__F,1), UBOUND(OutData%ID__F,1) + OutData%ID__F(i1) = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 END DO END IF @@ -8378,62 +11283,6 @@ SUBROUTINE SD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ElemProps not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%ElemProps)) DEALLOCATE(OutData%ElemProps) - ALLOCATE(OutData%ElemProps(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ElemProps.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%ElemProps,1), UBOUND(OutData%ElemProps,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL SD_Unpackelemproptype( Re_Buf, Db_Buf, Int_Buf, OutData%ElemProps(i1), ErrStat2, ErrMsg2 ) ! ElemProps - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OutParam not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -8500,6 +11349,59 @@ SUBROUTINE SD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Int_Xferred = Int_Xferred + 1 OutData%OutDec = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Jac_u_indx not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Jac_u_indx)) DEALLOCATE(OutData%Jac_u_indx) + ALLOCATE(OutData%Jac_u_indx(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Jac_u_indx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Jac_u_indx,2), UBOUND(OutData%Jac_u_indx,2) + DO i1 = LBOUND(OutData%Jac_u_indx,1), UBOUND(OutData%Jac_u_indx,1) + OutData%Jac_u_indx(i1,i2) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! du not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%du)) DEALLOCATE(OutData%du) + ALLOCATE(OutData%du(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%du.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%du,1), UBOUND(OutData%du,1) + OutData%du(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + i1_l = LBOUND(OutData%dx,1) + i1_u = UBOUND(OutData%dx,1) + DO i1 = LBOUND(OutData%dx,1), UBOUND(OutData%dx,1) + OutData%dx(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + OutData%Jac_ny = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%Jac_nx = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%RotStates = TRANSFER(IntKiBuf(Int_Xferred), OutData%RotStates) + Int_Xferred = Int_Xferred + 1 END SUBROUTINE SD_UnPackParam SUBROUTINE SD_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) @@ -8510,6 +11412,7 @@ SUBROUTINE SD_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'SD_CopyInput' @@ -8522,6 +11425,18 @@ SUBROUTINE SD_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) CALL MeshCopy( SrcInputData%LMesh, DstInputData%LMesh, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcInputData%CableDeltaL)) THEN + i1_l = LBOUND(SrcInputData%CableDeltaL,1) + i1_u = UBOUND(SrcInputData%CableDeltaL,1) + IF (.NOT. ALLOCATED(DstInputData%CableDeltaL)) THEN + ALLOCATE(DstInputData%CableDeltaL(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%CableDeltaL.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputData%CableDeltaL = SrcInputData%CableDeltaL +ENDIF END SUBROUTINE SD_CopyInput SUBROUTINE SD_DestroyInput( InputData, ErrStat, ErrMsg ) @@ -8535,6 +11450,9 @@ SUBROUTINE SD_DestroyInput( InputData, ErrStat, ErrMsg ) ErrMsg = "" CALL MeshDestroy( InputData%TPMesh, ErrStat, ErrMsg ) CALL MeshDestroy( InputData%LMesh, ErrStat, ErrMsg ) +IF (ALLOCATED(InputData%CableDeltaL)) THEN + DEALLOCATE(InputData%CableDeltaL) +ENDIF END SUBROUTINE SD_DestroyInput SUBROUTINE SD_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -8607,6 +11525,11 @@ SUBROUTINE SD_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 1 ! CableDeltaL allocated yes/no + IF ( ALLOCATED(InData%CableDeltaL) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! CableDeltaL upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%CableDeltaL) ! CableDeltaL + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -8690,6 +11613,21 @@ SUBROUTINE SD_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + IF ( .NOT. ALLOCATED(InData%CableDeltaL) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CableDeltaL,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CableDeltaL,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%CableDeltaL,1), UBOUND(InData%CableDeltaL,1) + ReKiBuf(Re_Xferred) = InData%CableDeltaL(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE SD_PackInput SUBROUTINE SD_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -8705,6 +11643,7 @@ SUBROUTINE SD_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg INTEGER(IntKi) :: Db_Xferred INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'SD_UnPackInput' @@ -8798,6 +11737,24 @@ SUBROUTINE SD_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CableDeltaL not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%CableDeltaL)) DEALLOCATE(OutData%CableDeltaL) + ALLOCATE(OutData%CableDeltaL(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CableDeltaL.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%CableDeltaL,1), UBOUND(OutData%CableDeltaL,1) + OutData%CableDeltaL(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE SD_UnPackInput SUBROUTINE SD_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -9232,6 +12189,8 @@ SUBROUTINE SD_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg ) REAL(DbKi) :: ScaleFactor ! temporary for extrapolation/interpolation INTEGER(IntKi) :: ErrStat2 ! local errors CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors + INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts + INTEGER :: i1 ! dim1 counter variable for arrays ! Initialize ErrStat ErrStat = ErrID_None ErrMsg = "" @@ -9250,6 +12209,12 @@ SUBROUTINE SD_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) CALL MeshExtrapInterp1(u1%LMesh, u2%LMesh, tin, u_out%LMesh, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) +IF (ALLOCATED(u_out%CableDeltaL) .AND. ALLOCATED(u1%CableDeltaL)) THEN + DO i1 = LBOUND(u_out%CableDeltaL,1),UBOUND(u_out%CableDeltaL,1) + b = -(u1%CableDeltaL(i1) - u2%CableDeltaL(i1)) + u_out%CableDeltaL(i1) = u1%CableDeltaL(i1) + b * ScaleFactor + END DO +END IF ! check if allocated END SUBROUTINE SD_Input_ExtrapInterp1 @@ -9285,6 +12250,8 @@ SUBROUTINE SD_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, ErrM INTEGER(IntKi) :: ErrStat2 ! local errors CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors CHARACTER(*), PARAMETER :: RoutineName = 'SD_Input_ExtrapInterp2' + INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts + INTEGER :: i1 ! dim1 counter variable for arrays ! Initialize ErrStat ErrStat = ErrID_None ErrMsg = "" @@ -9309,6 +12276,13 @@ SUBROUTINE SD_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, ErrM CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) CALL MeshExtrapInterp2(u1%LMesh, u2%LMesh, u3%LMesh, tin, u_out%LMesh, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) +IF (ALLOCATED(u_out%CableDeltaL) .AND. ALLOCATED(u1%CableDeltaL)) THEN + DO i1 = LBOUND(u_out%CableDeltaL,1),UBOUND(u_out%CableDeltaL,1) + b = (t(3)**2*(u1%CableDeltaL(i1) - u2%CableDeltaL(i1)) + t(2)**2*(-u1%CableDeltaL(i1) + u3%CableDeltaL(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%CableDeltaL(i1) + t(3)*u2%CableDeltaL(i1) - t(2)*u3%CableDeltaL(i1) ) * scaleFactor + u_out%CableDeltaL(i1) = u1%CableDeltaL(i1) + b + c * t_out + END DO +END IF ! check if allocated END SUBROUTINE SD_Input_ExtrapInterp2 diff --git a/modules/subdyn/src/Yaml.f90 b/modules/subdyn/src/Yaml.f90 new file mode 100644 index 0000000000..ec3043c23c --- /dev/null +++ b/modules/subdyn/src/Yaml.f90 @@ -0,0 +1,609 @@ +!.................................................................................................................................. +! LICENSING +! Copyright (C) 2013-2016 National Renewable Energy Laboratory +! +! This file is part of SubDyn. +! +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at +! +! http://www.apache.org/licenses/LICENSE-2.0 +! +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. +! +!********************************************************************************************************************************** +module YAML + use NWTC_Library + + implicit none + + integer(IntKi), parameter :: INDENT_SPACES = 2 + + !> Write 1D or 2D array to file + interface yaml_write_array + module procedure yaml_write_array1I ! Single dimension array (Ary) of IntKi + module procedure yaml_write_array1R4 ! Single dimension array (Ary) of SiKi + module procedure yaml_write_array2R4 ! Two dimension array of SiKi + module procedure yaml_write_array1R8 ! Single dimension array (Ary) of R8Ki + module procedure yaml_write_array2R8 ! Two dimension array of R8Ki + module procedure yaml_write_array2I ! Two dimension array of IntKi + module procedure yaml_write_array1R16 ! Single dimension array (Ary) of QuKi + module procedure yaml_write_array2R16 ! Two dimension array of QuKi + end interface + + !> Write variable to file + interface yaml_write_var + module procedure yaml_write_varC ! Character + module procedure yaml_write_varI ! IntKi + module procedure yaml_write_varR4 ! SiKi + module procedure yaml_write_varR8 ! R8Ki + module procedure yaml_write_varR16 ! QuKi + end interface + private + + public :: yaml_write_var + public :: yaml_write_array + +contains + +! -------------------------------------------------------------------------------- +! --- Write variable +! -------------------------------------------------------------------------------- +!> Write simple key/variable to yaml file +subroutine yaml_write_varC(fid, key, val, VarFmt, ErrStat, ErrMsg, level, comment) + integer(IntKi), intent(in ) :: fid !< File Unit + character(len=*), intent(in ) :: key !< Variable name + character(len=*), intent(in ) :: val !< Value + character(len=*), intent(in ) :: VarFmt !< Format for printing real numbers + integer, intent( out) :: ErrStat !< A non-zero value indicates an error occurred + character(len=*), intent( out) :: ErrMsg !< Error message if errstat /= errid_none + integer(IntKi), optional, intent(in ) :: level !< indentation level + character(len=*), optional, intent(in ) :: comment !< + character(256) :: Fmt + ErrStat = ErrID_None + ErrMsg = "" + Fmt = '' + if (present(level)) Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' + if (present(comment)) then + Fmt = '('//trim(Fmt)//'A,": ",'//trim(VarFmt)//', " # ",A)' + write(fid, Fmt, iostat=ErrStat) key, val, comment + else + Fmt = '('//trim(Fmt)//'A,": ",'//trim(VarFmt)//')' + write(fid, Fmt, iostat=ErrStat) key, val + endif + if (ErrStat /= 0) then + ErrMsg='Error writting variable '//trim(key)//' to YAML file' + return + endif +end subroutine yaml_write_varC + +subroutine yaml_write_varI(fid, key, val, VarFmt, ErrStat, ErrMsg, level, comment) + integer(IntKi), intent(in ) :: fid !< File Unit + character(len=*), intent(in ) :: key !< Variable name + integer(IntKi), intent(in ) :: val !< Value + character(len=*), intent(in ) :: VarFmt !< Format for printing real numbers + integer, intent( out) :: ErrStat !< A non-zero value indicates an error occurred + character(len=*), intent( out) :: ErrMsg !< Error message if errstat /= errid_none + integer(IntKi), optional, intent(in ) :: level !< indentation level + character(len=*), optional, intent(in ) :: comment !< + character(256) :: Fmt + ErrStat = ErrID_None + ErrMsg = "" + Fmt = '' + if (present(level)) Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' + if (present(comment)) then + Fmt = '('//trim(Fmt)//'A,": ",'//trim(VarFmt)//', " # ",A)' + write(fid, Fmt, iostat=ErrStat) key, val, comment + else + Fmt = '('//trim(Fmt)//'A,": ",'//trim(VarFmt)//')' + write(fid, Fmt, iostat=ErrStat) key, val + endif + if (ErrStat /= 0) then + ErrMsg='Error writting variable '//trim(key)//' to YAML file' + return + endif +end subroutine yaml_write_varI + +subroutine yaml_write_varR4(fid, key, val, VarFmt, ErrStat, ErrMsg, level, comment) + integer(IntKi), intent(in ) :: fid !< File Unit + character(len=*), intent(in ) :: key !< Variable name + real(SiKi), intent(in ) :: val !< Value + character(len=*), intent(in ) :: VarFmt !< Format for printing real numbers + integer, intent( out) :: ErrStat !< A non-zero value indicates an error occurred + character(len=*), intent( out) :: ErrMsg !< Error message if errstat /= errid_none + integer(IntKi), optional, intent(in ) :: level !< indentation level + character(len=*), optional, intent(in ) :: comment !< + character(256) :: Fmt + ErrStat = ErrID_None + ErrMsg = "" + Fmt = '' + if (present(level)) Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' + if (present(comment)) then + Fmt = '('//trim(Fmt)//'A,": ",'//trim(VarFmt)//', " # ",A)' + write(fid, Fmt, iostat=ErrStat) key, val, comment + else + Fmt = '('//trim(Fmt)//'A,": ",'//trim(VarFmt)//')' + write(fid, Fmt, iostat=ErrStat) key, val + endif + if (ErrStat /= 0) then + ErrMsg='Error writting variable '//trim(key)//' to YAML file' + return + endif +end subroutine yaml_write_varR4 + +subroutine yaml_write_varR8(fid, key, val, VarFmt, ErrStat, ErrMsg, level, comment) + integer(IntKi), intent(in ) :: fid !< File Unit + character(len=*), intent(in ) :: key !< Variable name + real(R8Ki), intent(in ) :: val !< Value + character(len=*), intent(in ) :: VarFmt !< Format for printing real numbers + integer, intent( out) :: ErrStat !< A non-zero value indicates an error occurred + character(len=*), intent( out) :: ErrMsg !< Error message if errstat /= errid_none + integer(IntKi), optional, intent(in ) :: level !< indentation level + character(len=*), optional, intent(in ) :: comment !< + character(256) :: Fmt + ErrStat = ErrID_None + ErrMsg = "" + Fmt = '' + if (present(level)) Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' + if (present(comment)) then + Fmt = '('//trim(Fmt)//'A,": ",'//trim(VarFmt)//', " # ",A)' + write(fid, Fmt, iostat=ErrStat) key, val, comment + else + Fmt = '('//trim(Fmt)//'A,": ",'//trim(VarFmt)//')' + write(fid, Fmt, iostat=ErrStat) key, val + endif + if (ErrStat /= 0) then + ErrMsg='Error writting variable '//trim(key)//' to YAML file' + return + endif +end subroutine yaml_write_varR8 + +subroutine yaml_write_varR16(fid, key, val, VarFmt, ErrStat, ErrMsg, level, comment) + integer(IntKi), intent(in ) :: fid !< File Unit + character(len=*), intent(in ) :: key !< Variable name + real(QuKi), intent(in ) :: val !< Value + character(len=*), intent(in ) :: VarFmt !< Format for printing real numbers + integer, intent( out) :: ErrStat !< A non-zero value indicates an error occurred + character(len=*), intent( out) :: ErrMsg !< Error message if errstat /= errid_none + integer(IntKi), optional, intent(in ) :: level !< indentation level + character(len=*), optional, intent(in ) :: comment !< + character(256) :: Fmt + ErrStat = ErrID_None + ErrMsg = "" + Fmt = '' + if (present(level)) Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' + if (present(comment)) then + Fmt = '('//trim(Fmt)//'A,": ",'//trim(VarFmt)//', " # ",A)' + write(fid, Fmt, iostat=ErrStat) key, val, comment + else + Fmt = '('//trim(Fmt)//'A,": ",'//trim(VarFmt)//')' + write(fid, Fmt, iostat=ErrStat) key, val + endif + if (ErrStat /= 0) then + ErrMsg='Error writting variable '//trim(key)//' to YAML file' + return + endif +end subroutine yaml_write_varR16 + +! -------------------------------------------------------------------------------- +! --- Write array +! -------------------------------------------------------------------------------- +!> Write 1D or 2D array to file +subroutine yaml_write_array1I(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment) + integer(IntKi), intent(in ) :: fid !< File Unit + character(len=*), intent(in ) :: key !< Array name + integer(IntKi), dimension(:), intent(in ) :: A !< Array + character(len=*), intent(in ) :: VarFmt !< Format for printing real numbers + integer, intent( out) :: ErrStat !< A non-zero value indicates an error occurred + character(len=*), intent( out) :: ErrMsg !< Error message if errstat /= errid_none + integer(IntKi), optional, intent(in ) :: level !< indentation level + character(len=*), optional, intent(in ) :: comment !< + integer :: nc ! size (rows and columns) of A + integer :: nSpaces ! number of indentation spaces + character(256) :: Fmt + ErrStat = ErrID_None + ErrMsg = "" + nc = size(A,1) + + if (present(level)) then + Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' + else + Fmt = '' + endif + + if (present(comment)) then + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0,1X,A)', iostat=ErrStat ) trim(key), 1, nc, trim(comment) + + else + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0)' , iostat=ErrStat ) trim(key), 1, nc + end if + + if (present(level)) then + Fmt = trim(Num2LStr((level+1)*INDENT_SPACES))//'X,' + else + Fmt = trim(Num2LStr(INDENT_SPACES))//'X,' + endif + + if (nc==0) then + write(fid, '('//trim(Fmt)//'"- [ ]")', iostat=ErrStat) + else + Fmt = '('//trim(Fmt)//'"- [",'//trim(Num2LStr(nc))//'('//VarFmt//',","),"]")' + write(fid, Fmt, iostat=ErrStat) A(:) + if (ErrStat /= 0) then + ErrMsg='Error writting array '//trim(key)//' to YAML file' + return + end if + endif +end subroutine yaml_write_array1I + +subroutine yaml_write_array1R4(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment) + integer(IntKi), intent(in ) :: fid !< File Unit + character(len=*), intent(in ) :: key !< Array name + real(SiKi), dimension(:), intent(in ) :: A !< Array + character(len=*), intent(in ) :: VarFmt !< Format for printing real numbers + integer, intent( out) :: ErrStat !< A non-zero value indicates an error occurred + character(len=*), intent( out) :: ErrMsg !< Error message if errstat /= errid_none + integer(IntKi), optional, intent(in ) :: level !< indentation level + character(len=*), optional, intent(in ) :: comment !< + integer :: nc ! size (rows and columns) of A + integer :: nSpaces ! number of indentation spaces + character(256) :: Fmt + ErrStat = ErrID_None + ErrMsg = "" + nc = size(A,1) + + if (present(level)) then + Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' + else + Fmt = '' + endif + + if (present(comment)) then + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0,1X,A)', iostat=ErrStat ) trim(key), 1, nc, trim(comment) + + else + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0)' , iostat=ErrStat ) trim(key),1,nc + end if + + if (present(level)) then + Fmt = trim(Num2LStr((level+1)*INDENT_SPACES))//'X,' + else + Fmt = trim(Num2LStr(INDENT_SPACES))//'X,' + endif + + if (nc==0) then + write(fid, '('//trim(Fmt)//'"- [ ]")', iostat=ErrStat) + else + Fmt = '('//trim(Fmt)//'"- [",'//trim(Num2LStr(nc))//'('//VarFmt//',","),"]")' + write(fid, Fmt, iostat=ErrStat) A(:) + if (ErrStat /= 0) then + ErrMsg='Error writting array '//trim(key)//' to YAML file' + return + end if + endif +end subroutine yaml_write_array1R4 + +subroutine yaml_write_array1R8(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment) + integer(IntKi), intent(in ) :: fid !< File Unit + character(len=*), intent(in ) :: key !< Array name + real(R8Ki), dimension(:), intent(in ) :: A !< Array + character(len=*), intent(in ) :: VarFmt !< Format for printing real numbers + integer, intent( out) :: ErrStat !< A non-zero value indicates an error occurred + character(len=*), intent( out) :: ErrMsg !< Error message if errstat /= errid_none + integer(IntKi), optional, intent(in ) :: level !< indentation level + character(len=*), optional, intent(in ) :: comment !< + integer :: nc ! size (rows and columns) of A + integer :: nSpaces ! number of indentation spaces + character(256) :: Fmt + ErrStat = ErrID_None + ErrMsg = "" + nc = size(A,1) + + if (present(level)) then + Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' + else + Fmt = '' + endif + + if (present(comment)) then + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0,1X,A)', iostat=ErrStat ) trim(key), 1, nc, trim(comment) + else + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0)' , iostat=ErrStat ) trim(key), 1, nc + end if + + if (present(level)) then + Fmt = trim(Num2LStr((level+1)*INDENT_SPACES))//'X,' + else + Fmt = trim(Num2LStr(INDENT_SPACES))//'X,' + endif + + if (nc==0) then + write(fid, '('//trim(Fmt)//'"- [ ]")', iostat=ErrStat) + else + Fmt = '('//trim(Fmt)//'"- [",'//trim(Num2LStr(nc))//'('//VarFmt//',","),"]")' + write(fid, Fmt, iostat=ErrStat) A(:) + if (ErrStat /= 0) then + ErrMsg='Error writting array '//trim(key)//' to YAML file' + return + end if + endif +end subroutine yaml_write_array1R8 + +subroutine yaml_write_array1R16(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment) + integer(IntKi), intent(in ) :: fid !< File Unit + character(len=*), intent(in ) :: key !< Array name + real(QuKi), dimension(:), intent(in ) :: A !< Array + character(len=*), intent(in ) :: VarFmt !< Format for printing real numbers + integer, intent( out) :: ErrStat !< A non-zero value indicates an error occurred + character(len=*), intent( out) :: ErrMsg !< Error message if errstat /= errid_none + integer(IntKi), optional, intent(in ) :: level !< indentation level + character(len=*), optional, intent(in ) :: comment !< + integer :: nc ! size (rows and columns) of A + integer :: nSpaces ! number of indentation spaces + character(256) :: Fmt + ErrStat = ErrID_None + ErrMsg = "" + nc = size(A,1) + + if (present(level)) then + Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' + else + Fmt = '' + endif + + if (present(comment)) then + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0,1X,A)', iostat=ErrStat ) trim(key), 1, nc, trim(comment) + + else + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0)' , iostat=ErrStat ) trim(key),1,nc + end if + + if (present(level)) then + Fmt = trim(Num2LStr((level+1)*INDENT_SPACES))//'X,' + else + Fmt = trim(Num2LStr(INDENT_SPACES))//'X,' + endif + + if (nc==0) then + write(fid, '('//trim(Fmt)//'"- [ ]")', iostat=ErrStat) + else + Fmt = '('//trim(Fmt)//'"- [",'//trim(Num2LStr(nc))//'('//VarFmt//',","),"]")' + write(fid, Fmt, iostat=ErrStat) A(:) + if (ErrStat /= 0) then + ErrMsg='Error writting array '//trim(key)//' to YAML file' + return + end if + endif +end subroutine yaml_write_array1R16 + +subroutine yaml_write_array2I(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment, label) + integer(IntKi), intent(in ) :: fid !< File Unit + character(len=*), intent(in ) :: key !< Array name + integer(IntKi), dimension(:,:), intent(in ) :: A !< Array + character(len=*), intent(in ) :: VarFmt !< Format for printing real numbers + integer, intent( out) :: ErrStat !< A non-zero value indicates an error occurred + character(len=*), intent( out) :: ErrMsg !< Error message if errstat /= errid_none + integer(IntKi), optional, intent(in ) :: level !< indentation level + character(len=*), optional, intent(in ) :: comment !< + logical, optional, intent(in ) :: label !< If present, add a index label at end of line + integer :: nr, nc, i ! size (rows and columns) of A + integer :: nSpaces ! number of indentation spaces + character(256) :: Fmt + ErrStat = ErrID_None + ErrMsg = "" + nr = size(A,1) + nc = size(A,2) + + Fmt = '' + if (present(level)) Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' + if (present(comment)) then + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0,1X,A)', iostat=ErrStat ) trim(key), nr, nc, trim(comment) + + else + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0)' , iostat=ErrStat ) trim(key),nr,nc + end if + + if (present(level)) then + Fmt = trim(Num2LStr((level+1)*INDENT_SPACES))//'X,' + else + Fmt = trim(Num2LStr(INDENT_SPACES))//'X,' + endif + if (nr==0) then + write(fid, '('//trim(Fmt)//'"- [ ]")', iostat=ErrStat) + else + if (present(label)) then + Fmt = '('//trim(Fmt)//'"- [",'//trim(Num2LStr(nc))//'('//VarFmt//',","),"] # ",I0)' + else + Fmt = '('//trim(Fmt)//'"- [",'//trim(Num2LStr(nc))//'('//VarFmt//',","),"]")' + endif + do i=1,nr + if (present(label)) then + write(fid, Fmt, iostat=ErrStat) A(i,:), i + else + write(fid, Fmt, iostat=ErrStat) A(i,:) + endif + if (ErrStat /= 0) then + ErrMsg='Error writting array '//trim(key)//' to YAML file' + return + end if + end do + endif +end subroutine yaml_write_array2I + +subroutine yaml_write_array2R4(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment, AllFmt) + integer(IntKi), intent(in ) :: fid !< File Unit + character(len=*), intent(in ) :: key !< Array name + real(SiKi), dimension(:,:), intent(in ) :: A !< Array + character(len=*), intent(in ) :: VarFmt !< Format for printing real numbers + integer, intent( out) :: ErrStat !< A non-zero value indicates an error occurred + character(len=*), intent( out) :: ErrMsg !< Error message if errstat /= errid_none + integer(IntKi), optional, intent(in ) :: level !< indentation level + character(len=*), optional, intent(in ) :: comment !< + character(len=*), optional, intent(in ) :: AllFmt !< Format for printing a line + integer :: nr, nc, i ! size (rows and columns) of A + integer :: nSpaces ! number of indentation spaces + character(256) :: Fmt + ErrStat = ErrID_None + ErrMsg = "" + nr = size(A,1) + nc = size(A,2) + + if (present(level)) then + Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' + else + Fmt = '' + endif + + if (present(comment)) then + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0,1X,A)', iostat=ErrStat ) trim(key), nr, nc, trim(comment) + + else + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0)' , iostat=ErrStat ) trim(key),nr,nc + end if + + if (present(level)) then + Fmt = trim(Num2LStr((level+1)*INDENT_SPACES))//'X,' + else + Fmt = trim(Num2LStr(INDENT_SPACES))//'X,' + endif + + if (nr==0) then + write(fid, '('//trim(Fmt)//'"- [ ]")', iostat=ErrStat) + else + if (nc==0) then + Fmt = '('//trim(Fmt)//'"- []")' + else + if (present(AllFmt)) then + Fmt = '('//trim(Fmt)//'"- [",'//trim(AllFmt)//'"]")' + else + Fmt = '('//trim(Fmt)//'"- [",'//trim(Num2LStr(nc))//'('//VarFmt//',","),"]")' + endif + endif + do i=1,nr + write(fid, Fmt, iostat=ErrStat) A(i,:) + if (ErrStat /= 0) then + ErrMsg='Error writting array '//trim(key)//' to YAML file' + return + end if + end do + endif +end subroutine yaml_write_array2R4 + +subroutine yaml_write_array2R8(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment, AllFmt) + integer(IntKi), intent(in ) :: fid !< File Unit + character(len=*), intent(in ) :: key !< Array name + real(R8Ki), dimension(:,:), intent(in ) :: A !< Array + character(len=*), intent(in ) :: VarFmt !< Format for printing real numbers + integer, intent( out) :: ErrStat !< A non-zero value indicates an error occurred + character(len=*), intent( out) :: ErrMsg !< Error message if errstat /= errid_none + integer(IntKi), optional, intent(in ) :: level !< indentation level + character(len=*), optional, intent(in ) :: comment !< + character(len=*), optional, intent(in ) :: AllFmt !< Format for printing a line + integer :: nr, nc, i ! size (rows and columns) of A + integer :: nSpaces ! number of indentation spaces + character(256) :: Fmt + ErrStat = ErrID_None + ErrMsg = "" + nr = size(A,1) + nc = size(A,2) + + if (present(level)) then + Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' + else + Fmt = '' + endif + if (present(comment)) then + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0,1X,A)', iostat=ErrStat ) trim(key), nr, nc, trim(comment) + + else + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0)' , iostat=ErrStat ) trim(key),nr,nc + end if + + if (present(level)) then + Fmt = trim(Num2LStr((level+1)*INDENT_SPACES))//'X,' + else + Fmt = trim(Num2LStr(INDENT_SPACES))//'X,' + endif + if (nr==0) then + write(fid, '('//trim(Fmt)//'"- [ ]")', iostat=ErrStat) + else + if (nc==0) then + Fmt = '('//trim(Fmt)//'"- []")' + else + if (present(AllFmt)) then + Fmt = '('//trim(Fmt)//'"- [",'//trim(AllFmt)//'"]")' + else + Fmt = '('//trim(Fmt)//'"- [",'//trim(Num2LStr(nc))//'('//VarFmt//',","),"]")' + endif + endif + do i=1,nr + write(fid, Fmt, iostat=ErrStat) A(i,:) + if (ErrStat /= 0) then + ErrMsg='Error writting array '//trim(key)//' to YAML file' + return + end if + end do + endif +end subroutine yaml_write_array2R8 + +subroutine yaml_write_array2R16(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment, AllFmt) + integer(IntKi), intent(in ) :: fid !< File Unit + character(len=*), intent(in ) :: key !< Array name + real(QuKi), dimension(:,:), intent(in ) :: A !< Array + character(len=*), intent(in ) :: VarFmt !< Format for printing real numbers + integer, intent( out) :: ErrStat !< A non-zero value indicates an error occurred + character(len=*), intent( out) :: ErrMsg !< Error message if errstat /= errid_none + integer(IntKi), optional, intent(in ) :: level !< indentation level + character(len=*), optional, intent(in ) :: comment !< + character(len=*), optional, intent(in ) :: AllFmt !< Format for printing a line + integer :: nr, nc, i ! size (rows and columns) of A + integer :: nSpaces ! number of indentation spaces + character(256) :: Fmt + ErrStat = ErrID_None + ErrMsg = "" + nr = size(A,1) + nc = size(A,2) + + Fmt = '' + if (present(level)) Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' + if (present(comment)) then + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0,1X,A)', iostat=ErrStat ) trim(key), nr, nc, trim(comment) + + else + write(fid, '('//trim(Fmt)//'A,": # ",I0," x ",I0)' , iostat=ErrStat ) trim(key),nr,nc + end if + + if (present(level)) then + Fmt = trim(Num2LStr((level+1)*INDENT_SPACES))//'X,' + else + Fmt = trim(Num2LStr(INDENT_SPACES))//'X,' + endif + if (nr==0) then + write(fid, '('//trim(Fmt)//'"- [ ]")', iostat=ErrStat) + else + if (nc==0) then + Fmt = '('//trim(Fmt)//'"- []")' + else + if (present(AllFmt)) then + Fmt = '('//trim(Fmt)//'"- [",'//trim(AllFmt)//'"]")' + else + Fmt = '('//trim(Fmt)//'"- [",'//trim(Num2LStr(nc))//'('//VarFmt//',","),"]")' + endif + endif + do i=1,nr + write(fid, Fmt, iostat=ErrStat) A(i,:) + if (ErrStat /= 0) then + ErrMsg='Error writting array '//trim(key)//' to YAML file' + return + end if + end do + endif +end subroutine yaml_write_array2R16 + + +end module YAML diff --git a/modules/subdyn/src/qsort_c_module.f90 b/modules/subdyn/src/qsort_c_module.f90 deleted file mode 100644 index 553b255443..0000000000 --- a/modules/subdyn/src/qsort_c_module.f90 +++ /dev/null @@ -1,61 +0,0 @@ -!********************************************************************************************************************************** -module qsort_c_module -!This routine ASSUMES A is (m,2) dimensioned array -implicit none -public :: QsortC -private :: Partition - -contains - -recursive subroutine QsortC(A) - integer, intent(in out), dimension(:,:) :: A - integer :: iq - - if(size(A,1) > 1) then - call Partition(A, iq) - call QsortC(A(:iq-1, :)) - call QsortC(A(iq:, :)) - endif -end subroutine QsortC - -subroutine Partition(A, marker) - integer, intent(in out), dimension(:,:) :: A - integer, intent(out) :: marker - integer :: i, j, k - integer :: temp - integer :: x ! pivot point - x = A(1, 1) - i= 0 - j= size(A,1) + 1 - - - do - j = j-1 - do - if (A(j,1) <= x) exit - j = j-1 - end do - i = i+1 - do - if (A(i,1) >= x) exit - i = i+1 - end do - if (i < j) then - ! exchange A(i) and A(j) - do k=1,size(A,2) - temp = A(i,k) - A(i,k) = A(j,k) - A(j,k) = temp - end do !k - elseif (i == j) then - marker = i+1 - return - else - marker = i - return - endif - end do - -end subroutine Partition - -end module qsort_c_module \ No newline at end of file diff --git a/reg_tests/CMakeLists.txt b/reg_tests/CMakeLists.txt index 71350e7981..7f1beb912e 100644 --- a/reg_tests/CMakeLists.txt +++ b/reg_tests/CMakeLists.txt @@ -46,6 +46,9 @@ set(CTEST_BEAMDYN_EXECUTABLE "${CMAKE_BINARY_DIR}/modules/beamdyn/beamdyn_driver # Set the HydroDyn executable configuration option and default set(CTEST_HYDRODYN_EXECUTABLE "${CMAKE_BINARY_DIR}/modules/hydrodyn/hydrodyn_driver" CACHE FILEPATH "Specify the HydroDyn driver executable to use in testing.") +# Set the SubDyn executable configuration option and default +set(CTEST_SUBDYN_EXECUTABLE "${CMAKE_BINARY_DIR}/modules/subdyn/subdyn_driver" CACHE FILEPATH "Specify the SubDyn driver executable to use in testing.") + # Set the python executable configuration option and default if(NOT EXISTS ${PYTHON_EXECUTABLE}) find_program(PYTHON_EXECUTABLE NAMES python3 python py) @@ -67,7 +70,7 @@ add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/r-test") # build and seed the test directories with the data they need to run the tests file(MAKE_DIRECTORY ${CTEST_BINARY_DIR}) -foreach(regTest glue-codes/openfast modules/aerodyn modules/beamdyn modules/hydrodyn) +foreach(regTest glue-codes/openfast modules/aerodyn modules/beamdyn modules/hydrodyn modules/subdyn) file(MAKE_DIRECTORY ${CTEST_BINARY_DIR}/${regTest}) endforeach() diff --git a/reg_tests/CTestList.cmake b/reg_tests/CTestList.cmake index 6c02090505..d9fd1a471b 100644 --- a/reg_tests/CTestList.cmake +++ b/reg_tests/CTestList.cmake @@ -111,6 +111,15 @@ function(hd_regression TESTNAME LABEL) regression(${TEST_SCRIPT} ${HYDRODYN_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} ${TESTNAME} "${LABEL}") endfunction(hd_regression) +# subdyn +function(sd_regression TESTNAME LABEL) + set(TEST_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/executeSubdynRegressionCase.py") + set(SUBDYN_EXECUTABLE "${CTEST_SUBDYN_EXECUTABLE}") + set(SOURCE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/..") + set(BUILD_DIRECTORY "${CTEST_BINARY_DIR}/modules/subdyn") + regression(${TEST_SCRIPT} ${SUBDYN_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} ${TESTNAME} "${LABEL}") +endfunction(sd_regression) + #=============================================================================== # Regression tests #=============================================================================== @@ -173,3 +182,9 @@ hd_regression("hd_5MW_ITIBarge_DLL_WTurb_WavesIrr" "hydrodyn;offshore") hd_regression("hd_5MW_OC3Spar_DLL_WTurb_WavesIrr" "hydrodyn;offshore") hd_regression("hd_5MW_OC4Semi_WSt_WavesWN" "hydrodyn;offshore") hd_regression("hd_5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti" "hydrodyn;offshore") + +# SubDyn regression tests +sd_regression("SD_Cable_5Joints" "subdyn;offshore") +sd_regression("SD_PendulumDamp" "subdyn;offshore") +sd_regression("SD_Rigid" "subdyn;offshore") +sd_regression("SD_SparHanging" "subdyn;offshore") diff --git a/reg_tests/executeOpenfastLinearRegressionCase.py b/reg_tests/executeOpenfastLinearRegressionCase.py index 11c7671e11..d23937bbfd 100644 --- a/reg_tests/executeOpenfastLinearRegressionCase.py +++ b/reg_tests/executeOpenfastLinearRegressionCase.py @@ -164,6 +164,9 @@ def isclose(a, b, rel_tol=1e-09, abs_tol=0.0): ### Get a list of all the files in the baseline directory baselineOutFiles = os.listdir(targetOutputDirectory) +# Drop the log file, if its listed +if caseName + '.log' in baselineOutFiles: + baselineOutFiles.remove(caseName + '.log') # these should all exist in the local outputs directory localFiles = os.listdir(testBuildDirectory) diff --git a/reg_tests/executeSubdynRegressionCase.py b/reg_tests/executeSubdynRegressionCase.py new file mode 100644 index 0000000000..151049fa4e --- /dev/null +++ b/reg_tests/executeSubdynRegressionCase.py @@ -0,0 +1,141 @@ +# +# Copyright 2017 National Renewable Energy Laboratory +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +""" + This program executes SubDyn and a regression test for a single test case. + The test data is contained in a git submodule, r-test, which must be initialized + prior to running. See the r-test README or OpenFAST documentation for more info. + + Get usage with: `executeSubdynRegressionCase.py -h` +""" + +import os +import sys +basepath = os.path.sep.join(sys.argv[0].split(os.path.sep)[:-1]) if os.path.sep in sys.argv[0] else "." +sys.path.insert(0, os.path.sep.join([basepath, "lib"])) +import argparse +import shutil +import glob +import subprocess +import rtestlib as rtl +import openfastDrivers +import pass_fail +from errorPlotting import exportCaseSummary + +##### Main program + +### Store the python executable for future python calls +pythonCommand = sys.executable + +### Verify input arguments +parser = argparse.ArgumentParser(description="Executes SubDyn and a regression test for a single test case.") +parser.add_argument("caseName", metavar="Case-Name", type=str, nargs=1, help="The name of the test case.") +parser.add_argument("executable", metavar="SubDyn-Driver", type=str, nargs=1, help="The path to the SubDyn driver executable.") +parser.add_argument("sourceDirectory", metavar="path/to/openfast_repo", type=str, nargs=1, help="The path to the OpenFAST repository.") +parser.add_argument("buildDirectory", metavar="path/to/openfast_repo/build", type=str, nargs=1, help="The path to the OpenFAST repository build directory.") +parser.add_argument("tolerance", metavar="Test-Tolerance", type=float, nargs=1, help="Tolerance defining pass or failure in the regression test.") +parser.add_argument("systemName", metavar="System-Name", type=str, nargs=1, help="The current system\'s name: [Darwin,Linux,Windows]") +parser.add_argument("compilerId", metavar="Compiler-Id", type=str, nargs=1, help="The compiler\'s id: [Intel,GNU]") +parser.add_argument("-p", "-plot", dest="plot", default=False, metavar="Plotting-Flag", type=bool, nargs="?", help="bool to include matplotlib plots in failed cases") +parser.add_argument("-n", "-no-exec", dest="noExec", default=False, metavar="No-Execution", type=bool, nargs="?", help="bool to prevent execution of the test cases") +parser.add_argument("-v", "-verbose", dest="verbose", default=False, metavar="Verbose-Flag", type=bool, nargs="?", help="bool to include verbose system output") + +args = parser.parse_args() + +caseName = args.caseName[0] +executable = args.executable[0] +sourceDirectory = args.sourceDirectory[0] +buildDirectory = args.buildDirectory[0] +tolerance = args.tolerance[0] +plotError = args.plot if args.plot is False else True +noExec = args.noExec if args.noExec is False else True +verbose = args.verbose if args.verbose is False else True + +# validate inputs +rtl.validateExeOrExit(executable) +rtl.validateDirOrExit(sourceDirectory) +if not os.path.isdir(buildDirectory): + os.makedirs(buildDirectory) + +### Build the filesystem navigation variables for running the test case +regtests = os.path.join(sourceDirectory, "reg_tests") +lib = os.path.join(regtests, "lib") +rtest = os.path.join(regtests, "r-test") +moduleDirectory = os.path.join(rtest, "modules", "subdyn") +inputsDirectory = os.path.join(moduleDirectory, caseName) +targetOutputDirectory = os.path.join(inputsDirectory) +testBuildDirectory = os.path.join(buildDirectory, caseName) + +# verify all the required directories exist +if not os.path.isdir(rtest): + rtl.exitWithError("The test data directory, {}, does not exist. If you haven't already, run `git submodule update --init --recursive`".format(rtest)) +if not os.path.isdir(targetOutputDirectory): + rtl.exitWithError("The test data outputs directory, {}, does not exist. Try running `git submodule update`".format(targetOutputDirectory)) +if not os.path.isdir(inputsDirectory): + rtl.exitWithError("The test data inputs directory, {}, does not exist. Verify your local repository is up to date.".format(inputsDirectory)) + +# create the local output directory if it does not already exist +# and initialize it with input files for all test cases +if not os.path.isdir(testBuildDirectory): + os.makedirs(testBuildDirectory) + for file in glob.glob(os.path.join(inputsDirectory,caseName+".dvr")): + filename = file.split(os.path.sep)[-1] + shutil.copy(os.path.join(inputsDirectory,filename), os.path.join(testBuildDirectory,filename)) + for file in glob.glob(os.path.join(inputsDirectory,"*dat")): + filename = file.split(os.path.sep)[-1] + shutil.copy(os.path.join(inputsDirectory,filename), os.path.join(testBuildDirectory,filename)) + +### Run SubDyn on the test case +if not noExec: + caseInputFile = os.path.join(testBuildDirectory, caseName+".dvr") + returnCode = openfastDrivers.runSubdynDriverCase(caseInputFile, executable) + if returnCode != 0: + rtl.exitWithError("") + +### Build the filesystem navigation variables for running the regression test +localOutFile = os.path.join(testBuildDirectory, caseName+".SD.out") +baselineOutFile = os.path.join(targetOutputDirectory, caseName+".SD.out") +rtl.validateFileOrExit(localOutFile) +rtl.validateFileOrExit(baselineOutFile) + +testData, testInfo, testPack = pass_fail.readFASTOut(localOutFile) +baselineData, baselineInfo, _ = pass_fail.readFASTOut(baselineOutFile) +performance = pass_fail.calculateNorms(testData, baselineData) +normalizedNorm = performance[:, 1] + +# export all case summaries +results = list(zip(testInfo["attribute_names"], [*performance])) +results_max = performance.max(axis=0) +exportCaseSummary(testBuildDirectory, caseName, results, results_max, tolerance) + +# failing case +if not pass_fail.passRegressionTest(normalizedNorm, tolerance): + if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + ixFailChannels = [i for i in range(len(testInfo["attribute_names"])) if normalizedNorm[i] > tolerance] + failChannels = [channel for i, channel in enumerate(testInfo["attribute_names"]) if i in ixFailChannels] + failResults = [res for i, res in enumerate(results) if i in ixFailChannels] + for channel in failChannels: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error.msg)) + finalizePlotDirectory(localOutFile, failChannels, caseName) + sys.exit(1) + +# passing case +sys.exit(0) diff --git a/reg_tests/lib/openfastDrivers.py b/reg_tests/lib/openfastDrivers.py index b06fd76218..550171f390 100644 --- a/reg_tests/lib/openfastDrivers.py +++ b/reg_tests/lib/openfastDrivers.py @@ -64,3 +64,8 @@ def runHydrodynDriverCase(inputFile, executable, verbose=False): caseDirectory = os.path.sep.join(inputFile.split(os.path.sep)[:-1]) os.chdir(caseDirectory) return _runGenericCase(inputFile, executable, verbose) + +def runSubdynDriverCase(inputFile, executable, verbose=False): + caseDirectory = os.path.sep.join(inputFile.split(os.path.sep)[:-1]) + os.chdir(caseDirectory) + return _runGenericCase(inputFile, executable, verbose) diff --git a/reg_tests/manualRegressionTest.py b/reg_tests/manualRegressionTest.py index ef63ddfac9..f51b1e5a5c 100644 --- a/reg_tests/manualRegressionTest.py +++ b/reg_tests/manualRegressionTest.py @@ -65,14 +65,20 @@ def strFormat(string): else: with open(os.path.join("r-test", "glue-codes", "openfast", "CaseList.md")) as listfile: caselist = listfile.readlines() +# allow comments with '#' casenames = [c.rstrip("\n\r").strip() for c in caselist if "#" not in c] +# allow empty lines +casenames = [c for c in casenames if len(c.strip()) > 0] results = [] prefix, passString, failString = "executing", "PASS", "FAIL" longestName = max(casenames, key=len) for case in casenames: print(strFormat(prefix).format(prefix), strFormat(longestName+" ").format(case), end="", flush=True) - command = "\"{}\" executeOpenfastRegressionCase.py {} {} {} {} {} {} {} {} {}".format(pythonCommand, case, openfast_executable, sourceDirectory, buildDirectory, tolerance, machine, compiler, plotFlag, noExecFlag) + if "linear" in case.lower(): + command = "\"{}\" executeOpenfastLinearRegressionCase.py {} {} {} {} {} {} {} {} {}".format(pythonCommand, case, openfast_executable, sourceDirectory, buildDirectory, tolerance, machine, compiler, plotFlag, noExecFlag) + else: + command = "\"{}\" executeOpenfastRegressionCase.py {} {} {} {} {} {} {} {} {}".format(pythonCommand, case, openfast_executable, sourceDirectory, buildDirectory, tolerance, machine, compiler, plotFlag, noExecFlag) returnCode = subprocess.call(command, stdout=outstd, shell=True) resultString = passString if returnCode == 0 else failString results.append((case, resultString)) diff --git a/reg_tests/r-test b/reg_tests/r-test index 01f51597b8..adffb7e3ba 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit 01f51597b8f058d6f08ec67d7b9aeb4a2ffccaad +Subproject commit adffb7e3baa3ef4b8b2ea4b777ba6b23b8048069 diff --git a/unit_tests/beamdyn/CMakeLists.txt b/unit_tests/beamdyn/CMakeLists.txt index 2ae37b0fc4..c93ac28494 100644 --- a/unit_tests/beamdyn/CMakeLists.txt +++ b/unit_tests/beamdyn/CMakeLists.txt @@ -31,6 +31,7 @@ include_directories( set(testlist test_tools + test_BD_ComputeIniNodalCrv test_BD_CrvCompose test_BD_CheckRotMat test_BD_CrvExtractCrv diff --git a/vs-build/FASTlib/FASTlib.vfproj b/vs-build/FASTlib/FASTlib.vfproj index 18a52174ac..0f174f2f11 100644 --- a/vs-build/FASTlib/FASTlib.vfproj +++ b/vs-build/FASTlib/FASTlib.vfproj @@ -122,11 +122,11 @@ - + - + @@ -967,9 +967,7 @@ - - @@ -1456,11 +1454,9 @@ - + - - @@ -1574,8 +1570,6 @@ - - @@ -1602,8 +1596,6 @@ - - @@ -1629,8 +1621,6 @@ - - @@ -1657,8 +1647,6 @@ - - @@ -1684,8 +1672,6 @@ - - @@ -1711,8 +1697,6 @@ - - @@ -1738,8 +1722,6 @@ - - @@ -1765,8 +1747,6 @@ - - @@ -1792,8 +1772,6 @@ - - @@ -1819,8 +1797,6 @@ - - @@ -1846,8 +1822,6 @@ - - @@ -1873,8 +1847,6 @@ - - @@ -1900,8 +1872,6 @@ - - @@ -1927,8 +1897,6 @@ - - @@ -1954,8 +1922,6 @@ - - @@ -1981,8 +1947,6 @@ - - @@ -2003,8 +1967,8 @@ - - + + @@ -2190,10 +2154,14 @@ - + + - + + + + diff --git a/vs-build/HydroDyn/HydroDynDriver.sln b/vs-build/HydroDyn/HydroDynDriver.sln index e149d60493..cc5662783c 100644 --- a/vs-build/HydroDyn/HydroDynDriver.sln +++ b/vs-build/HydroDyn/HydroDynDriver.sln @@ -1,18 +1,24 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30501.0 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30503.244 MinimumVisualStudioVersion = 10.0.40219.1 Project("{6989167D-11E4-40FE-8C1A-2192A86A7E90}") = "HydroDynDriver", "HydroDynDriver.vfproj", "{815C302F-A93D-4C22-9329-717B085113C0}" 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|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {815C302F-A93D-4C22-9329-717B085113C0}.Debug_Double|Win32.ActiveCfg = Debug_Double|Win32 + {815C302F-A93D-4C22-9329-717B085113C0}.Debug_Double|Win32.Build.0 = Debug_Double|Win32 + {815C302F-A93D-4C22-9329-717B085113C0}.Debug_Double|x64.ActiveCfg = Debug_Double|x64 + {815C302F-A93D-4C22-9329-717B085113C0}.Debug_Double|x64.Build.0 = Debug_Double|x64 {815C302F-A93D-4C22-9329-717B085113C0}.Debug|Win32.ActiveCfg = Debug|Win32 {815C302F-A93D-4C22-9329-717B085113C0}.Debug|Win32.Build.0 = Debug|Win32 {815C302F-A93D-4C22-9329-717B085113C0}.Debug|x64.ActiveCfg = Debug|x64 @@ -25,4 +31,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D73C5D81-14CD-4C14-8B52-6885B380AE3E} + EndGlobalSection EndGlobal diff --git a/vs-build/HydroDyn/HydroDynDriver.vfproj b/vs-build/HydroDyn/HydroDynDriver.vfproj index 89e4500f42..4bec1b3320 100644 --- a/vs-build/HydroDyn/HydroDynDriver.vfproj +++ b/vs-build/HydroDyn/HydroDynDriver.vfproj @@ -6,7 +6,7 @@ - + @@ -16,7 +16,7 @@ - + @@ -25,8 +25,8 @@ - - + + @@ -36,7 +36,27 @@ - + + + + + + + + + + + + + + + + + + + + + @@ -51,81 +71,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -141,133 +259,183 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vs-build/MAPlib/MAP_dll.vcxproj b/vs-build/MAPlib/MAP_dll.vcxproj index 0339dfa085..1c17aebaaf 100644 --- a/vs-build/MAPlib/MAP_dll.vcxproj +++ b/vs-build/MAPlib/MAP_dll.vcxproj @@ -1,5 +1,5 @@  - + Debug diff --git a/vs-build/RunRegistry.bat b/vs-build/RunRegistry.bat index 734ebf9ccc..e85beb48d8 100644 --- a/vs-build/RunRegistry.bat +++ b/vs-build/RunRegistry.bat @@ -63,6 +63,12 @@ SET Output_Loc=%CURR_LOC% %REGISTRY% "%CURR_LOC%\MAP_Fortran_Registry.txt" -I "%NWTC_Lib_Loc%" -I "%CURR_LOC%" -O "%Output_Loc%" -noextrap GOTO checkError +:MAP_Fortran +SET CURR_LOC=%MAP_Loc% +SET Output_Loc=%CURR_LOC% +%REGISTRY% "%CURR_LOC%\%ModuleName%_Registry.txt" -I "%NWTC_Lib_Loc%" -I "%CURR_LOC%" -O "%Output_Loc%" -noextrap +GOTO checkError + :FAST SET CURR_LOC=%FAST_Loc% SET Output_Loc=%CURR_LOC% diff --git a/vs-build/SubDyn/SubDyn.sln b/vs-build/SubDyn/SubDyn.sln index 0aa100f6f8..d497e8bd4a 100644 --- a/vs-build/SubDyn/SubDyn.sln +++ b/vs-build/SubDyn/SubDyn.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.40629.0 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{6989167D-11E4-40FE-8C1A-2192A86A7E90}") = "SubDyn", "SubDyn.vfproj", "{815C302F-A93D-4C22-9329-717B085113C0}" ProjectSection(ProjectDependencies) = postProject @@ -12,16 +12,28 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FAST_Registry", "..\Registr 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 + {815C302F-A93D-4C22-9329-717B085113C0}.Debug_Double|Win32.ActiveCfg = Debug_Double|Win32 + {815C302F-A93D-4C22-9329-717B085113C0}.Debug_Double|Win32.Build.0 = Debug_Double|Win32 + {815C302F-A93D-4C22-9329-717B085113C0}.Debug_Double|x64.ActiveCfg = Debug_Double|x64 + {815C302F-A93D-4C22-9329-717B085113C0}.Debug_Double|x64.Build.0 = Debug_Double|x64 {815C302F-A93D-4C22-9329-717B085113C0}.Debug|Win32.ActiveCfg = Debug|Win32 {815C302F-A93D-4C22-9329-717B085113C0}.Debug|Win32.Build.0 = Debug|Win32 {815C302F-A93D-4C22-9329-717B085113C0}.Debug|x64.ActiveCfg = Debug|x64 {815C302F-A93D-4C22-9329-717B085113C0}.Debug|x64.Build.0 = Debug|x64 + {815C302F-A93D-4C22-9329-717B085113C0}.Release_Double|Win32.ActiveCfg = Release_Double|Win32 + {815C302F-A93D-4C22-9329-717B085113C0}.Release_Double|Win32.Build.0 = Release_Double|Win32 + {815C302F-A93D-4C22-9329-717B085113C0}.Release_Double|x64.ActiveCfg = Release_Double|x64 + {815C302F-A93D-4C22-9329-717B085113C0}.Release_Double|x64.Build.0 = Release_Double|x64 {815C302F-A93D-4C22-9329-717B085113C0}.Release|Win32.ActiveCfg = Release|Win32 {815C302F-A93D-4C22-9329-717B085113C0}.Release|Win32.Build.0 = Release|Win32 {815C302F-A93D-4C22-9329-717B085113C0}.Release|x64.ActiveCfg = Release|x64 diff --git a/vs-build/SubDyn/SubDyn.vfproj b/vs-build/SubDyn/SubDyn.vfproj index 5f0256521a..b8e89e3c0c 100644 --- a/vs-build/SubDyn/SubDyn.vfproj +++ b/vs-build/SubDyn/SubDyn.vfproj @@ -5,7 +5,7 @@ - + @@ -15,7 +15,7 @@ - + @@ -25,7 +25,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -43,141 +43,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + - + - + + + - - - + + + + + - - - - - - - - - - - + + + - + - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - + - - - - - - - - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - + + + + - + + + +